blob: ef591b76fda4be4b8cf61253af989cd32d6867af [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 Cross30e076a2015-04-13 13:58:27 -070025)
26
Colin Cross3bc7ffa2017-11-22 16:19:37 -080027func init() {
Colin Cross5ab4e6d2017-11-22 16:20:45 -080028 android.RegisterModuleType("android_app", AndroidAppFactory)
Colin Crossae5caf52018-05-22 11:11:52 -070029 android.RegisterModuleType("android_test", AndroidTestFactory)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080030}
31
Colin Cross30e076a2015-04-13 13:58:27 -070032// AndroidManifest.xml merging
33// package splits
34
Colin Crossfabb6082018-02-20 17:22:23 -080035type appProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -070036 // path to a certificate, or the name of a certificate in the default
37 // certificate directory, or blank to use the default product certificate
Nan Zhangea568a42017-11-08 21:20:04 -080038 Certificate *string
Colin Cross7d5136f2015-05-11 13:39:40 -070039
40 // paths to extra certificates to sign the apk with
41 Additional_certificates []string
42
43 // If set, create package-export.apk, which other packages can
44 // use to get PRODUCT-agnostic resource data like IDs and type definitions.
Nan Zhangea568a42017-11-08 21:20:04 -080045 Export_package_resources *bool
Colin Cross7d5136f2015-05-11 13:39:40 -070046
Colin Cross16056062017-12-13 22:46:28 -080047 // Specifies that this app should be installed to the priv-app directory,
48 // where the system will grant it additional privileges not available to
49 // normal apps.
50 Privileged *bool
Colin Crossa97c5d32018-03-28 14:58:31 -070051
52 // list of resource labels to generate individual resource packages
53 Package_splits []string
Jason Monkd4122be2018-08-10 09:33:36 -040054
55 // Names of modules to be overridden. Listed modules can only be other binaries
56 // (in Make or Soong).
57 // This does not completely prevent installation of the overridden binaries, but if both
58 // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
59 // from PRODUCT_PACKAGES.
60 Overrides []string
Colin Cross7d5136f2015-05-11 13:39:40 -070061}
62
Colin Cross30e076a2015-04-13 13:58:27 -070063type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -070064 Library
65 aapt
66
67 certificate certificate
Colin Cross30e076a2015-04-13 13:58:27 -070068
Colin Crossfabb6082018-02-20 17:22:23 -080069 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -070070
71 extraLinkFlags []string
Colin Crosse1731a52017-12-14 11:22:55 -080072}
73
Colin Cross89c31582018-04-30 15:55:11 -070074func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
75 return nil
76}
77
Colin Cross66f78822018-05-02 12:58:28 -070078func (a *AndroidApp) ExportedStaticPackages() android.Paths {
79 return nil
80}
81
Colin Cross31656952018-05-24 16:11:20 -070082func (a *AndroidApp) ExportedManifest() android.Path {
83 return a.manifestPath
84}
85
Colin Crossa97c5d32018-03-28 14:58:31 -070086var _ AndroidLibraryDependency = (*AndroidApp)(nil)
87
Colin Crosse1731a52017-12-14 11:22:55 -080088type certificate struct {
89 pem, key android.Path
Colin Cross30e076a2015-04-13 13:58:27 -070090}
91
Colin Cross46c9b8b2017-06-22 16:51:17 -070092func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
93 a.Module.deps(ctx)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080094 if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) {
Colin Cross83bb3162018-06-25 15:48:06 -070095 a.aapt.deps(ctx, sdkContext(a))
Colin Cross30e076a2015-04-13 13:58:27 -070096 }
Colin Cross30e076a2015-04-13 13:58:27 -070097}
98
Colin Cross46c9b8b2017-06-22 16:51:17 -070099func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crossae5caf52018-05-22 11:11:52 -0700100 a.generateAndroidBuildActions(ctx)
101}
102
103func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
104 linkFlags := append([]string(nil), a.extraLinkFlags...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800105
Colin Crosse78dcd32018-04-19 15:25:19 -0700106 hasProduct := false
107 for _, f := range a.aaptProperties.Aaptflags {
108 if strings.HasPrefix(f, "--product") {
109 hasProduct = true
110 }
111 }
112
113 // Product characteristics
114 if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 {
115 linkFlags = append(linkFlags, "--product", ctx.Config().ProductAAPTCharacteristics())
116 }
117
118 // Product AAPT config
119 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
120 linkFlags = append(linkFlags, "-c", aaptConfig)
121 }
122
123 // Product AAPT preferred config
124 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
125 linkFlags = append(linkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
126 }
127
Colin Crossa97c5d32018-03-28 14:58:31 -0700128 // TODO: LOCAL_PACKAGE_OVERRIDES
129 // $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800130
Colin Cross83bb3162018-06-25 15:48:06 -0700131 a.aapt.buildActions(ctx, sdkContext(a), linkFlags...)
Colin Cross30e076a2015-04-13 13:58:27 -0700132
Colin Cross46c9b8b2017-06-22 16:51:17 -0700133 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700134 a.properties.Manifest = nil
Colin Cross30e076a2015-04-13 13:58:27 -0700135
Colin Cross89c31582018-04-30 15:55:11 -0700136 var staticLibProguardFlagFiles android.Paths
137 ctx.VisitDirectDeps(func(m android.Module) {
138 if lib, ok := m.(AndroidLibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
139 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
140 }
141 })
142
143 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
144
145 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, staticLibProguardFlagFiles...)
146 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile)
Colin Cross66dbc0b2017-12-28 12:23:20 -0800147
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800148 if ctx.ModuleName() != "framework-res" {
149 a.Module.compile(ctx, a.aaptSrcJar)
150 }
Colin Cross30e076a2015-04-13 13:58:27 -0700151
Colin Crosse1731a52017-12-14 11:22:55 -0800152 c := String(a.appProperties.Certificate)
153 switch {
154 case c == "":
155 pem, key := ctx.Config().DefaultAppCertificate(ctx)
156 a.certificate = certificate{pem, key}
157 case strings.ContainsRune(c, '/'):
158 a.certificate = certificate{
159 android.PathForSource(ctx, c+".x509.pem"),
160 android.PathForSource(ctx, c+".pk8"),
161 }
162 default:
163 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
164 a.certificate = certificate{
165 defaultDir.Join(ctx, c+".x509.pem"),
166 defaultDir.Join(ctx, c+".pk8"),
167 }
Colin Cross30e076a2015-04-13 13:58:27 -0700168 }
169
Colin Crosse1731a52017-12-14 11:22:55 -0800170 certificates := []certificate{a.certificate}
Colin Cross30e076a2015-04-13 13:58:27 -0700171 for _, c := range a.appProperties.Additional_certificates {
Colin Crosse1731a52017-12-14 11:22:55 -0800172 certificates = append(certificates, certificate{
173 android.PathForSource(ctx, c+".x509.pem"),
174 android.PathForSource(ctx, c+".pk8"),
175 })
Colin Cross30e076a2015-04-13 13:58:27 -0700176 }
177
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800178 packageFile := android.PathForModuleOut(ctx, "package.apk")
179
180 CreateAppPackage(ctx, packageFile, a.exportPackage, a.outputFile, certificates)
181
182 a.outputFile = packageFile
183
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800184 if ctx.ModuleName() == "framework-res" {
185 // framework-res.apk is installed as system/framework/framework-res.apk
186 ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".apk", a.outputFile)
Colin Cross16056062017-12-13 22:46:28 -0800187 } else if Bool(a.appProperties.Privileged) {
188 ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app"), ctx.ModuleName()+".apk", a.outputFile)
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800189 } else {
190 ctx.InstallFile(android.PathForModuleInstall(ctx, "app"), ctx.ModuleName()+".apk", a.outputFile)
191 }
Colin Cross30e076a2015-04-13 13:58:27 -0700192}
193
Colin Cross36242852017-06-23 15:06:31 -0700194func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -0700195 module := &AndroidApp{}
196
Colin Cross66dbc0b2017-12-28 12:23:20 -0800197 module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
198 module.Module.deviceProperties.Optimize.Shrink = proptools.BoolPtr(true)
199
Colin Crossae5caf52018-05-22 11:11:52 -0700200 module.Module.properties.Instrument = true
Colin Cross9ae1b922018-06-26 17:59:05 -0700201 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -0700202
Colin Cross36242852017-06-23 15:06:31 -0700203 module.AddProperties(
Colin Cross540eff82017-06-22 17:01:52 -0700204 &module.Module.properties,
205 &module.Module.deviceProperties,
Colin Crossa97c5d32018-03-28 14:58:31 -0700206 &module.Module.protoProperties,
207 &module.aaptProperties,
Colin Cross540eff82017-06-22 17:01:52 -0700208 &module.appProperties)
Colin Cross36242852017-06-23 15:06:31 -0700209
210 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
211 return module
Colin Cross30e076a2015-04-13 13:58:27 -0700212}
Colin Crossae5caf52018-05-22 11:11:52 -0700213
214type appTestProperties struct {
215 Instrumentation_for *string
216}
217
218type AndroidTest struct {
219 AndroidApp
220
221 appTestProperties appTestProperties
222
223 testProperties testProperties
224}
225
226func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
227 if String(a.appTestProperties.Instrumentation_for) != "" {
228 a.AndroidApp.extraLinkFlags = append(a.AndroidApp.extraLinkFlags,
229 "--rename-instrumentation-target-package",
230 String(a.appTestProperties.Instrumentation_for))
231 }
232
233 a.generateAndroidBuildActions(ctx)
234}
235
236func AndroidTestFactory() android.Module {
237 module := &AndroidTest{}
238
239 module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
Colin Cross9ae1b922018-06-26 17:59:05 -0700240 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -0700241
242 module.AddProperties(
243 &module.Module.properties,
244 &module.Module.deviceProperties,
245 &module.Module.protoProperties,
246 &module.aaptProperties,
247 &module.appProperties,
Dan Willemsenf5531d22018-07-16 17:21:19 -0700248 &module.appTestProperties,
249 &module.testProperties)
Colin Crossae5caf52018-05-22 11:11:52 -0700250
251 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
252
253 return module
254}