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 127func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) { 128 // Compile and link resources 129 r.aapt.hasNoCode = true 130 // Do not remove resources without default values nor dedupe resource configurations with the same value 131 aaptLinkFlags := []string{"--no-resource-deduping", "--no-resource-removal"} 132 // Allow the override of "package name" and "overlay target package name" 133 manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName()) 134 if overridden || r.overridableProperties.Package_name != nil { 135 // The product override variable has a priority over the package_name property. 136 if !overridden { 137 manifestPackageName = *r.overridableProperties.Package_name 138 } 139 aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, false)...) 140 } 141 if r.overridableProperties.Target_package_name != nil { 142 aaptLinkFlags = append(aaptLinkFlags, 143 "--rename-overlay-target-package "+*r.overridableProperties.Target_package_name) 144 } 145 r.aapt.buildActions(ctx, r, nil, nil, aaptLinkFlags...) 146 147 // Sign the built package 148 _, certificates := collectAppDeps(ctx, r, false, false) 149 certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx) 150 signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk") 151 var lineageFile android.Path 152 if lineage := String(r.properties.Lineage); lineage != "" { 153 lineageFile = android.PathForModuleSrc(ctx, lineage) 154 } 155 156 rotationMinSdkVersion := String(r.properties.RotationMinSdkVersion) 157 158 SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, lineageFile, rotationMinSdkVersion) 159 r.certificate = certificates[0] 160 161 r.outputFile = signed 162 partition := rroPartition(ctx) 163 r.installDir = android.PathForModuleInPartitionInstall(ctx, partition, "overlay", String(r.properties.Theme)) 164 ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile) 165} 166 167func (r *RuntimeResourceOverlay) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 168 return android.SdkSpecFrom(ctx, String(r.properties.Sdk_version)) 169} 170 171func (r *RuntimeResourceOverlay) SystemModules() string { 172 return "" 173} 174 175func (r *RuntimeResourceOverlay) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 176 if r.properties.Min_sdk_version != nil { 177 return android.SdkSpecFrom(ctx, *r.properties.Min_sdk_version) 178 } 179 return r.SdkVersion(ctx) 180} 181 182func (r *RuntimeResourceOverlay) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 183 return r.SdkVersion(ctx) 184} 185 186func (r *RuntimeResourceOverlay) Certificate() Certificate { 187 return r.certificate 188} 189 190func (r *RuntimeResourceOverlay) OutputFile() android.Path { 191 return r.outputFile 192} 193 194func (r *RuntimeResourceOverlay) Theme() string { 195 return String(r.properties.Theme) 196} 197 198// runtime_resource_overlay generates a resource-only apk file that can overlay application and 199// system resources at run time. 200func RuntimeResourceOverlayFactory() android.Module { 201 module := &RuntimeResourceOverlay{} 202 module.AddProperties( 203 &module.properties, 204 &module.aaptProperties, 205 &module.overridableProperties) 206 207 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) 208 android.InitDefaultableModule(module) 209 android.InitOverridableModule(module, &module.properties.Overrides) 210 return module 211} 212 213// runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay 214type OverridableRuntimeResourceOverlayProperties struct { 215 // the package name of this app. The package name in the manifest file is used if one was not given. 216 Package_name *string 217 218 // the target package name of this overlay app. The target package name in the manifest file is used if one was not given. 219 Target_package_name *string 220} 221 222type OverrideRuntimeResourceOverlay struct { 223 android.ModuleBase 224 android.OverrideModuleBase 225} 226 227func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(_ android.ModuleContext) { 228 // All the overrides happen in the base module. 229 // TODO(jungjw): Check the base module type. 230} 231 232// override_runtime_resource_overlay is used to create a module based on another 233// runtime_resource_overlay module by overriding some of its properties. 234func OverrideRuntimeResourceOverlayModuleFactory() android.Module { 235 m := &OverrideRuntimeResourceOverlay{} 236 m.AddProperties(&OverridableRuntimeResourceOverlayProperties{}) 237 238 android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) 239 android.InitOverrideModule(m) 240 return m 241} 242