blob: 7ad525d1911a4367bfb71784715e566feec0a63f [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
Colin Cross7d5136f2015-05-11 13:39:40 -070054}
55
Colin Cross30e076a2015-04-13 13:58:27 -070056type AndroidApp struct {
Colin Crossa97c5d32018-03-28 14:58:31 -070057 Library
58 aapt
59
60 certificate certificate
Colin Cross30e076a2015-04-13 13:58:27 -070061
Colin Crossfabb6082018-02-20 17:22:23 -080062 appProperties appProperties
Colin Crossae5caf52018-05-22 11:11:52 -070063
64 extraLinkFlags []string
Colin Crosse1731a52017-12-14 11:22:55 -080065}
66
Colin Cross89c31582018-04-30 15:55:11 -070067func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
68 return nil
69}
70
Colin Cross66f78822018-05-02 12:58:28 -070071func (a *AndroidApp) ExportedStaticPackages() android.Paths {
72 return nil
73}
74
Colin Cross31656952018-05-24 16:11:20 -070075func (a *AndroidApp) ExportedManifest() android.Path {
76 return a.manifestPath
77}
78
Colin Crossa97c5d32018-03-28 14:58:31 -070079var _ AndroidLibraryDependency = (*AndroidApp)(nil)
80
Colin Crosse1731a52017-12-14 11:22:55 -080081type certificate struct {
82 pem, key android.Path
Colin Cross30e076a2015-04-13 13:58:27 -070083}
84
Colin Cross46c9b8b2017-06-22 16:51:17 -070085func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
86 a.Module.deps(ctx)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080087 if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) {
Colin Cross83bb3162018-06-25 15:48:06 -070088 a.aapt.deps(ctx, sdkContext(a))
Colin Cross30e076a2015-04-13 13:58:27 -070089 }
Colin Cross30e076a2015-04-13 13:58:27 -070090}
91
Colin Cross46c9b8b2017-06-22 16:51:17 -070092func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crossae5caf52018-05-22 11:11:52 -070093 a.generateAndroidBuildActions(ctx)
94}
95
96func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
97 linkFlags := append([]string(nil), a.extraLinkFlags...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080098
Colin Crosse78dcd32018-04-19 15:25:19 -070099 hasProduct := false
100 for _, f := range a.aaptProperties.Aaptflags {
101 if strings.HasPrefix(f, "--product") {
102 hasProduct = true
103 }
104 }
105
106 // Product characteristics
107 if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 {
108 linkFlags = append(linkFlags, "--product", ctx.Config().ProductAAPTCharacteristics())
109 }
110
111 // Product AAPT config
112 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
113 linkFlags = append(linkFlags, "-c", aaptConfig)
114 }
115
116 // Product AAPT preferred config
117 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
118 linkFlags = append(linkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
119 }
120
Colin Crossa97c5d32018-03-28 14:58:31 -0700121 // TODO: LOCAL_PACKAGE_OVERRIDES
122 // $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800123
Colin Cross83bb3162018-06-25 15:48:06 -0700124 a.aapt.buildActions(ctx, sdkContext(a), linkFlags...)
Colin Cross30e076a2015-04-13 13:58:27 -0700125
Colin Cross46c9b8b2017-06-22 16:51:17 -0700126 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700127 a.properties.Manifest = nil
Colin Cross30e076a2015-04-13 13:58:27 -0700128
Colin Cross89c31582018-04-30 15:55:11 -0700129 var staticLibProguardFlagFiles android.Paths
130 ctx.VisitDirectDeps(func(m android.Module) {
131 if lib, ok := m.(AndroidLibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
132 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
133 }
134 })
135
136 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
137
138 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, staticLibProguardFlagFiles...)
139 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile)
Colin Cross66dbc0b2017-12-28 12:23:20 -0800140
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800141 if ctx.ModuleName() != "framework-res" {
142 a.Module.compile(ctx, a.aaptSrcJar)
143 }
Colin Cross30e076a2015-04-13 13:58:27 -0700144
Colin Crosse1731a52017-12-14 11:22:55 -0800145 c := String(a.appProperties.Certificate)
146 switch {
147 case c == "":
148 pem, key := ctx.Config().DefaultAppCertificate(ctx)
149 a.certificate = certificate{pem, key}
150 case strings.ContainsRune(c, '/'):
151 a.certificate = certificate{
152 android.PathForSource(ctx, c+".x509.pem"),
153 android.PathForSource(ctx, c+".pk8"),
154 }
155 default:
156 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
157 a.certificate = certificate{
158 defaultDir.Join(ctx, c+".x509.pem"),
159 defaultDir.Join(ctx, c+".pk8"),
160 }
Colin Cross30e076a2015-04-13 13:58:27 -0700161 }
162
Colin Crosse1731a52017-12-14 11:22:55 -0800163 certificates := []certificate{a.certificate}
Colin Cross30e076a2015-04-13 13:58:27 -0700164 for _, c := range a.appProperties.Additional_certificates {
Colin Crosse1731a52017-12-14 11:22:55 -0800165 certificates = append(certificates, certificate{
166 android.PathForSource(ctx, c+".x509.pem"),
167 android.PathForSource(ctx, c+".pk8"),
168 })
Colin Cross30e076a2015-04-13 13:58:27 -0700169 }
170
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800171 packageFile := android.PathForModuleOut(ctx, "package.apk")
172
173 CreateAppPackage(ctx, packageFile, a.exportPackage, a.outputFile, certificates)
174
175 a.outputFile = packageFile
176
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800177 if ctx.ModuleName() == "framework-res" {
178 // framework-res.apk is installed as system/framework/framework-res.apk
179 ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".apk", a.outputFile)
Colin Cross16056062017-12-13 22:46:28 -0800180 } else if Bool(a.appProperties.Privileged) {
181 ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app"), ctx.ModuleName()+".apk", a.outputFile)
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800182 } else {
183 ctx.InstallFile(android.PathForModuleInstall(ctx, "app"), ctx.ModuleName()+".apk", a.outputFile)
184 }
Colin Cross30e076a2015-04-13 13:58:27 -0700185}
186
Colin Cross36242852017-06-23 15:06:31 -0700187func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -0700188 module := &AndroidApp{}
189
Colin Cross66dbc0b2017-12-28 12:23:20 -0800190 module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
191 module.Module.deviceProperties.Optimize.Shrink = proptools.BoolPtr(true)
192
Colin Crossae5caf52018-05-22 11:11:52 -0700193 module.Module.properties.Instrument = true
Colin Cross9ae1b922018-06-26 17:59:05 -0700194 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -0700195
Colin Cross36242852017-06-23 15:06:31 -0700196 module.AddProperties(
Colin Cross540eff82017-06-22 17:01:52 -0700197 &module.Module.properties,
198 &module.Module.deviceProperties,
Colin Crossa97c5d32018-03-28 14:58:31 -0700199 &module.Module.protoProperties,
200 &module.aaptProperties,
Colin Cross540eff82017-06-22 17:01:52 -0700201 &module.appProperties)
Colin Cross36242852017-06-23 15:06:31 -0700202
203 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
204 return module
Colin Cross30e076a2015-04-13 13:58:27 -0700205}
Colin Crossae5caf52018-05-22 11:11:52 -0700206
207type appTestProperties struct {
208 Instrumentation_for *string
209}
210
211type AndroidTest struct {
212 AndroidApp
213
214 appTestProperties appTestProperties
215
216 testProperties testProperties
217}
218
219func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
220 if String(a.appTestProperties.Instrumentation_for) != "" {
221 a.AndroidApp.extraLinkFlags = append(a.AndroidApp.extraLinkFlags,
222 "--rename-instrumentation-target-package",
223 String(a.appTestProperties.Instrumentation_for))
224 }
225
226 a.generateAndroidBuildActions(ctx)
227}
228
229func AndroidTestFactory() android.Module {
230 module := &AndroidTest{}
231
232 module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
Colin Cross9ae1b922018-06-26 17:59:05 -0700233 module.Module.properties.Installable = proptools.BoolPtr(true)
Colin Crossae5caf52018-05-22 11:11:52 -0700234
235 module.AddProperties(
236 &module.Module.properties,
237 &module.Module.deviceProperties,
238 &module.Module.protoProperties,
239 &module.aaptProperties,
240 &module.appProperties,
241 &module.appTestProperties)
242
243 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
244
245 return module
246}