1// Copyright 2020 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package java 16 17// This file contains the module implementations for runtime_resource_overlay and 18// override_runtime_resource_overlay. 19 20import "android/soong/android" 21 22func init() { 23 RegisterRuntimeResourceOverlayBuildComponents(android.InitRegistrationContext) 24} 25 26func RegisterRuntimeResourceOverlayBuildComponents(ctx android.RegistrationContext) { 27 ctx.RegisterModuleType("runtime_resource_overlay", RuntimeResourceOverlayFactory) 28 ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory) 29} 30 31type RuntimeResourceOverlay struct { 32 android.ModuleBase 33 android.DefaultableModuleBase 34 android.OverridableModuleBase 35 aapt 36 37 properties RuntimeResourceOverlayProperties 38 overridableProperties OverridableRuntimeResourceOverlayProperties 39 40 certificate Certificate 41 42 outputFile android.Path 43 installDir android.InstallPath 44} 45 46type RuntimeResourceOverlayProperties struct { 47 // the name of a certificate in the default certificate directory or an android_app_certificate 48 // module name in the form ":module". 49 Certificate *string 50 51 // Name of the signing certificate lineage file. 52 Lineage *string 53 54 // For overriding the --rotation-min-sdk-version property of apksig 55 RotationMinSdkVersion *string 56 57 // optional theme name. If specified, the overlay package will be applied 58 // only when the ro.boot.vendor.overlay.theme system property is set to the same value. 59 Theme *string 60 61 // If not blank, set to the version of the sdk to compile against. This 62 // can be either an API version (e.g. "29" for API level 29 AKA Android 10) 63 // or special subsets of the current platform, for example "none", "current", 64 // "core", "system", "test". See build/soong/java/sdk.go for the full and 65 // up-to-date list of possible values. 66 // Defaults to compiling against the current platform. 67 Sdk_version *string 68 69 // if not blank, set the minimum version of the sdk that the compiled artifacts will run against. 70 // Defaults to sdk_version if not set. 71 Min_sdk_version *string 72 73 // list of android_library modules whose resources are extracted and linked against statically 74 Static_libs []string 75 76 // list of android_app modules whose resources are extracted and linked against 77 Resource_libs []string 78 79 // Names of modules to be overridden. Listed modules can only be other overlays 80 // (in Make or Soong). 81 // This does not completely prevent installation of the overridden overlays, but if both 82 // overlays would be installed by default (in PRODUCT_PACKAGES) the other overlay will be removed 83 // from PRODUCT_PACKAGES. 84 Overrides []string 85} 86 87// RuntimeResourceOverlayModule interface is used by the apex package to gather information from 88// a RuntimeResourceOverlay module. 89type RuntimeResourceOverlayModule interface { 90 android.Module 91 OutputFile() android.Path 92 Certificate() Certificate 93 Theme() string 94} 95 96// RRO's partition logic is different from the partition logic of other modules defined in soong/android/paths.go 97// The default partition for RRO is "/product" and not "/system" 98func rroPartition(ctx android.ModuleContext) string { 99 var partition string 100 if ctx.DeviceSpecific() { 101 partition = ctx.DeviceConfig().OdmPath() 102 } else if ctx.SocSpecific() { 103 partition = ctx.DeviceConfig().VendorPath() 104 } else if ctx.SystemExtSpecific() { 105 partition = ctx.DeviceConfig().SystemExtPath() 106 } else { 107 partition = ctx.DeviceConfig().ProductPath() 108 } 109 return partition 110} 111 112func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) { 113 sdkDep := decodeSdkDep(ctx, android.SdkContext(r)) 114 if sdkDep.hasFrameworkLibs() { 115 r.aapt.deps(ctx, sdkDep) 116 } 117 118 cert := android.SrcIsModule(String(r.properties.Certificate)) 119 if cert != "" { 120 ctx.AddDependency(ctx.Module(), certificateTag, cert) 121 } 122 123 ctx.AddVariationDependencies(nil, staticLibTag, r.properties.Static_libs...) 124 ctx.AddVariationDependencies(nil, libTag, r.properties.Resource_libs...) 125 126 for _, aconfig_declaration := range r.aaptProperties.Flags_packages { 127 ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration) 128 } 129} 130 131func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) { 132 // Compile and link resources 133 r.aapt.hasNoCode = true 134 // Do not remove resources without default values nor dedupe resource configurations with the same value 135 aaptLinkFlags := []string{"--no-resource-deduping", "--no-resource-removal"} 136 // Allow the override of "package name" and "overlay target package name" 137 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName()) 138 if overridden || r.overridableProperties.Package_name != nil { 139 // The product override variable has a priority over the package_name property. 140 if !overridden { 141 manifestPackageName = *r.overridableProperties.Package_name 142 } 143 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, false)...) 144 } 145 if r.overridableProperties.Target_package_name != nil { 146 aaptLinkFlags = append(aaptLinkFlags, 147 "--rename-overlay-target-package "+*r.overridableProperties.Target_package_name) 148 } 149 if r.overridableProperties.Category != nil { 150 aaptLinkFlags = append(aaptLinkFlags, 151 "--rename-overlay-category "+*r.overridableProperties.Category) 152 } 153 r.aapt.buildActions(ctx, 154 aaptBuildActionOptions{ 155 sdkContext: r, 156 enforceDefaultTargetSdkVersion: false, 157 extraLinkFlags: aaptLinkFlags, 158 aconfigTextFiles: getAconfigFilePaths(ctx), 159 }, 160 ) 161 162 // Sign the built package 163 _, _, certificates := collectAppDeps(ctx, r, false, false) 164 r.certificate, certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx) 165 signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk") 166 var lineageFile android.Path 167 if lineage := String(r.properties.Lineage); lineage != "" { 168 lineageFile = android.PathForModuleSrc(ctx, lineage) 169 } 170 171 rotationMinSdkVersion := String(r.properties.RotationMinSdkVersion) 172 173 SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, lineageFile, rotationMinSdkVersion) 174 175 r.outputFile = signed 176 partition := rroPartition(ctx) 177 r.installDir = android.PathForModuleInPartitionInstall(ctx, partition, "overlay", String(r.properties.Theme)) 178 ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile) 179} 180 181func (r *RuntimeResourceOverlay) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 182 return android.SdkSpecFrom(ctx, String(r.properties.Sdk_version)) 183} 184 185func (r *RuntimeResourceOverlay) SystemModules() string { 186 return "" 187} 188 189func (r *RuntimeResourceOverlay) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 190 if r.properties.Min_sdk_version != nil { 191 return android.ApiLevelFrom(ctx, *r.properties.Min_sdk_version) 192 } 193 return r.SdkVersion(ctx).ApiLevel 194} 195 196func (r *RuntimeResourceOverlay) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel { 197 return android.SdkSpecPrivate.ApiLevel 198} 199 200func (r *RuntimeResourceOverlay) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 201 return r.SdkVersion(ctx).ApiLevel 202} 203 204func (r *RuntimeResourceOverlay) Certificate() Certificate { 205 return r.certificate 206} 207 208func (r *RuntimeResourceOverlay) OutputFile() android.Path { 209 return r.outputFile 210} 211 212func (r *RuntimeResourceOverlay) Theme() string { 213 return String(r.properties.Theme) 214} 215 216// runtime_resource_overlay generates a resource-only apk file that can overlay application and 217// system resources at run time. 218func RuntimeResourceOverlayFactory() android.Module { 219 module := &RuntimeResourceOverlay{} 220 module.AddProperties( 221 &module.properties, 222 &module.aaptProperties, 223 &module.overridableProperties) 224 225 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 226 android.InitDefaultableModule(module) 227 android.InitOverridableModule(module, &module.properties.Overrides) 228 return module 229} 230 231// runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay 232type OverridableRuntimeResourceOverlayProperties struct { 233 // the package name of this app. The package name in the manifest file is used if one was not given. 234 Package_name *string 235 236 // the target package name of this overlay app. The target package name in the manifest file is used if one was not given. 237 Target_package_name *string 238 239 // the rro category of this overlay. The category in the manifest file is used if one was not given. 240 Category *string 241} 242 243type OverrideRuntimeResourceOverlay struct { 244 android.ModuleBase 245 android.OverrideModuleBase 246} 247 248func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(_ android.ModuleContext) { 249 // All the overrides happen in the base module. 250 // TODO(jungjw): Check the base module type. 251} 252 253// override_runtime_resource_overlay is used to create a module based on another 254// runtime_resource_overlay module by overriding some of its properties. 255func OverrideRuntimeResourceOverlayModuleFactory() android.Module { 256 m := &OverrideRuntimeResourceOverlay{} 257 m.AddProperties(&OverridableRuntimeResourceOverlayProperties{}) 258 259 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) 260 android.InitOverrideModule(m) 261 return m 262} 263