blob: 0ca7a2b61ab203f61f32dbd01965954f4cc4e8ce [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 "strings"
21
Colin Cross76b5f0c2017-08-29 16:02:06 -070022 "github.com/google/blueprint/proptools"
Colin Cross30e076a2015-04-13 13:58:27 -070023
Colin Cross635c3b02016-05-18 15:37:25 -070024 "android/soong/android"
Colin Cross303e21f2018-08-07 16:49:25 -070025 "android/soong/tradefed"
Colin Cross30e076a2015-04-13 13:58:27 -070026)
27
Colin Cross3bc7ffa2017-11-22 16:19:37 -080028func init() {
Colin Cross5ab4e6d2017-11-22 16:20:45 -080029 android.RegisterModuleType("android_app", AndroidAppFactory)
Colin Crossae5caf52018-05-22 11:11:52 -070030 android.RegisterModuleType("android_test", AndroidTestFactory)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080031}
32
Colin Cross30e076a2015-04-13 13:58:27 -070033// AndroidManifest.xml merging
34// package splits
35
Colin Crossfabb6082018-02-20 17:22:23 -080036type appProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -070037 // path to a certificate, or the name of a certificate in the default
38 // certificate directory, or blank to use the default product certificate
Nan Zhangea568a42017-11-08 21:20:04 -080039 Certificate *string
Colin Cross7d5136f2015-05-11 13:39:40 -070040
41 // paths to extra certificates to sign the apk with
42 Additional_certificates []string
43
44 // If set, create package-export.apk, which other packages can
45 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080046 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070047
Colin Cross16056062017-12-13 22:46:28 -080048 // Specifies that this app should be installed to the priv-app directory,
49 // where the system will grant it additional privileges not available to
50 // normal apps.
51 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -070052
53 // list of resource labels to generate individual resource packages
54 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -040055
56 // Names of modules to be overridden. Listed modules can only be other binaries
57 // (in Make or Soong).
58 // This does not completely prevent installation of the overridden binaries, but if both
59 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
60 // from PRODUCT_PACKAGES.
61 Overrides []string
Colin Cross7d5136f2015-05-11 13:39:40 -070062}
63
Colin Cross30e076a2015-04-13 13:58:27 -070064type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -070065 Library
66 aapt
67
68 certificate certificate
Colin Cross30e076a2015-04-13 13:58:27 -070069
Colin Crossfabb6082018-02-20 17:22:23 -080070 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -070071
72 extraLinkFlags []string
Colin Crosse1731a52017-12-14 11:22:55 -080073}
74
Colin Cross89c31582018-04-30 15:55:11 -070075func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
76 return nil
77}
78
Colin Cross66f78822018-05-02 12:58:28 -070079func (a *AndroidApp) ExportedStaticPackages() android.Paths {
80 return nil
81}
82
Colin Cross31656952018-05-24 16:11:20 -070083func (a *AndroidApp) ExportedManifest() android.Path {
84 return a.manifestPath
85}
86
Colin Crossa97c5d32018-03-28 14:58:31 -070087var _ AndroidLibraryDependency = (*AndroidApp)(nil)
88
Colin Crosse1731a52017-12-14 11:22:55 -080089type certificate struct {
90 pem, key android.Path
Colin Cross30e076a2015-04-13 13:58:27 -070091}
92
Colin Cross46c9b8b2017-06-22 16:51:17 -070093func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
94 a.Module.deps(ctx)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080095 if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) {
Colin Cross83bb3162018-06-25 15:48:06 -070096 a.aapt.deps(ctx, sdkContext(a))
Colin Cross30e076a2015-04-13 13:58:27 -070097 }
Colin Cross30e076a2015-04-13 13:58:27 -070098}
99
Colin Cross46c9b8b2017-06-22 16:51:17 -0700100func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crossae5caf52018-05-22 11:11:52 -0700101 a.generateAndroidBuildActions(ctx)
102}
103
104func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
105 linkFlags := append([]string(nil), a.extraLinkFlags...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800106
Colin Crosse78dcd32018-04-19 15:25:19 -0700107 hasProduct := false
108 for _, f := range a.aaptProperties.Aaptflags {
109 if strings.HasPrefix(f, "--product") {
110 hasProduct = true
111 }
112 }
113
114 // Product characteristics
115 if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 {
116 linkFlags = append(linkFlags, "--product", ctx.Config().ProductAAPTCharacteristics())
117 }
118
119 // Product AAPT config
120 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
121 linkFlags = append(linkFlags, "-c", aaptConfig)
122 }
123
124 // Product AAPT preferred config
125 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
126 linkFlags = append(linkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
127 }
128
Colin Crossa97c5d32018-03-28 14:58:31 -0700129 // TODO: LOCAL_PACKAGE_OVERRIDES
130 // $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800131
Colin Cross83bb3162018-06-25 15:48:06 -0700132 a.aapt.buildActions(ctx, sdkContext(a), linkFlags...)
Colin Cross30e076a2015-04-13 13:58:27 -0700133
Colin Cross46c9b8b2017-06-22 16:51:17 -0700134 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700135 a.properties.Manifest = nil
Colin Cross30e076a2015-04-13 13:58:27 -0700136
Colin Cross89c31582018-04-30 15:55:11 -0700137 var staticLibProguardFlagFiles android.Paths
138 ctx.VisitDirectDeps(func(m android.Module) {
139 if lib, ok := m.(AndroidLibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
140 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
141 }
142 })
143
144 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
145
146 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, staticLibProguardFlagFiles...)
147 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile)
Colin Cross66dbc0b2017-12-28 12:23:20 -0800148
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800149 if ctx.ModuleName() != "framework-res" {
150 a.Module.compile(ctx, a.aaptSrcJar)
151 }
Colin Cross30e076a2015-04-13 13:58:27 -0700152
Colin Crosse1731a52017-12-14 11:22:55 -0800153 c := String(a.appProperties.Certificate)
154 switch {
155 case c == "":
156 pem, key := ctx.Config().DefaultAppCertificate(ctx)
157 a.certificate = certificate{pem, key}
158 case strings.ContainsRune(c, '/'):
159 a.certificate = certificate{
160 android.PathForSource(ctx, c+".x509.pem"),
161 android.PathForSource(ctx, c+".pk8"),
162 }
163 default:
164 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
165 a.certificate = certificate{
166 defaultDir.Join(ctx, c+".x509.pem"),
167 defaultDir.Join(ctx, c+".pk8"),
168 }
Colin Cross30e076a2015-04-13 13:58:27 -0700169 }
170
Colin Crosse1731a52017-12-14 11:22:55 -0800171 certificates := []certificate{a.certificate}
Colin Cross30e076a2015-04-13 13:58:27 -0700172 for _, c := range a.appProperties.Additional_certificates {
Colin Crosse1731a52017-12-14 11:22:55 -0800173 certificates = append(certificates, certificate{
174 android.PathForSource(ctx, c+".x509.pem"),
175 android.PathForSource(ctx, c+".pk8"),
176 })
Colin Cross30e076a2015-04-13 13:58:27 -0700177 }
178
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800179 packageFile := android.PathForModuleOut(ctx, "package.apk")
180
181 CreateAppPackage(ctx, packageFile, a.exportPackage, a.outputFile, certificates)
182
183 a.outputFile = packageFile
184
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800185 if ctx.ModuleName() == "framework-res" {
186 // framework-res.apk is installed as system/framework/framework-res.apk
187 ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".apk", a.outputFile)
Colin Cross16056062017-12-13 22:46:28 -0800188 } else if Bool(a.appProperties.Privileged) {
189 ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app"), ctx.ModuleName()+".apk", a.outputFile)
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800190 } else {
191 ctx.InstallFile(android.PathForModuleInstall(ctx, "app"), ctx.ModuleName()+".apk", a.outputFile)
192 }
Colin Cross30e076a2015-04-13 13:58:27 -0700193}
194
Colin Cross36242852017-06-23 15:06:31 -0700195func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -0700196 module := &AndroidApp{}
197
Colin Cross66dbc0b2017-12-28 12:23:20 -0800198 module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
199 module.Module.deviceProperties.Optimize.Shrink = proptools.BoolPtr(true)
200
Colin Crossae5caf52018-05-22 11:11:52 -0700201 module.Module.properties.Instrument = true
Colin Cross9ae1b922018-06-26 17:59:05 -0700202 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -0700203
Colin Cross36242852017-06-23 15:06:31 -0700204 module.AddProperties(
Colin Cross540eff82017-06-22 17:01:52 -0700205 &module.Module.properties,
206 &module.Module.deviceProperties,
Colin Crossa97c5d32018-03-28 14:58:31 -0700207 &module.Module.protoProperties,
208 &module.aaptProperties,
Colin Cross540eff82017-06-22 17:01:52 -0700209 &module.appProperties)
Colin Cross36242852017-06-23 15:06:31 -0700210
211 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
212 return module
Colin Cross30e076a2015-04-13 13:58:27 -0700213}
Colin Crossae5caf52018-05-22 11:11:52 -0700214
215type appTestProperties struct {
216 Instrumentation_for *string
217}
218
219type AndroidTest struct {
220 AndroidApp
221
222 appTestProperties appTestProperties
223
224 testProperties testProperties
Colin Cross303e21f2018-08-07 16:49:25 -0700225
226 testConfig android.Path
Colin Crossae5caf52018-05-22 11:11:52 -0700227}
228
229func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
230 if String(a.appTestProperties.Instrumentation_for) != "" {
231 a.AndroidApp.extraLinkFlags = append(a.AndroidApp.extraLinkFlags,
232 "--rename-instrumentation-target-package",
233 String(a.appTestProperties.Instrumentation_for))
234 }
235
236 a.generateAndroidBuildActions(ctx)
Colin Cross303e21f2018-08-07 16:49:25 -0700237
238 a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.manifestPath)
239}
240
241func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
242 android.ExtractSourceDeps(ctx, a.testProperties.Test_config)
243 a.AndroidApp.DepsMutator(ctx)
Colin Crossae5caf52018-05-22 11:11:52 -0700244}
245
246func AndroidTestFactory() android.Module {
247 module := &AndroidTest{}
248
249 module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
Colin Cross9ae1b922018-06-26 17:59:05 -0700250 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -0700251
252 module.AddProperties(
253 &module.Module.properties,
254 &module.Module.deviceProperties,
255 &module.Module.protoProperties,
256 &module.aaptProperties,
257 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -0700258 &module.appTestProperties,
259 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -0700260
261 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
262
263 return module
264}