blob: dc7f84876702745d313d667f56396dec842c0fff [file] [log] [blame]
Colin Cross30e076a2015-04-13 13:58:27 -07001// Copyright 2015 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 types for compiling Android apps.
18
19import (
Colin Cross30e076a2015-04-13 13:58:27 -070020 "path/filepath"
21 "strings"
22
Colin Cross76b5f0c2017-08-29 16:02:06 -070023 "github.com/google/blueprint/proptools"
Colin Cross30e076a2015-04-13 13:58:27 -070024
Colin Cross635c3b02016-05-18 15:37:25 -070025 "android/soong/android"
Colin Cross30e076a2015-04-13 13:58:27 -070026)
27
Colin Cross3bc7ffa2017-11-22 16:19:37 -080028func init() {
29 android.RegisterPreSingletonType("overlay", OverlaySingletonFactory)
Colin Cross5ab4e6d2017-11-22 16:20:45 -080030 android.RegisterModuleType("android_app", AndroidAppFactory)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080031}
32
Colin Cross30e076a2015-04-13 13:58:27 -070033// AAR prebuilts
34// AndroidManifest.xml merging
35// package splits
36
Colin Cross7d5136f2015-05-11 13:39:40 -070037type androidAppProperties struct {
38 // path to a certificate, or the name of a certificate in the default
39 // certificate directory, or blank to use the default product certificate
Nan Zhangea568a42017-11-08 21:20:04 -080040 Certificate *string
Colin Cross7d5136f2015-05-11 13:39:40 -070041
42 // paths to extra certificates to sign the apk with
43 Additional_certificates []string
44
45 // If set, create package-export.apk, which other packages can
46 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080047 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070048
49 // flags passed to aapt when creating the apk
50 Aaptflags []string
51
52 // list of resource labels to generate individual resource packages
53 Package_splits []string
54
55 // list of directories relative to the Blueprints file containing assets.
56 // Defaults to "assets"
57 Asset_dirs []string
58
59 // list of directories relative to the Blueprints file containing
Colin Cross86a63ff2017-09-27 17:33:10 -070060 // Android resources
61 Resource_dirs []string
Colin Crosscb933592017-11-22 13:49:43 -080062
63 Instrumentation_for *string
Colin Cross16056062017-12-13 22:46:28 -080064
65 // Specifies that this app should be installed to the priv-app directory,
66 // where the system will grant it additional privileges not available to
67 // normal apps.
68 Privileged *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070069}
70
Colin Cross30e076a2015-04-13 13:58:27 -070071type AndroidApp struct {
Colin Cross46c9b8b2017-06-22 16:51:17 -070072 Module
Colin Cross30e076a2015-04-13 13:58:27 -070073
Colin Cross7d5136f2015-05-11 13:39:40 -070074 appProperties androidAppProperties
Colin Cross30e076a2015-04-13 13:58:27 -070075
Colin Cross3bc7ffa2017-11-22 16:19:37 -080076 aaptSrcJar android.Path
77 exportPackage android.Path
Colin Cross890ff552017-11-30 20:13:19 -080078 rroDirs android.Paths
79 manifestPath android.Path
Colin Crosse1731a52017-12-14 11:22:55 -080080 certificate certificate
81}
82
83type certificate struct {
84 pem, key android.Path
Colin Cross30e076a2015-04-13 13:58:27 -070085}
86
Colin Cross46c9b8b2017-06-22 16:51:17 -070087func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
88 a.Module.deps(ctx)
Colin Cross30e076a2015-04-13 13:58:27 -070089
Colin Cross3bc7ffa2017-11-22 16:19:37 -080090 if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) {
Nan Zhangea568a42017-11-08 21:20:04 -080091 switch String(a.deviceProperties.Sdk_version) { // TODO: Res_sdk_version?
Colin Cross5ab4e6d2017-11-22 16:20:45 -080092 case "current", "system_current", "test_current", "":
Colin Crossbe1da472017-07-07 15:59:46 -070093 ctx.AddDependency(ctx.Module(), frameworkResTag, "framework-res")
Colin Cross30e076a2015-04-13 13:58:27 -070094 default:
95 // We'll already have a dependency on an sdk prebuilt android.jar
96 }
97 }
Colin Cross30e076a2015-04-13 13:58:27 -070098}
99
Colin Cross46c9b8b2017-06-22 16:51:17 -0700100func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross890ff552017-11-30 20:13:19 -0800101 linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, manifestPath := a.aapt2Flags(ctx)
Colin Cross30e076a2015-04-13 13:58:27 -0700102
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800103 packageRes := android.PathForModuleOut(ctx, "package-res.apk")
104 srcJar := android.PathForModuleGen(ctx, "R.jar")
105 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
Colin Cross30e076a2015-04-13 13:58:27 -0700106
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800107 var compiledRes, compiledOverlay android.Paths
108 for _, dir := range resDirs {
109 compiledRes = append(compiledRes, aapt2Compile(ctx, dir.dir, dir.files).Paths()...)
Colin Cross30e076a2015-04-13 13:58:27 -0700110 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800111 for _, dir := range overlayDirs {
112 compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files).Paths()...)
113 }
114
115 aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile,
116 linkFlags, linkDeps, compiledRes, compiledOverlay)
117
118 a.exportPackage = packageRes
119 a.aaptSrcJar = srcJar
120
121 ctx.CheckbuildFile(proguardOptionsFile)
122 ctx.CheckbuildFile(a.exportPackage)
123 ctx.CheckbuildFile(a.aaptSrcJar)
Colin Cross30e076a2015-04-13 13:58:27 -0700124
Colin Cross46c9b8b2017-06-22 16:51:17 -0700125 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700126 a.properties.Manifest = nil
Colin Cross30e076a2015-04-13 13:58:27 -0700127
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800128 if String(a.appProperties.Instrumentation_for) == "" {
129 a.properties.Instrument = true
130 }
131
Colin Cross66dbc0b2017-12-28 12:23:20 -0800132 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles,
133 proguardOptionsFile)
134
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800135 if ctx.ModuleName() != "framework-res" {
136 a.Module.compile(ctx, a.aaptSrcJar)
137 }
Colin Cross30e076a2015-04-13 13:58:27 -0700138
Colin Crosse1731a52017-12-14 11:22:55 -0800139 c := String(a.appProperties.Certificate)
140 switch {
141 case c == "":
142 pem, key := ctx.Config().DefaultAppCertificate(ctx)
143 a.certificate = certificate{pem, key}
144 case strings.ContainsRune(c, '/'):
145 a.certificate = certificate{
146 android.PathForSource(ctx, c+".x509.pem"),
147 android.PathForSource(ctx, c+".pk8"),
148 }
149 default:
150 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
151 a.certificate = certificate{
152 defaultDir.Join(ctx, c+".x509.pem"),
153 defaultDir.Join(ctx, c+".pk8"),
154 }
Colin Cross30e076a2015-04-13 13:58:27 -0700155 }
156
Colin Crosse1731a52017-12-14 11:22:55 -0800157 certificates := []certificate{a.certificate}
Colin Cross30e076a2015-04-13 13:58:27 -0700158 for _, c := range a.appProperties.Additional_certificates {
Colin Crosse1731a52017-12-14 11:22:55 -0800159 certificates = append(certificates, certificate{
160 android.PathForSource(ctx, c+".x509.pem"),
161 android.PathForSource(ctx, c+".pk8"),
162 })
Colin Cross30e076a2015-04-13 13:58:27 -0700163 }
164
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800165 packageFile := android.PathForModuleOut(ctx, "package.apk")
166
167 CreateAppPackage(ctx, packageFile, a.exportPackage, a.outputFile, certificates)
168
169 a.outputFile = packageFile
Colin Cross890ff552017-11-30 20:13:19 -0800170 a.rroDirs = rroDirs
171 a.manifestPath = manifestPath
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800172
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800173 if ctx.ModuleName() == "framework-res" {
174 // framework-res.apk is installed as system/framework/framework-res.apk
175 ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".apk", a.outputFile)
Colin Cross16056062017-12-13 22:46:28 -0800176 } else if Bool(a.appProperties.Privileged) {
177 ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app"), ctx.ModuleName()+".apk", a.outputFile)
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800178 } else {
179 ctx.InstallFile(android.PathForModuleInstall(ctx, "app"), ctx.ModuleName()+".apk", a.outputFile)
180 }
Colin Cross30e076a2015-04-13 13:58:27 -0700181}
182
183var aaptIgnoreFilenames = []string{
184 ".svn",
185 ".git",
186 ".ds_store",
187 "*.scc",
188 ".*",
189 "CVS",
190 "thumbs.db",
191 "picasa.ini",
192 "*~",
193}
194
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800195type globbedResourceDir struct {
196 dir android.Path
197 files android.Paths
198}
199
200func (a *AndroidApp) aapt2Flags(ctx android.ModuleContext) (flags []string, deps android.Paths,
Colin Cross890ff552017-11-30 20:13:19 -0800201 resDirs, overlayDirs []globbedResourceDir, rroDirs android.Paths, manifestPath android.Path) {
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800202
Colin Cross30e076a2015-04-13 13:58:27 -0700203 hasVersionCode := false
204 hasVersionName := false
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800205 hasProduct := false
206 for _, f := range a.appProperties.Aaptflags {
Colin Cross30e076a2015-04-13 13:58:27 -0700207 if strings.HasPrefix(f, "--version-code") {
208 hasVersionCode = true
209 } else if strings.HasPrefix(f, "--version-name") {
210 hasVersionName = true
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800211 } else if strings.HasPrefix(f, "--product") {
212 hasProduct = true
Colin Cross30e076a2015-04-13 13:58:27 -0700213 }
214 }
215
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800216 var linkFlags []string
Colin Cross30e076a2015-04-13 13:58:27 -0700217
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800218 // Flags specified in Android.bp
219 linkFlags = append(linkFlags, a.appProperties.Aaptflags...)
220
221 linkFlags = append(linkFlags, "--no-static-lib-packages")
222
223 // Find implicit or explicit asset and resource dirs
Colin Cross635c3b02016-05-18 15:37:25 -0700224 assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.appProperties.Asset_dirs, "assets")
Colin Cross86a63ff2017-09-27 17:33:10 -0700225 resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.appProperties.Resource_dirs, "res")
Colin Cross30e076a2015-04-13 13:58:27 -0700226
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800227 var linkDeps android.Paths
228
229 // Glob directories into lists of paths
230 for _, dir := range resourceDirs {
231 resDirs = append(resDirs, globbedResourceDir{
232 dir: dir,
233 files: resourceGlob(ctx, dir),
234 })
Colin Cross890ff552017-11-30 20:13:19 -0800235 resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, dir)
236 overlayDirs = append(overlayDirs, resOverlayDirs...)
237 rroDirs = append(rroDirs, resRRODirs...)
Colin Cross30e076a2015-04-13 13:58:27 -0700238 }
239
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800240 var assetFiles android.Paths
241 for _, dir := range assetDirs {
242 assetFiles = append(assetFiles, resourceGlob(ctx, dir)...)
Colin Cross30e076a2015-04-13 13:58:27 -0700243 }
244
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800245 // App manifest file
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700246 var manifestFile string
247 if a.properties.Manifest == nil {
Colin Cross30e076a2015-04-13 13:58:27 -0700248 manifestFile = "AndroidManifest.xml"
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700249 } else {
250 manifestFile = *a.properties.Manifest
Colin Cross30e076a2015-04-13 13:58:27 -0700251 }
252
Colin Cross890ff552017-11-30 20:13:19 -0800253 manifestPath = android.PathForModuleSrc(ctx, manifestFile)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800254 linkFlags = append(linkFlags, "--manifest "+manifestPath.String())
255 linkDeps = append(linkDeps, manifestPath)
Colin Cross30e076a2015-04-13 13:58:27 -0700256
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800257 linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirs.Strings(), "-A "))
258 linkDeps = append(linkDeps, assetFiles...)
Colin Cross30e076a2015-04-13 13:58:27 -0700259
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800260 // Include dirs
Colin Crossd11fcda2017-10-23 17:59:01 -0700261 ctx.VisitDirectDeps(func(module android.Module) {
Colin Cross74d73e22017-08-02 11:05:49 -0700262 var depFiles android.Paths
Colin Crossfc3674a2017-09-18 17:41:52 -0700263 if javaDep, ok := module.(Dependency); ok {
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800264 // TODO: shared android libraries
Colin Cross30e076a2015-04-13 13:58:27 -0700265 if ctx.OtherModuleName(module) == "framework-res" {
Colin Cross74d73e22017-08-02 11:05:49 -0700266 depFiles = android.Paths{javaDep.(*AndroidApp).exportPackage}
Colin Cross30e076a2015-04-13 13:58:27 -0700267 }
268 }
Colin Cross74d73e22017-08-02 11:05:49 -0700269
270 for _, dep := range depFiles {
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800271 linkFlags = append(linkFlags, "-I "+dep.String())
Colin Cross30e076a2015-04-13 13:58:27 -0700272 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800273 linkDeps = append(linkDeps, depFiles...)
Colin Cross30e076a2015-04-13 13:58:27 -0700274 })
275
Colin Cross9ca69422018-02-20 15:30:31 -0800276 sdkDep := decodeSdkDep(ctx, String(a.deviceProperties.Sdk_version))
277 if sdkDep.useFiles {
278 linkFlags = append(linkFlags, "-I "+sdkDep.jar.String())
279 linkDeps = append(linkDeps, sdkDep.jar)
280 }
281
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800282 // SDK version flags
Nan Zhangea568a42017-11-08 21:20:04 -0800283 sdkVersion := String(a.deviceProperties.Sdk_version)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800284 switch sdkVersion {
285 case "", "current", "system_current", "test_current":
Colin Cross42f3a762017-12-02 16:14:26 -0800286 sdkVersion = proptools.NinjaEscape([]string{ctx.Config().AppsDefaultVersionName()})[0]
Colin Cross30e076a2015-04-13 13:58:27 -0700287 }
288
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800289 linkFlags = append(linkFlags, "--min-sdk-version "+sdkVersion)
290 linkFlags = append(linkFlags, "--target-sdk-version "+sdkVersion)
Colin Cross30e076a2015-04-13 13:58:27 -0700291
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800292 // Product characteristics
Colin Cross6510f912017-11-29 00:27:14 -0800293 if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 {
294 linkFlags = append(linkFlags, "--product", ctx.Config().ProductAAPTCharacteristics())
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800295 }
296
297 // Product AAPT config
Colin Cross6510f912017-11-29 00:27:14 -0800298 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800299 linkFlags = append(linkFlags, "-c", aaptConfig)
300 }
301
302 // Product AAPT preferred config
Colin Cross6510f912017-11-29 00:27:14 -0800303 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
304 linkFlags = append(linkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800305 }
306
307 // Version code
Colin Cross30e076a2015-04-13 13:58:27 -0700308 if !hasVersionCode {
Colin Cross6510f912017-11-29 00:27:14 -0800309 linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion())
Colin Cross30e076a2015-04-13 13:58:27 -0700310 }
311
312 if !hasVersionName {
Colin Cross6510f912017-11-29 00:27:14 -0800313 versionName := proptools.NinjaEscape([]string{ctx.Config().AppsDefaultVersionName()})[0]
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800314 linkFlags = append(linkFlags, "--version-name ", versionName)
315 }
316
317 if String(a.appProperties.Instrumentation_for) != "" {
318 linkFlags = append(linkFlags,
319 "--rename-instrumentation-target-package",
320 String(a.appProperties.Instrumentation_for))
Colin Cross30e076a2015-04-13 13:58:27 -0700321 }
322
323 // TODO: LOCAL_PACKAGE_OVERRIDES
324 // $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
325
Colin Cross890ff552017-11-30 20:13:19 -0800326 return linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, manifestPath
Colin Cross30e076a2015-04-13 13:58:27 -0700327}
328
Colin Cross36242852017-06-23 15:06:31 -0700329func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -0700330 module := &AndroidApp{}
331
Colin Cross66dbc0b2017-12-28 12:23:20 -0800332 module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
333 module.Module.deviceProperties.Optimize.Shrink = proptools.BoolPtr(true)
334
Colin Cross36242852017-06-23 15:06:31 -0700335 module.AddProperties(
Colin Cross540eff82017-06-22 17:01:52 -0700336 &module.Module.properties,
337 &module.Module.deviceProperties,
338 &module.appProperties)
Colin Cross36242852017-06-23 15:06:31 -0700339
340 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
341 return module
Colin Cross30e076a2015-04-13 13:58:27 -0700342}
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800343
344func resourceGlob(ctx android.ModuleContext, dir android.Path) android.Paths {
345 var ret android.Paths
346 files := ctx.Glob(filepath.Join(dir.String(), "**/*"), aaptIgnoreFilenames)
347 for _, f := range files {
348 if isDir, err := ctx.Fs().IsDir(f.String()); err != nil {
349 ctx.ModuleErrorf("error in IsDir(%s): %s", f.String(), err.Error())
350 return nil
351 } else if !isDir {
352 ret = append(ret, f)
353 }
354 }
355 return ret
356}
357
358type overlayGlobResult struct {
359 dir string
360 paths android.DirectorySortedPaths
Colin Cross890ff552017-11-30 20:13:19 -0800361
362 // Set to true of the product has selected that values in this overlay should not be moved to
363 // Runtime Resource Overlay (RRO) packages.
364 excludeFromRRO bool
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800365}
366
367const overlayDataKey = "overlayDataKey"
368
Colin Cross890ff552017-11-30 20:13:19 -0800369func overlayResourceGlob(ctx android.ModuleContext, dir android.Path) (res []globbedResourceDir,
370 rroDirs android.Paths) {
371
Colin Cross6510f912017-11-29 00:27:14 -0800372 overlayData := ctx.Config().Get(overlayDataKey).([]overlayGlobResult)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800373
Colin Cross890ff552017-11-30 20:13:19 -0800374 // Runtime resource overlays (RRO) may be turned on by the product config for some modules
375 rroEnabled := false
376 enforceRROTargets := ctx.Config().ProductVariables.EnforceRROTargets
377 if enforceRROTargets != nil {
378 if len(*enforceRROTargets) == 1 && (*enforceRROTargets)[0] == "*" {
379 rroEnabled = true
380 } else if inList(ctx.ModuleName(), *enforceRROTargets) {
381 rroEnabled = true
382 }
383 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800384
385 for _, data := range overlayData {
386 files := data.paths.PathsInDirectory(filepath.Join(data.dir, dir.String()))
387 if len(files) > 0 {
Colin Cross890ff552017-11-30 20:13:19 -0800388 overlayModuleDir := android.PathForSource(ctx, data.dir, dir.String())
389 // If enforce RRO is enabled for this module and this overlay is not in the
390 // exclusion list, ignore the overlay. The list of ignored overlays will be
391 // passed to Make to be turned into an RRO package.
392 if rroEnabled && !data.excludeFromRRO {
393 rroDirs = append(rroDirs, overlayModuleDir)
394 } else {
395 res = append(res, globbedResourceDir{
396 dir: overlayModuleDir,
397 files: files,
398 })
399 }
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800400 }
401 }
402
Colin Cross890ff552017-11-30 20:13:19 -0800403 return res, rroDirs
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800404}
405
406func OverlaySingletonFactory() android.Singleton {
407 return overlaySingleton{}
408}
409
410type overlaySingleton struct{}
411
412func (overlaySingleton) GenerateBuildActions(ctx android.SingletonContext) {
Colin Cross890ff552017-11-30 20:13:19 -0800413
414 // Specific overlays may be excluded from Runtime Resource Overlays by the product config
415 var rroExcludedOverlays []string
416 if ctx.Config().ProductVariables.EnforceRROExcludedOverlays != nil {
417 rroExcludedOverlays = *ctx.Config().ProductVariables.EnforceRROExcludedOverlays
418 }
419
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800420 var overlayData []overlayGlobResult
Colin Cross68a70232018-01-04 14:50:13 -0800421 overlayDirs := ctx.Config().ResourceOverlays()
422 for i := range overlayDirs {
423 // Iterate backwards through the list of overlay directories so that the later, lower-priority
424 // directories in the list show up earlier in the command line to aapt2.
425 overlay := overlayDirs[len(overlayDirs)-1-i]
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800426 var result overlayGlobResult
427 result.dir = overlay
Colin Cross890ff552017-11-30 20:13:19 -0800428
429 // Mark overlays that will not have Runtime Resource Overlays enforced on them
430 for _, exclude := range rroExcludedOverlays {
431 if strings.HasPrefix(overlay, exclude) {
432 result.excludeFromRRO = true
433 }
434 }
435
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800436 files, err := ctx.GlobWithDeps(filepath.Join(overlay, "**/*"), aaptIgnoreFilenames)
437 if err != nil {
438 ctx.Errorf("failed to glob resource dir %q: %s", overlay, err.Error())
439 continue
440 }
441 var paths android.Paths
442 for _, f := range files {
443 if isDir, err := ctx.Fs().IsDir(f); err != nil {
444 ctx.Errorf("error in IsDir(%s): %s", f, err.Error())
445 return
446 } else if !isDir {
447 paths = append(paths, android.PathForSource(ctx, f))
448 }
449 }
450 result.paths = android.PathsToDirectorySortedPaths(paths)
451 overlayData = append(overlayData, result)
452 }
453
Colin Crossaabf6792017-11-29 00:27:14 -0800454 ctx.Config().Once(overlayDataKey, func() interface{} {
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800455 return overlayData
456 })
457}