blob: 37109b56a2bc0e2ecf27f0ce7dee97883aa121f1 [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 Crossa97c5d32018-03-28 14:58:31 -070075var _ AndroidLibraryDependency = (*AndroidApp)(nil)
76
Colin Crosse1731a52017-12-14 11:22:55 -080077type certificate struct {
78 pem, key android.Path
Colin Cross30e076a2015-04-13 13:58:27 -070079}
80
Colin Cross46c9b8b2017-06-22 16:51:17 -070081func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
82 a.Module.deps(ctx)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080083 if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) {
Colin Crossa97c5d32018-03-28 14:58:31 -070084 a.aapt.deps(ctx, String(a.deviceProperties.Sdk_version))
Colin Cross30e076a2015-04-13 13:58:27 -070085 }
Colin Cross30e076a2015-04-13 13:58:27 -070086}
87
Colin Cross46c9b8b2017-06-22 16:51:17 -070088func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crossae5caf52018-05-22 11:11:52 -070089 a.generateAndroidBuildActions(ctx)
90}
91
92func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
93 linkFlags := append([]string(nil), a.extraLinkFlags...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080094
Colin Crosse78dcd32018-04-19 15:25:19 -070095 hasProduct := false
96 for _, f := range a.aaptProperties.Aaptflags {
97 if strings.HasPrefix(f, "--product") {
98 hasProduct = true
99 }
100 }
101
102 // Product characteristics
103 if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 {
104 linkFlags = append(linkFlags, "--product", ctx.Config().ProductAAPTCharacteristics())
105 }
106
107 // Product AAPT config
108 for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
109 linkFlags = append(linkFlags, "-c", aaptConfig)
110 }
111
112 // Product AAPT preferred config
113 if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
114 linkFlags = append(linkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
115 }
116
Colin Crossa97c5d32018-03-28 14:58:31 -0700117 // TODO: LOCAL_PACKAGE_OVERRIDES
118 // $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800119
Colin Crossa97c5d32018-03-28 14:58:31 -0700120 a.aapt.buildActions(ctx, String(a.deviceProperties.Sdk_version), linkFlags...)
Colin Cross30e076a2015-04-13 13:58:27 -0700121
Colin Cross46c9b8b2017-06-22 16:51:17 -0700122 // apps manifests are handled by aapt, don't let Module see them
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700123 a.properties.Manifest = nil
Colin Cross30e076a2015-04-13 13:58:27 -0700124
Colin Cross89c31582018-04-30 15:55:11 -0700125 var staticLibProguardFlagFiles android.Paths
126 ctx.VisitDirectDeps(func(m android.Module) {
127 if lib, ok := m.(AndroidLibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
128 staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
129 }
130 })
131
132 staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
133
134 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, staticLibProguardFlagFiles...)
135 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile)
Colin Cross66dbc0b2017-12-28 12:23:20 -0800136
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800137 if ctx.ModuleName() != "framework-res" {
138 a.Module.compile(ctx, a.aaptSrcJar)
139 }
Colin Cross30e076a2015-04-13 13:58:27 -0700140
Colin Crosse1731a52017-12-14 11:22:55 -0800141 c := String(a.appProperties.Certificate)
142 switch {
143 case c == "":
144 pem, key := ctx.Config().DefaultAppCertificate(ctx)
145 a.certificate = certificate{pem, key}
146 case strings.ContainsRune(c, '/'):
147 a.certificate = certificate{
148 android.PathForSource(ctx, c+".x509.pem"),
149 android.PathForSource(ctx, c+".pk8"),
150 }
151 default:
152 defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
153 a.certificate = certificate{
154 defaultDir.Join(ctx, c+".x509.pem"),
155 defaultDir.Join(ctx, c+".pk8"),
156 }
Colin Cross30e076a2015-04-13 13:58:27 -0700157 }
158
Colin Crosse1731a52017-12-14 11:22:55 -0800159 certificates := []certificate{a.certificate}
Colin Cross30e076a2015-04-13 13:58:27 -0700160 for _, c := range a.appProperties.Additional_certificates {
Colin Crosse1731a52017-12-14 11:22:55 -0800161 certificates = append(certificates, certificate{
162 android.PathForSource(ctx, c+".x509.pem"),
163 android.PathForSource(ctx, c+".pk8"),
164 })
Colin Cross30e076a2015-04-13 13:58:27 -0700165 }
166
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800167 packageFile := android.PathForModuleOut(ctx, "package.apk")
168
169 CreateAppPackage(ctx, packageFile, a.exportPackage, a.outputFile, certificates)
170
171 a.outputFile = packageFile
172
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
Colin Cross36242852017-06-23 15:06:31 -0700183func AndroidAppFactory() android.Module {
Colin Cross30e076a2015-04-13 13:58:27 -0700184 module := &AndroidApp{}
185
Colin Cross66dbc0b2017-12-28 12:23:20 -0800186 module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
187 module.Module.deviceProperties.Optimize.Shrink = proptools.BoolPtr(true)
188
Colin Crossae5caf52018-05-22 11:11:52 -0700189 module.Module.properties.Instrument = true
190
Colin Cross36242852017-06-23 15:06:31 -0700191 module.AddProperties(
Colin Cross540eff82017-06-22 17:01:52 -0700192 &module.Module.properties,
193 &module.Module.deviceProperties,
Colin Crossa97c5d32018-03-28 14:58:31 -0700194 &module.Module.protoProperties,
195 &module.aaptProperties,
Colin Cross540eff82017-06-22 17:01:52 -0700196 &module.appProperties)
Colin Cross36242852017-06-23 15:06:31 -0700197
198 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
199 return module
Colin Cross30e076a2015-04-13 13:58:27 -0700200}
Colin Crossae5caf52018-05-22 11:11:52 -0700201
202type appTestProperties struct {
203 Instrumentation_for *string
204}
205
206type AndroidTest struct {
207 AndroidApp
208
209 appTestProperties appTestProperties
210
211 testProperties testProperties
212}
213
214func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
215 if String(a.appTestProperties.Instrumentation_for) != "" {
216 a.AndroidApp.extraLinkFlags = append(a.AndroidApp.extraLinkFlags,
217 "--rename-instrumentation-target-package",
218 String(a.appTestProperties.Instrumentation_for))
219 }
220
221 a.generateAndroidBuildActions(ctx)
222}
223
224func AndroidTestFactory() android.Module {
225 module := &AndroidTest{}
226
227 module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
228
229 module.AddProperties(
230 &module.Module.properties,
231 &module.Module.deviceProperties,
232 &module.Module.protoProperties,
233 &module.aaptProperties,
234 &module.appProperties,
235 &module.appTestProperties)
236
237 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
238
239 return module
240}