2015-04-13 22:58:27 +02:00
|
|
|
// Copyright 2015 Google Inc. All rights reserved.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package java
|
|
|
|
|
|
|
|
// This file contains the module types for compiling Android apps.
|
|
|
|
|
|
|
|
import (
|
2019-04-26 23:31:50 +02:00
|
|
|
"path/filepath"
|
|
|
|
"reflect"
|
2019-06-18 02:40:56 +02:00
|
|
|
"sort"
|
2019-04-26 23:31:50 +02:00
|
|
|
"strings"
|
2015-04-13 22:58:27 +02:00
|
|
|
|
2019-05-16 21:28:22 +02:00
|
|
|
"github.com/google/blueprint"
|
|
|
|
"github.com/google/blueprint/proptools"
|
|
|
|
|
2016-05-19 00:37:25 +02:00
|
|
|
"android/soong/android"
|
2018-10-03 07:03:40 +02:00
|
|
|
"android/soong/cc"
|
2018-08-08 01:49:25 +02:00
|
|
|
"android/soong/tradefed"
|
2015-04-13 22:58:27 +02:00
|
|
|
)
|
|
|
|
|
2019-06-11 21:25:34 +02:00
|
|
|
var supportedDpis = []string{"ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"}
|
2019-04-26 23:31:50 +02:00
|
|
|
|
2017-11-23 01:19:37 +01:00
|
|
|
func init() {
|
2019-12-18 20:51:55 +01:00
|
|
|
RegisterAppBuildComponents(android.InitRegistrationContext)
|
2019-08-13 23:11:33 +02:00
|
|
|
|
|
|
|
initAndroidAppImportVariantGroupTypes()
|
2017-11-23 01:19:37 +01:00
|
|
|
}
|
|
|
|
|
2019-12-18 20:51:55 +01:00
|
|
|
func RegisterAppBuildComponents(ctx android.RegistrationContext) {
|
|
|
|
ctx.RegisterModuleType("android_app", AndroidAppFactory)
|
|
|
|
ctx.RegisterModuleType("android_test", AndroidTestFactory)
|
|
|
|
ctx.RegisterModuleType("android_test_helper_app", AndroidTestHelperAppFactory)
|
|
|
|
ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
|
|
|
|
ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
|
|
|
|
ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
|
2020-04-27 18:42:27 +02:00
|
|
|
ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory)
|
2019-12-18 20:51:55 +01:00
|
|
|
ctx.RegisterModuleType("android_app_import", AndroidAppImportFactory)
|
|
|
|
ctx.RegisterModuleType("android_test_import", AndroidTestImportFactory)
|
2020-01-18 19:33:43 +01:00
|
|
|
ctx.RegisterModuleType("runtime_resource_overlay", RuntimeResourceOverlayFactory)
|
2019-12-18 20:51:55 +01:00
|
|
|
}
|
|
|
|
|
2015-04-13 22:58:27 +02:00
|
|
|
// AndroidManifest.xml merging
|
|
|
|
// package splits
|
|
|
|
|
2018-02-21 02:22:23 +01:00
|
|
|
type appProperties struct {
|
2018-10-05 00:21:03 +02:00
|
|
|
// Names of extra android_app_certificate modules to sign the apk with in the form ":module".
|
2015-05-11 22:39:40 +02:00
|
|
|
Additional_certificates []string
|
2015-04-13 22:58:27 +02:00
|
|
|
|
2015-05-11 22:39:40 +02:00
|
|
|
// If set, create package-export.apk, which other packages can
|
|
|
|
// use to get PRODUCT-agnostic resource data like IDs and type definitions.
|
2017-11-09 06:20:04 +01:00
|
|
|
Export_package_resources *bool
|
2015-04-13 22:58:27 +02:00
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
// Specifies that this app should be installed to the priv-app directory,
|
|
|
|
// where the system will grant it additional privileges not available to
|
|
|
|
// normal apps.
|
|
|
|
Privileged *bool
|
2015-04-13 22:58:27 +02:00
|
|
|
|
2015-05-11 22:39:40 +02:00
|
|
|
// list of resource labels to generate individual resource packages
|
|
|
|
Package_splits []string
|
2018-08-10 15:33:36 +02:00
|
|
|
|
|
|
|
// Names of modules to be overridden. Listed modules can only be other binaries
|
|
|
|
// (in Make or Soong).
|
|
|
|
// This does not completely prevent installation of the overridden binaries, but if both
|
|
|
|
// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
|
|
|
|
// from PRODUCT_PACKAGES.
|
|
|
|
Overrides []string
|
2018-10-03 07:03:40 +02:00
|
|
|
|
|
|
|
// list of native libraries that will be provided in or alongside the resulting jar
|
|
|
|
Jni_libs []string `android:"arch_variant"`
|
|
|
|
|
2020-05-07 02:51:39 +02:00
|
|
|
// if true, use JNI libraries that link against platform APIs even if this module sets
|
2020-02-20 01:57:15 +01:00
|
|
|
// sdk_version.
|
|
|
|
Jni_uses_platform_apis *bool
|
|
|
|
|
2020-05-07 02:51:39 +02:00
|
|
|
// if true, use JNI libraries that link against SDK APIs even if this module does not set
|
|
|
|
// sdk_version.
|
|
|
|
Jni_uses_sdk_apis *bool
|
|
|
|
|
2019-05-07 00:48:44 +02:00
|
|
|
// STL library to use for JNI libraries.
|
|
|
|
Stl *string `android:"arch_variant"`
|
|
|
|
|
2019-02-06 06:55:21 +01:00
|
|
|
// Store native libraries uncompressed in the APK and set the android:extractNativeLibs="false" manifest
|
|
|
|
// flag so that they are used from inside the APK at runtime. Defaults to true for android_test modules unless
|
2019-11-11 02:14:32 +01:00
|
|
|
// sdk_version or min_sdk_version is set to a version that doesn't support it (<23), defaults to true for
|
|
|
|
// android_app modules that are embedded to APEXes, defaults to false for other module types where the native
|
|
|
|
// libraries are generally preinstalled outside the APK.
|
2019-02-06 06:55:21 +01:00
|
|
|
Use_embedded_native_libs *bool
|
2019-02-07 22:07:08 +01:00
|
|
|
|
|
|
|
// Store dex files uncompressed in the APK and set the android:useEmbeddedDex="true" manifest attribute so that
|
|
|
|
// they are used from inside the APK at runtime.
|
|
|
|
Use_embedded_dex *bool
|
2019-03-26 18:51:39 +01:00
|
|
|
|
|
|
|
// Forces native libraries to always be packaged into the APK,
|
|
|
|
// Use_embedded_native_libs still selects whether they are stored uncompressed and aligned or compressed.
|
|
|
|
// True for android_test* modules.
|
|
|
|
AlwaysPackageNativeLibs bool `blueprint:"mutated"`
|
2019-06-18 02:40:56 +02:00
|
|
|
|
|
|
|
// If set, find and merge all NOTICE files that this module and its dependencies have and store
|
|
|
|
// it in the APK as an asset.
|
|
|
|
Embed_notices *bool
|
2020-03-26 22:01:48 +01:00
|
|
|
|
|
|
|
// cc.Coverage related properties
|
|
|
|
PreventInstall bool `blueprint:"mutated"`
|
|
|
|
HideFromMake bool `blueprint:"mutated"`
|
|
|
|
IsCoverageVariant bool `blueprint:"mutated"`
|
2020-04-08 20:09:30 +02:00
|
|
|
|
|
|
|
// Whether this app is considered mainline updatable or not. When set to true, this will enforce
|
2020-04-16 14:43:02 +02:00
|
|
|
// additional rules to make sure an app can safely be updated. Default is false.
|
|
|
|
// Prefer using other specific properties if build behaviour must be changed; avoid using this
|
|
|
|
// flag for anything but neverallow rules (unless the behaviour change is invisible to owners).
|
2020-04-08 20:09:30 +02:00
|
|
|
Updatable *bool
|
2015-05-11 22:39:40 +02:00
|
|
|
}
|
2015-04-13 22:58:27 +02:00
|
|
|
|
2019-03-01 00:35:54 +01:00
|
|
|
// android_app properties that can be overridden by override_android_app
|
|
|
|
type overridableAppProperties struct {
|
|
|
|
// The name of a certificate in the default certificate directory, blank to use the default product certificate,
|
|
|
|
// or an android_app_certificate module name in the form ":module".
|
|
|
|
Certificate *string
|
2019-03-13 18:13:24 +01:00
|
|
|
|
2020-05-07 22:24:05 +02:00
|
|
|
// Name of the signing certificate lineage file.
|
|
|
|
Lineage *string
|
|
|
|
|
2019-03-13 18:13:24 +01:00
|
|
|
// the package name of this app. The package name in the manifest file is used if one was not given.
|
|
|
|
Package_name *string
|
2020-02-12 02:27:19 +01:00
|
|
|
|
|
|
|
// the logging parent of this app.
|
|
|
|
Logging_parent *string
|
2019-03-01 00:35:54 +01:00
|
|
|
}
|
|
|
|
|
2020-04-27 18:42:27 +02:00
|
|
|
// runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay
|
|
|
|
type OverridableRuntimeResourceOverlayProperties struct {
|
|
|
|
// the package name of this app. The package name in the manifest file is used if one was not given.
|
|
|
|
Package_name *string
|
|
|
|
|
|
|
|
// the target package name of this overlay app. The target package name in the manifest file is used if one was not given.
|
|
|
|
Target_package_name *string
|
|
|
|
}
|
|
|
|
|
2015-05-11 22:39:40 +02:00
|
|
|
type AndroidApp struct {
|
2018-03-28 23:58:31 +02:00
|
|
|
Library
|
|
|
|
aapt
|
2019-03-01 00:35:54 +01:00
|
|
|
android.OverridableModuleBase
|
2015-05-11 22:39:40 +02:00
|
|
|
|
2019-05-16 21:28:22 +02:00
|
|
|
usesLibrary usesLibrary
|
|
|
|
|
2018-10-30 13:20:05 +01:00
|
|
|
certificate Certificate
|
2015-04-13 22:58:27 +02:00
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
appProperties appProperties
|
2018-05-22 20:11:52 +02:00
|
|
|
|
2019-03-01 00:35:54 +01:00
|
|
|
overridableAppProperties overridableAppProperties
|
|
|
|
|
2020-03-26 22:01:48 +01:00
|
|
|
installJniLibs []jniLib
|
|
|
|
jniCoverageOutputs android.Paths
|
2018-10-30 07:14:58 +01:00
|
|
|
|
|
|
|
bundleFile android.Path
|
2019-01-24 01:27:47 +01:00
|
|
|
|
|
|
|
// the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
|
|
|
|
installApkName string
|
2019-02-28 01:26:28 +01:00
|
|
|
|
2019-10-02 07:05:35 +02:00
|
|
|
installDir android.InstallPath
|
2019-09-11 19:25:18 +02:00
|
|
|
|
2019-09-28 02:13:15 +02:00
|
|
|
onDeviceDir string
|
|
|
|
|
2019-02-28 01:26:28 +01:00
|
|
|
additionalAaptFlags []string
|
2019-07-02 02:15:13 +02:00
|
|
|
|
|
|
|
noticeOutputs android.NoticeOutputs
|
2020-02-28 08:51:07 +01:00
|
|
|
|
|
|
|
overriddenManifestPackageName string
|
2020-04-27 20:05:28 +02:00
|
|
|
|
|
|
|
android.ApexBundleDepsInfo
|
2017-12-14 20:22:55 +01:00
|
|
|
}
|
|
|
|
|
2020-01-31 18:10:36 +01:00
|
|
|
func (a *AndroidApp) IsInstallable() bool {
|
|
|
|
return Bool(a.properties.Installable)
|
|
|
|
}
|
|
|
|
|
2018-05-01 00:55:11 +02:00
|
|
|
func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-05-02 21:58:28 +02:00
|
|
|
func (a *AndroidApp) ExportedStaticPackages() android.Paths {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-08-27 06:55:42 +02:00
|
|
|
func (a *AndroidApp) OutputFile() android.Path {
|
|
|
|
return a.outputFile
|
|
|
|
}
|
|
|
|
|
2020-01-28 23:00:53 +01:00
|
|
|
func (a *AndroidApp) Certificate() Certificate {
|
|
|
|
return a.certificate
|
|
|
|
}
|
|
|
|
|
2020-03-26 22:01:48 +01:00
|
|
|
func (a *AndroidApp) JniCoverageOutputs() android.Paths {
|
|
|
|
return a.jniCoverageOutputs
|
|
|
|
}
|
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
var _ AndroidLibraryDependency = (*AndroidApp)(nil)
|
|
|
|
|
2018-10-30 13:20:05 +01:00
|
|
|
type Certificate struct {
|
2020-01-28 23:00:53 +01:00
|
|
|
Pem, Key android.Path
|
|
|
|
presigned bool
|
|
|
|
}
|
|
|
|
|
|
|
|
var presignedCertificate = Certificate{presigned: true}
|
|
|
|
|
|
|
|
func (c Certificate) AndroidMkString() string {
|
|
|
|
if c.presigned {
|
|
|
|
return "PRESIGNED"
|
|
|
|
} else {
|
|
|
|
return c.Pem.String()
|
|
|
|
}
|
2015-04-13 22:58:27 +02:00
|
|
|
}
|
|
|
|
|
2017-06-23 01:51:17 +02:00
|
|
|
func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
|
|
a.Module.deps(ctx)
|
2018-10-03 07:03:40 +02:00
|
|
|
|
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
|
|
|
if String(a.appProperties.Stl) == "c++_shared" && !a.sdkVersion().specified() {
|
2019-05-07 00:48:44 +02:00
|
|
|
ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
|
|
|
|
}
|
|
|
|
|
2019-06-07 11:44:37 +02:00
|
|
|
sdkDep := decodeSdkDep(ctx, sdkContext(a))
|
|
|
|
if sdkDep.hasFrameworkLibs() {
|
|
|
|
a.aapt.deps(ctx, sdkDep)
|
2015-04-13 22:58:27 +02:00
|
|
|
}
|
2018-10-03 07:03:40 +02:00
|
|
|
|
2020-05-08 20:20:24 +02:00
|
|
|
usesSDK := a.sdkVersion().specified() && a.sdkVersion().kind != sdkCorePlatform
|
|
|
|
|
|
|
|
if usesSDK && Bool(a.appProperties.Jni_uses_sdk_apis) {
|
|
|
|
ctx.PropertyErrorf("jni_uses_sdk_apis",
|
|
|
|
"can only be set for modules that do not set sdk_version")
|
|
|
|
} else if !usesSDK && Bool(a.appProperties.Jni_uses_platform_apis) {
|
|
|
|
ctx.PropertyErrorf("jni_uses_platform_apis",
|
|
|
|
"can only be set for modules that set sdk_version")
|
|
|
|
}
|
|
|
|
|
2019-12-18 01:46:18 +01:00
|
|
|
tag := &jniDependencyTag{}
|
2018-10-03 07:03:40 +02:00
|
|
|
for _, jniTarget := range ctx.MultiTargets() {
|
2019-10-16 20:03:10 +02:00
|
|
|
variation := append(jniTarget.Variations(),
|
|
|
|
blueprint.Variation{Mutator: "link", Variation: "shared"})
|
2020-04-07 18:50:32 +02:00
|
|
|
|
|
|
|
// If the app builds against an Android SDK use the SDK variant of JNI dependencies
|
|
|
|
// unless jni_uses_platform_apis is set.
|
2020-05-13 20:05:02 +02:00
|
|
|
// Don't require the SDK variant for apps that are shipped on vendor, etc., as they already
|
|
|
|
// have stable APIs through the VNDK.
|
|
|
|
if (usesSDK && !a.RequiresStableAPIs(ctx) &&
|
|
|
|
!Bool(a.appProperties.Jni_uses_platform_apis)) ||
|
2020-05-07 02:51:39 +02:00
|
|
|
Bool(a.appProperties.Jni_uses_sdk_apis) {
|
2020-04-07 18:50:32 +02:00
|
|
|
variation = append(variation, blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
|
|
|
|
}
|
2018-10-03 07:03:40 +02:00
|
|
|
ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...)
|
|
|
|
}
|
2019-05-16 21:28:22 +02:00
|
|
|
|
2019-06-07 11:44:37 +02:00
|
|
|
a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
|
2019-05-11 00:16:29 +02:00
|
|
|
}
|
2018-10-05 00:21:03 +02:00
|
|
|
|
2019-05-11 00:16:29 +02:00
|
|
|
func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
|
2019-01-18 23:27:16 +01:00
|
|
|
cert := android.SrcIsModule(a.getCertString(ctx))
|
2018-10-05 00:21:03 +02:00
|
|
|
if cert != "" {
|
|
|
|
ctx.AddDependency(ctx.Module(), certificateTag, cert)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, cert := range a.appProperties.Additional_certificates {
|
|
|
|
cert = android.SrcIsModule(cert)
|
|
|
|
if cert != "" {
|
|
|
|
ctx.AddDependency(ctx.Module(), certificateTag, cert)
|
|
|
|
} else {
|
|
|
|
ctx.PropertyErrorf("additional_certificates",
|
|
|
|
`must be names of android_app_certificate modules in the form ":module"`)
|
|
|
|
}
|
|
|
|
}
|
2015-04-13 22:58:27 +02:00
|
|
|
}
|
|
|
|
|
2019-07-11 08:54:27 +02:00
|
|
|
func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
|
|
a.generateAndroidBuildActions(ctx)
|
|
|
|
}
|
|
|
|
|
2017-06-23 01:51:17 +02:00
|
|
|
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
2020-04-08 20:09:30 +02:00
|
|
|
a.checkAppSdkVersions(ctx)
|
2018-05-22 20:11:52 +02:00
|
|
|
a.generateAndroidBuildActions(ctx)
|
|
|
|
}
|
|
|
|
|
2020-04-08 20:09:30 +02:00
|
|
|
func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
|
2020-04-29 07:01:06 +02:00
|
|
|
if Bool(a.appProperties.Updatable) || a.ApexModuleBase.Updatable() {
|
2020-04-08 20:09:30 +02:00
|
|
|
if !a.sdkVersion().stable() {
|
|
|
|
ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.sdkVersion())
|
|
|
|
}
|
2020-04-16 14:43:02 +02:00
|
|
|
if String(a.deviceProperties.Min_sdk_version) == "" {
|
|
|
|
ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
|
|
|
|
}
|
2020-04-29 07:01:06 +02:00
|
|
|
if minSdkVersion, err := a.minSdkVersion().effectiveVersion(ctx); err == nil {
|
|
|
|
a.checkJniLibsSdkVersion(ctx, minSdkVersion)
|
|
|
|
} else {
|
|
|
|
ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
|
|
|
|
}
|
2020-04-08 20:09:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
a.checkPlatformAPI(ctx)
|
|
|
|
a.checkSdkVersions(ctx)
|
|
|
|
}
|
|
|
|
|
2020-04-29 07:01:06 +02:00
|
|
|
// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it.
|
|
|
|
// This check is enforced for "updatable" APKs (including APK-in-APEX).
|
|
|
|
// b/155209650: until min_sdk_version is properly supported, use sdk_version instead.
|
|
|
|
// because, sdk_version is overridden by min_sdk_version (if set as smaller)
|
|
|
|
// and linkType is checked with dependencies so we can be sure that the whole dependency tree
|
|
|
|
// will meet the requirements.
|
|
|
|
func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion sdkVersion) {
|
|
|
|
// It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
|
|
|
|
ctx.VisitDirectDeps(func(m android.Module) {
|
|
|
|
if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
dep, _ := m.(*cc.Module)
|
|
|
|
jniSdkVersion, err := android.ApiStrToNum(ctx, dep.SdkVersion())
|
|
|
|
if err != nil || int(minSdkVersion) < jniSdkVersion {
|
|
|
|
ctx.OtherModuleErrorf(dep, "sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
|
|
|
|
dep.SdkVersion(), minSdkVersion, ctx.ModuleName())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-05-01 22:16:22 +02:00
|
|
|
// Returns true if the native libraries should be stored in the APK uncompressed and the
|
2019-02-06 06:55:21 +01:00
|
|
|
// extractNativeLibs application flag should be set to false in the manifest.
|
2019-05-01 22:16:22 +02:00
|
|
|
func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
|
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
|
|
|
minSdkVersion, err := a.minSdkVersion().effectiveVersion(ctx)
|
2019-02-06 06:55:21 +01:00
|
|
|
if err != nil {
|
|
|
|
ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.minSdkVersion(), err)
|
|
|
|
}
|
|
|
|
|
2019-11-11 02:14:32 +01:00
|
|
|
return (minSdkVersion >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
|
|
|
|
!a.IsForPlatform()
|
2019-02-06 06:55:21 +01:00
|
|
|
}
|
|
|
|
|
2018-11-12 19:13:39 +01:00
|
|
|
// Returns whether this module should have the dex file stored uncompressed in the APK.
|
|
|
|
func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
|
2019-02-07 22:07:08 +01:00
|
|
|
if Bool(a.appProperties.Use_embedded_dex) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-06-25 22:35:30 +02:00
|
|
|
// Uncompress dex in APKs of privileged apps (even for unbundled builds, they may
|
|
|
|
// be preinstalled as prebuilts).
|
2019-10-17 05:54:30 +02:00
|
|
|
if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
|
2019-02-12 14:12:16 +01:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-06-25 22:35:30 +02:00
|
|
|
if ctx.Config().UnbundledBuild() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2019-05-02 23:55:29 +02:00
|
|
|
return shouldUncompressDex(ctx, &a.dexpreopter)
|
2018-10-05 23:20:06 +02:00
|
|
|
}
|
|
|
|
|
2019-05-07 00:48:44 +02:00
|
|
|
func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
|
|
|
|
return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
|
2019-11-11 02:14:32 +01:00
|
|
|
!a.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs
|
2019-05-07 00:48:44 +02:00
|
|
|
}
|
|
|
|
|
2020-02-28 08:51:07 +01:00
|
|
|
func (a *AndroidApp) OverriddenManifestPackageName() string {
|
|
|
|
return a.overriddenManifestPackageName
|
|
|
|
}
|
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
|
2019-02-18 19:24:16 +01:00
|
|
|
a.aapt.usesNonSdkApis = Bool(a.Module.deviceProperties.Platform_apis)
|
|
|
|
|
2019-05-31 00:51:14 +02:00
|
|
|
// Ask manifest_fixer to add or update the application element indicating this app has no code.
|
|
|
|
a.aapt.hasNoCode = !a.hasCode(ctx)
|
|
|
|
|
2019-01-22 20:19:56 +01:00
|
|
|
aaptLinkFlags := []string{}
|
2015-04-13 22:58:27 +02:00
|
|
|
|
2019-01-22 20:19:56 +01:00
|
|
|
// Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided.
|
2020-02-11 16:54:35 +01:00
|
|
|
hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
|
2018-04-20 00:25:19 +02:00
|
|
|
if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 {
|
2019-01-22 20:19:56 +01:00
|
|
|
aaptLinkFlags = append(aaptLinkFlags, "--product", ctx.Config().ProductAAPTCharacteristics())
|
2018-04-20 00:25:19 +02:00
|
|
|
}
|
|
|
|
|
2018-10-25 05:24:57 +02:00
|
|
|
if !Bool(a.aaptProperties.Aapt_include_all_resources) {
|
|
|
|
// Product AAPT config
|
|
|
|
for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
|
2019-01-22 20:19:56 +01:00
|
|
|
aaptLinkFlags = append(aaptLinkFlags, "-c", aaptConfig)
|
2018-10-25 05:24:57 +02:00
|
|
|
}
|
2018-04-20 00:25:19 +02:00
|
|
|
|
2018-10-25 05:24:57 +02:00
|
|
|
// Product AAPT preferred config
|
|
|
|
if len(ctx.Config().ProductAAPTPreferredConfig()) > 0 {
|
2019-01-22 20:19:56 +01:00
|
|
|
aaptLinkFlags = append(aaptLinkFlags, "--preferred-density", ctx.Config().ProductAAPTPreferredConfig())
|
2018-10-25 05:24:57 +02:00
|
|
|
}
|
2018-04-20 00:25:19 +02:00
|
|
|
}
|
|
|
|
|
2019-01-05 04:57:48 +01:00
|
|
|
manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
|
2019-03-13 18:13:24 +01:00
|
|
|
if overridden || a.overridableAppProperties.Package_name != nil {
|
|
|
|
// The product override variable has a priority over the package_name property.
|
|
|
|
if !overridden {
|
|
|
|
manifestPackageName = *a.overridableAppProperties.Package_name
|
|
|
|
}
|
2019-01-22 20:19:56 +01:00
|
|
|
aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName)
|
2020-02-28 08:51:07 +01:00
|
|
|
a.overriddenManifestPackageName = manifestPackageName
|
2019-01-05 04:57:48 +01:00
|
|
|
}
|
|
|
|
|
2019-02-28 01:26:28 +01:00
|
|
|
aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
|
|
|
|
|
2019-03-20 00:03:11 +01:00
|
|
|
a.aapt.splitNames = a.appProperties.Package_splits
|
2019-05-16 21:28:22 +02:00
|
|
|
a.aapt.sdkLibraries = a.exportedSdkLibs
|
2020-02-12 02:27:19 +01:00
|
|
|
a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
|
2019-01-22 20:19:56 +01:00
|
|
|
a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...)
|
2017-11-23 01:19:37 +01:00
|
|
|
|
2017-06-23 01:51:17 +02:00
|
|
|
// apps manifests are handled by aapt, don't let Module see them
|
2015-09-24 00:26:20 +02:00
|
|
|
a.properties.Manifest = nil
|
2019-01-23 01:40:58 +01:00
|
|
|
}
|
2015-04-13 22:58:27 +02:00
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
|
2018-05-01 00:55:11 +02:00
|
|
|
var staticLibProguardFlagFiles android.Paths
|
|
|
|
ctx.VisitDirectDeps(func(m android.Module) {
|
|
|
|
if lib, ok := m.(AndroidLibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
|
|
|
|
staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
|
|
|
|
|
|
|
|
a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, staticLibProguardFlagFiles...)
|
|
|
|
a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile)
|
2019-01-23 01:40:58 +01:00
|
|
|
}
|
2017-12-28 21:23:20 +01:00
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
|
2018-11-12 19:13:39 +01:00
|
|
|
|
|
|
|
var installDir string
|
|
|
|
if ctx.ModuleName() == "framework-res" {
|
|
|
|
// framework-res.apk is installed as system/framework/framework-res.apk
|
|
|
|
installDir = "framework"
|
2019-10-17 05:54:30 +02:00
|
|
|
} else if a.Privileged() {
|
2019-01-24 01:27:47 +01:00
|
|
|
installDir = filepath.Join("priv-app", a.installApkName)
|
2018-11-12 19:13:39 +01:00
|
|
|
} else {
|
2019-01-24 01:27:47 +01:00
|
|
|
installDir = filepath.Join("app", a.installApkName)
|
2018-11-12 19:13:39 +01:00
|
|
|
}
|
2019-01-24 01:27:47 +01:00
|
|
|
a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
|
2019-02-12 14:12:16 +01:00
|
|
|
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
|
2019-05-16 21:28:22 +02:00
|
|
|
|
|
|
|
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
|
|
|
|
a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs
|
|
|
|
a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx)
|
|
|
|
a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx)
|
|
|
|
a.dexpreopter.manifestFile = a.mergedManifestFile
|
|
|
|
|
2019-02-12 14:12:16 +01:00
|
|
|
a.deviceProperties.UncompressDex = a.dexpreopter.uncompressedDex
|
2018-10-05 23:20:06 +02:00
|
|
|
|
2017-11-23 01:20:45 +01:00
|
|
|
if ctx.ModuleName() != "framework-res" {
|
|
|
|
a.Module.compile(ctx, a.aaptSrcJar)
|
|
|
|
}
|
2015-04-13 22:58:27 +02:00
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
return a.maybeStrippedDexJarFile
|
|
|
|
}
|
2018-10-05 00:21:03 +02:00
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, ctx android.ModuleContext) android.WritablePath {
|
2018-10-03 07:03:40 +02:00
|
|
|
var jniJarFile android.WritablePath
|
|
|
|
if len(jniLibs) > 0 {
|
2019-05-07 00:48:44 +02:00
|
|
|
if a.shouldEmbedJnis(ctx) {
|
2018-10-03 07:03:40 +02:00
|
|
|
jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
|
2019-05-01 22:16:22 +02:00
|
|
|
TransformJniLibsToJar(ctx, jniJarFile, jniLibs, a.useEmbeddedNativeLibs(ctx))
|
2020-03-26 22:01:48 +01:00
|
|
|
for _, jni := range jniLibs {
|
|
|
|
if jni.coverageFile.Valid() {
|
2020-04-07 22:07:55 +02:00
|
|
|
// Only collect coverage for the first target arch if this is a multilib target.
|
|
|
|
// TODO(jungjw): Ideally, we want to collect both reports, but that would cause coverage
|
|
|
|
// data file path collisions since the current coverage file path format doesn't contain
|
|
|
|
// arch-related strings. This is fine for now though; the code coverage team doesn't use
|
|
|
|
// multi-arch targets such as test_suite_* for coverage collections yet.
|
|
|
|
//
|
|
|
|
// Work with the team to come up with a new format that handles multilib modules properly
|
|
|
|
// and change this.
|
|
|
|
if len(ctx.Config().Targets[android.Android]) == 1 ||
|
|
|
|
ctx.Config().Targets[android.Android][0].Arch.ArchType == jni.target.Arch.ArchType {
|
|
|
|
a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
|
|
|
|
}
|
2020-03-26 22:01:48 +01:00
|
|
|
}
|
|
|
|
}
|
2018-10-03 07:03:40 +02:00
|
|
|
} else {
|
|
|
|
a.installJniLibs = jniLibs
|
|
|
|
}
|
|
|
|
}
|
2019-01-23 01:40:58 +01:00
|
|
|
return jniJarFile
|
|
|
|
}
|
2018-10-03 07:03:40 +02:00
|
|
|
|
2019-09-11 19:25:18 +02:00
|
|
|
func (a *AndroidApp) noticeBuildActions(ctx android.ModuleContext) {
|
2019-06-18 02:40:56 +02:00
|
|
|
// Collect NOTICE files from all dependencies.
|
|
|
|
seenModules := make(map[android.Module]bool)
|
|
|
|
noticePathSet := make(map[android.Path]bool)
|
|
|
|
|
|
|
|
ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
|
|
|
|
// Have we already seen this?
|
|
|
|
if _, ok := seenModules[child]; ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
seenModules[child] = true
|
|
|
|
|
|
|
|
// Skip host modules.
|
|
|
|
if child.Target().Os.Class == android.Host || child.Target().Os.Class == android.HostCross {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-02-19 05:21:55 +01:00
|
|
|
paths := child.(android.Module).NoticeFiles()
|
|
|
|
if len(paths) > 0 {
|
|
|
|
for _, path := range paths {
|
|
|
|
noticePathSet[path] = true
|
|
|
|
}
|
2019-06-18 02:40:56 +02:00
|
|
|
}
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
|
|
|
|
// If the app has one, add it too.
|
2020-02-19 05:21:55 +01:00
|
|
|
if len(a.NoticeFiles()) > 0 {
|
|
|
|
for _, path := range a.NoticeFiles() {
|
|
|
|
noticePathSet[path] = true
|
|
|
|
}
|
2019-06-18 02:40:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if len(noticePathSet) == 0 {
|
2019-07-02 02:15:13 +02:00
|
|
|
return
|
2019-06-18 02:40:56 +02:00
|
|
|
}
|
|
|
|
var noticePaths []android.Path
|
|
|
|
for path := range noticePathSet {
|
|
|
|
noticePaths = append(noticePaths, path)
|
|
|
|
}
|
|
|
|
sort.Slice(noticePaths, func(i, j int) bool {
|
|
|
|
return noticePaths[i].String() < noticePaths[j].String()
|
|
|
|
})
|
|
|
|
|
2019-09-11 19:25:18 +02:00
|
|
|
a.noticeOutputs = android.BuildNoticeOutput(ctx, a.installDir, a.installApkName+".apk", noticePaths)
|
2019-06-18 02:40:56 +02:00
|
|
|
}
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
// Reads and prepends a main cert from the default cert dir if it hasn't been set already, i.e. it
|
|
|
|
// isn't a cert module reference. Also checks and enforces system cert restriction if applicable.
|
|
|
|
func processMainCert(m android.ModuleBase, certPropValue string, certificates []Certificate, ctx android.ModuleContext) []Certificate {
|
|
|
|
if android.SrcIsModule(certPropValue) == "" {
|
|
|
|
var mainCert Certificate
|
|
|
|
if certPropValue != "" {
|
|
|
|
defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
|
|
|
|
mainCert = Certificate{
|
2020-01-28 23:00:53 +01:00
|
|
|
Pem: defaultDir.Join(ctx, certPropValue+".x509.pem"),
|
|
|
|
Key: defaultDir.Join(ctx, certPropValue+".pk8"),
|
2019-04-15 18:48:31 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pem, key := ctx.Config().DefaultAppCertificate(ctx)
|
2020-01-28 23:00:53 +01:00
|
|
|
mainCert = Certificate{
|
|
|
|
Pem: pem,
|
|
|
|
Key: key,
|
|
|
|
}
|
2018-10-05 00:21:03 +02:00
|
|
|
}
|
2019-04-15 18:48:31 +02:00
|
|
|
certificates = append([]Certificate{mainCert}, certificates...)
|
2018-10-05 00:21:03 +02:00
|
|
|
}
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
if !m.Platform() {
|
|
|
|
certPath := certificates[0].Pem.String()
|
2019-01-07 04:07:27 +01:00
|
|
|
systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
|
|
|
|
if strings.HasPrefix(certPath, systemCertPath) {
|
|
|
|
enforceSystemCert := ctx.Config().EnforceSystemCertificate()
|
|
|
|
whitelist := ctx.Config().EnforceSystemCertificateWhitelist()
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
if enforceSystemCert && !inList(m.Name(), whitelist) {
|
2019-01-07 04:07:27 +01:00
|
|
|
ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
return certificates
|
2019-01-23 01:40:58 +01:00
|
|
|
}
|
|
|
|
|
2020-03-23 12:21:11 +01:00
|
|
|
func (a *AndroidApp) InstallApkName() string {
|
|
|
|
return a.installApkName
|
|
|
|
}
|
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
2019-05-16 21:28:22 +02:00
|
|
|
var apkDeps android.Paths
|
|
|
|
|
2019-07-11 08:54:27 +02:00
|
|
|
a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
|
|
|
|
a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
|
|
|
|
|
2019-01-24 01:27:47 +01:00
|
|
|
// Check if the install APK name needs to be overridden.
|
2019-03-01 00:35:54 +01:00
|
|
|
a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Name())
|
2019-01-24 01:27:47 +01:00
|
|
|
|
2019-06-18 02:40:56 +02:00
|
|
|
if ctx.ModuleName() == "framework-res" {
|
|
|
|
// framework-res.apk is installed as system/framework/framework-res.apk
|
2019-09-11 19:25:18 +02:00
|
|
|
a.installDir = android.PathForModuleInstall(ctx, "framework")
|
2019-10-17 05:54:30 +02:00
|
|
|
} else if a.Privileged() {
|
2019-09-11 19:25:18 +02:00
|
|
|
a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
|
|
|
|
} else if ctx.InstallInTestcases() {
|
2019-11-21 19:41:00 +01:00
|
|
|
a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch())
|
2019-06-18 02:40:56 +02:00
|
|
|
} else {
|
2019-09-11 19:25:18 +02:00
|
|
|
a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
|
2019-06-18 02:40:56 +02:00
|
|
|
}
|
2019-09-28 02:13:15 +02:00
|
|
|
a.onDeviceDir = android.InstallPathToOnDevicePath(ctx, a.installDir)
|
2019-06-18 02:40:56 +02:00
|
|
|
|
2019-09-11 19:25:18 +02:00
|
|
|
a.noticeBuildActions(ctx)
|
2019-07-02 02:15:13 +02:00
|
|
|
if Bool(a.appProperties.Embed_notices) || ctx.Config().IsEnvTrue("ALWAYS_EMBED_NOTICES") {
|
|
|
|
a.aapt.noticeFile = a.noticeOutputs.HtmlGzOutput
|
|
|
|
}
|
2019-06-18 02:40:56 +02:00
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
// Process all building blocks, from AAPT to certificates.
|
|
|
|
a.aaptBuildActions(ctx)
|
|
|
|
|
2019-05-16 21:28:22 +02:00
|
|
|
if a.usesLibrary.enforceUsesLibraries() {
|
|
|
|
manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile)
|
|
|
|
apkDeps = append(apkDeps, manifestCheckFile)
|
|
|
|
}
|
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
a.proguardBuildActions(ctx)
|
|
|
|
|
|
|
|
dexJarFile := a.dexBuildActions(ctx)
|
|
|
|
|
2020-05-13 20:05:02 +02:00
|
|
|
jniLibs, certificateDeps := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
|
2019-01-23 01:40:58 +01:00
|
|
|
jniJarFile := a.jniBuildActions(jniLibs, ctx)
|
|
|
|
|
|
|
|
if ctx.Failed() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
certificates := processMainCert(a.ModuleBase, a.getCertString(ctx), certificateDeps, ctx)
|
|
|
|
a.certificate = certificates[0]
|
2019-01-23 01:40:58 +01:00
|
|
|
|
|
|
|
// Build a final signed app package.
|
2019-11-07 23:14:38 +01:00
|
|
|
packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
|
2020-05-07 22:24:05 +02:00
|
|
|
var lineageFile android.Path
|
|
|
|
if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
|
|
|
|
lineageFile = android.PathForModuleSrc(ctx, lineage)
|
|
|
|
}
|
|
|
|
CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, lineageFile)
|
2017-11-23 01:19:37 +01:00
|
|
|
a.outputFile = packageFile
|
|
|
|
|
2019-03-20 00:03:11 +01:00
|
|
|
for _, split := range a.aapt.splits {
|
|
|
|
// Sign the split APKs
|
2019-11-07 23:14:38 +01:00
|
|
|
packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
|
2020-05-07 22:24:05 +02:00
|
|
|
CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, lineageFile)
|
2019-03-20 00:03:11 +01:00
|
|
|
a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
|
|
|
|
}
|
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
// Build an app bundle.
|
2018-10-30 07:14:58 +01:00
|
|
|
bundleFile := android.PathForModuleOut(ctx, "base.zip")
|
|
|
|
BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
|
|
|
|
a.bundleFile = bundleFile
|
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
// Install the app package.
|
2019-11-13 07:01:01 +01:00
|
|
|
if (Bool(a.Module.properties.Installable) || ctx.Host()) && a.IsForPlatform() {
|
|
|
|
ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile)
|
|
|
|
for _, extra := range a.extraOutputFiles {
|
|
|
|
ctx.InstallFile(a.installDir, extra.Base(), extra)
|
|
|
|
}
|
2017-11-23 01:20:45 +01:00
|
|
|
}
|
2020-04-27 20:05:28 +02:00
|
|
|
|
|
|
|
a.buildAppDependencyInfo(ctx)
|
2015-04-13 22:58:27 +02:00
|
|
|
}
|
|
|
|
|
2020-05-13 20:05:02 +02:00
|
|
|
type appDepsInterface interface {
|
|
|
|
sdkVersion() sdkSpec
|
|
|
|
minSdkVersion() sdkSpec
|
|
|
|
RequiresStableAPIs(ctx android.BaseModuleContext) bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
|
|
|
|
shouldCollectRecursiveNativeDeps bool,
|
2020-02-15 19:38:00 +01:00
|
|
|
checkNativeSdkVersion bool) ([]jniLib, []Certificate) {
|
2020-05-13 20:05:02 +02:00
|
|
|
|
2018-10-03 07:03:40 +02:00
|
|
|
var jniLibs []jniLib
|
2018-10-30 13:20:05 +01:00
|
|
|
var certificates []Certificate
|
2019-12-18 01:46:18 +01:00
|
|
|
seenModulePaths := make(map[string]bool)
|
2018-10-03 07:03:40 +02:00
|
|
|
|
2020-05-13 20:05:02 +02:00
|
|
|
if checkNativeSdkVersion {
|
|
|
|
checkNativeSdkVersion = app.sdkVersion().specified() &&
|
|
|
|
app.sdkVersion().kind != sdkCorePlatform && !app.RequiresStableAPIs(ctx)
|
|
|
|
}
|
|
|
|
|
2019-12-18 01:46:18 +01:00
|
|
|
ctx.WalkDeps(func(module android.Module, parent android.Module) bool {
|
2018-10-03 07:03:40 +02:00
|
|
|
otherName := ctx.OtherModuleName(module)
|
|
|
|
tag := ctx.OtherModuleDependencyTag(module)
|
|
|
|
|
2019-12-18 01:46:18 +01:00
|
|
|
if IsJniDepTag(tag) || tag == cc.SharedDepTag {
|
2018-10-03 07:03:40 +02:00
|
|
|
if dep, ok := module.(*cc.Module); ok {
|
2019-12-18 01:46:18 +01:00
|
|
|
if dep.IsNdk() || dep.IsStubs() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-10-03 07:03:40 +02:00
|
|
|
lib := dep.OutputFile()
|
2019-12-18 01:46:18 +01:00
|
|
|
path := lib.Path()
|
|
|
|
if seenModulePaths[path.String()] {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
seenModulePaths[path.String()] = true
|
|
|
|
|
2020-05-13 20:05:02 +02:00
|
|
|
if checkNativeSdkVersion && dep.SdkVersion() == "" {
|
|
|
|
ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
|
|
|
|
otherName)
|
2020-02-15 19:38:00 +01:00
|
|
|
}
|
|
|
|
|
2018-10-03 07:03:40 +02:00
|
|
|
if lib.Valid() {
|
|
|
|
jniLibs = append(jniLibs, jniLib{
|
2020-03-26 22:01:48 +01:00
|
|
|
name: ctx.OtherModuleName(module),
|
|
|
|
path: path,
|
|
|
|
target: module.Target(),
|
|
|
|
coverageFile: dep.CoverageOutputFile(),
|
2018-10-03 07:03:40 +02:00
|
|
|
})
|
|
|
|
} else {
|
|
|
|
ctx.ModuleErrorf("dependency %q missing output file", otherName)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ctx.ModuleErrorf("jni_libs dependency %q must be a cc library", otherName)
|
|
|
|
}
|
2019-12-18 01:46:18 +01:00
|
|
|
|
|
|
|
return shouldCollectRecursiveNativeDeps
|
|
|
|
}
|
|
|
|
|
|
|
|
if tag == certificateTag {
|
2018-10-05 00:21:03 +02:00
|
|
|
if dep, ok := module.(*AndroidAppCertificate); ok {
|
2018-10-30 13:20:05 +01:00
|
|
|
certificates = append(certificates, dep.Certificate)
|
2018-10-05 00:21:03 +02:00
|
|
|
} else {
|
|
|
|
ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName)
|
|
|
|
}
|
2018-10-03 07:03:40 +02:00
|
|
|
}
|
2019-12-18 01:46:18 +01:00
|
|
|
|
|
|
|
return false
|
2018-10-03 07:03:40 +02:00
|
|
|
})
|
|
|
|
|
2018-10-05 00:21:03 +02:00
|
|
|
return jniLibs, certificates
|
2018-10-03 07:03:40 +02:00
|
|
|
}
|
|
|
|
|
2020-04-27 20:05:28 +02:00
|
|
|
func (a *AndroidApp) walkPayloadDeps(ctx android.ModuleContext,
|
|
|
|
do func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool)) {
|
|
|
|
|
|
|
|
ctx.WalkDeps(func(child, parent android.Module) bool {
|
|
|
|
isExternal := !a.DepIsInSameApex(ctx, child)
|
|
|
|
if am, ok := child.(android.ApexModule); ok {
|
|
|
|
do(ctx, parent, am, isExternal)
|
|
|
|
}
|
|
|
|
return !isExternal
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
|
|
|
|
if ctx.Host() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
depsInfo := android.DepNameToDepInfoMap{}
|
|
|
|
a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) {
|
|
|
|
depName := to.Name()
|
|
|
|
if info, exist := depsInfo[depName]; exist {
|
|
|
|
info.From = append(info.From, from.Name())
|
|
|
|
info.IsExternal = info.IsExternal && externalDep
|
|
|
|
depsInfo[depName] = info
|
|
|
|
} else {
|
|
|
|
toMinSdkVersion := "(no version)"
|
|
|
|
if m, ok := to.(interface{ MinSdkVersion() string }); ok {
|
|
|
|
if v := m.MinSdkVersion(); v != "" {
|
|
|
|
toMinSdkVersion = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
depsInfo[depName] = android.ApexModuleDepInfo{
|
|
|
|
To: depName,
|
|
|
|
From: []string{from.Name()},
|
|
|
|
IsExternal: externalDep,
|
|
|
|
MinSdkVersion: toMinSdkVersion,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(), depsInfo)
|
|
|
|
}
|
|
|
|
|
2019-06-06 23:33:29 +02:00
|
|
|
func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string {
|
2019-01-18 23:27:16 +01:00
|
|
|
certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
|
|
|
|
if overridden {
|
2019-02-28 17:22:30 +01:00
|
|
|
return ":" + certificate
|
2019-01-18 23:27:16 +01:00
|
|
|
}
|
2019-03-01 00:35:54 +01:00
|
|
|
return String(a.overridableAppProperties.Certificate)
|
2019-01-18 23:27:16 +01:00
|
|
|
}
|
|
|
|
|
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
|
|
|
func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
|
|
|
|
if IsJniDepTag(ctx.OtherModuleDependencyTag(dep)) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return a.Library.DepIsInSameApex(ctx, dep)
|
|
|
|
}
|
|
|
|
|
2019-08-19 07:56:02 +02:00
|
|
|
// For OutputFileProducer interface
|
|
|
|
func (a *AndroidApp) OutputFiles(tag string) (android.Paths, error) {
|
|
|
|
switch tag {
|
|
|
|
case ".aapt.srcjar":
|
|
|
|
return []android.Path{a.aaptSrcJar}, nil
|
|
|
|
}
|
|
|
|
return a.Library.OutputFiles(tag)
|
|
|
|
}
|
|
|
|
|
2019-10-17 05:54:30 +02:00
|
|
|
func (a *AndroidApp) Privileged() bool {
|
|
|
|
return Bool(a.appProperties.Privileged)
|
|
|
|
}
|
|
|
|
|
2020-03-26 22:01:48 +01:00
|
|
|
func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
|
|
|
|
return ctx.Device() && (ctx.DeviceConfig().NativeCoverageEnabled() || ctx.DeviceConfig().ClangCoverageEnabled())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidApp) PreventInstall() {
|
|
|
|
a.appProperties.PreventInstall = true
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidApp) HideFromMake() {
|
|
|
|
a.appProperties.HideFromMake = true
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
|
|
|
|
a.appProperties.IsCoverageVariant = coverage
|
|
|
|
}
|
|
|
|
|
2020-04-09 15:56:02 +02:00
|
|
|
func (a *AndroidApp) EnableCoverageIfNeeded() {}
|
|
|
|
|
2020-03-26 22:01:48 +01:00
|
|
|
var _ cc.Coverage = (*AndroidApp)(nil)
|
|
|
|
|
2019-02-12 23:41:32 +01:00
|
|
|
// android_app compiles sources and Android resources into an Android application package `.apk` file.
|
2017-06-24 00:06:31 +02:00
|
|
|
func AndroidAppFactory() android.Module {
|
2015-04-13 22:58:27 +02:00
|
|
|
module := &AndroidApp{}
|
|
|
|
|
2019-04-17 02:16:58 +02:00
|
|
|
module.Module.deviceProperties.Optimize.EnabledByDefault = true
|
2017-12-28 21:23:20 +01:00
|
|
|
module.Module.deviceProperties.Optimize.Shrink = proptools.BoolPtr(true)
|
|
|
|
|
2018-05-22 20:11:52 +02:00
|
|
|
module.Module.properties.Instrument = true
|
2018-06-27 02:59:05 +02:00
|
|
|
module.Module.properties.Installable = proptools.BoolPtr(true)
|
2018-05-22 20:11:52 +02:00
|
|
|
|
2017-06-24 00:06:31 +02:00
|
|
|
module.AddProperties(
|
2017-06-23 02:01:52 +02:00
|
|
|
&module.Module.properties,
|
|
|
|
&module.Module.deviceProperties,
|
2018-11-12 19:13:39 +01:00
|
|
|
&module.Module.dexpreoptProperties,
|
2018-03-28 23:58:31 +02:00
|
|
|
&module.Module.protoProperties,
|
|
|
|
&module.aaptProperties,
|
2019-03-01 00:35:54 +01:00
|
|
|
&module.appProperties,
|
2019-05-16 21:28:22 +02:00
|
|
|
&module.overridableAppProperties,
|
|
|
|
&module.usesLibrary.usesLibraryProperties)
|
2017-06-24 00:06:31 +02:00
|
|
|
|
2018-10-02 22:59:46 +02:00
|
|
|
module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
|
|
|
|
return class == android.Device && ctx.Config().DevicePrefer32BitApps()
|
|
|
|
})
|
|
|
|
|
2018-10-03 07:03:40 +02:00
|
|
|
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
|
|
|
android.InitDefaultableModule(module)
|
2019-03-01 00:35:54 +01:00
|
|
|
android.InitOverridableModule(module, &module.appProperties.Overrides)
|
2019-11-11 02:14:32 +01:00
|
|
|
android.InitApexModule(module)
|
2018-10-03 07:03:40 +02:00
|
|
|
|
2017-06-24 00:06:31 +02:00
|
|
|
return module
|
2015-04-13 22:58:27 +02:00
|
|
|
}
|
2018-05-22 20:11:52 +02:00
|
|
|
|
|
|
|
type appTestProperties struct {
|
2020-04-29 01:10:55 +02:00
|
|
|
// The name of the android_app module that the tests will run against.
|
2018-05-22 20:11:52 +02:00
|
|
|
Instrumentation_for *string
|
2019-06-06 17:45:58 +02:00
|
|
|
|
|
|
|
// if specified, the instrumentation target package name in the manifest is overwritten by it.
|
|
|
|
Instrumentation_target_package *string
|
2018-05-22 20:11:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type AndroidTest struct {
|
|
|
|
AndroidApp
|
|
|
|
|
|
|
|
appTestProperties appTestProperties
|
|
|
|
|
|
|
|
testProperties testProperties
|
2018-08-08 01:49:25 +02:00
|
|
|
|
|
|
|
testConfig android.Path
|
2018-08-11 01:06:24 +02:00
|
|
|
data android.Paths
|
2018-05-22 20:11:52 +02:00
|
|
|
}
|
|
|
|
|
2019-09-11 19:25:18 +02:00
|
|
|
func (a *AndroidTest) InstallInTestcases() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2018-05-22 20:11:52 +02:00
|
|
|
func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
2019-06-06 17:45:58 +02:00
|
|
|
if a.appTestProperties.Instrumentation_target_package != nil {
|
|
|
|
a.additionalAaptFlags = append(a.additionalAaptFlags,
|
|
|
|
"--rename-instrumentation-target-package "+*a.appTestProperties.Instrumentation_target_package)
|
|
|
|
} else if a.appTestProperties.Instrumentation_for != nil {
|
|
|
|
// Check if the instrumentation target package is overridden.
|
2019-02-28 01:26:28 +01:00
|
|
|
manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(*a.appTestProperties.Instrumentation_for)
|
|
|
|
if overridden {
|
|
|
|
a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
|
|
|
|
}
|
|
|
|
}
|
2018-05-22 20:11:52 +02:00
|
|
|
a.generateAndroidBuildActions(ctx)
|
2018-08-08 01:49:25 +02:00
|
|
|
|
2020-01-14 19:27:18 +01:00
|
|
|
testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
|
2019-09-26 20:41:36 +02:00
|
|
|
a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config)
|
2020-01-14 19:27:18 +01:00
|
|
|
a.testConfig = a.FixTestConfig(ctx, testConfig)
|
|
|
|
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
|
|
|
|
if testConfig == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
|
|
|
|
rule := android.NewRuleBuilder()
|
|
|
|
command := rule.Command().BuiltTool(ctx, "test_config_fixer").Input(testConfig).Output(fixedConfig)
|
|
|
|
fixNeeded := false
|
|
|
|
|
|
|
|
if ctx.ModuleName() != a.installApkName {
|
|
|
|
fixNeeded = true
|
|
|
|
command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
|
|
|
|
}
|
|
|
|
|
2019-11-22 23:34:55 +01:00
|
|
|
if a.overridableAppProperties.Package_name != nil {
|
2020-01-14 19:27:18 +01:00
|
|
|
fixNeeded = true
|
|
|
|
command.FlagWithInput("--manifest ", a.manifestPath).
|
|
|
|
FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name)
|
|
|
|
}
|
|
|
|
|
|
|
|
if fixNeeded {
|
2019-11-22 23:34:55 +01:00
|
|
|
rule.Build(pctx, ctx, "fix_test_config", "fix test config")
|
2020-01-14 19:27:18 +01:00
|
|
|
return fixedConfig
|
2019-11-22 23:34:55 +01:00
|
|
|
}
|
2020-01-14 19:27:18 +01:00
|
|
|
return testConfig
|
2018-08-08 01:49:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
|
|
a.AndroidApp.DepsMutator(ctx)
|
2019-06-06 17:45:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
|
|
|
|
a.AndroidApp.OverridablePropertiesDepsMutator(ctx)
|
2018-10-16 01:18:06 +02:00
|
|
|
if a.appTestProperties.Instrumentation_for != nil {
|
|
|
|
// The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac,
|
|
|
|
// but not added to the aapt2 link includes like a normal android_app or android_library dependency, so
|
|
|
|
// use instrumentationForTag instead of libTag.
|
|
|
|
ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for))
|
|
|
|
}
|
2018-05-22 20:11:52 +02:00
|
|
|
}
|
|
|
|
|
2019-02-12 23:41:32 +01:00
|
|
|
// android_test compiles test sources and Android resources into an Android application package `.apk` file and
|
|
|
|
// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
|
2018-05-22 20:11:52 +02:00
|
|
|
func AndroidTestFactory() android.Module {
|
|
|
|
module := &AndroidTest{}
|
|
|
|
|
2019-04-17 02:16:58 +02:00
|
|
|
module.Module.deviceProperties.Optimize.EnabledByDefault = true
|
2018-09-18 01:46:35 +02:00
|
|
|
|
|
|
|
module.Module.properties.Instrument = true
|
2018-06-27 02:59:05 +02:00
|
|
|
module.Module.properties.Installable = proptools.BoolPtr(true)
|
2019-02-06 06:55:21 +01:00
|
|
|
module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
|
2019-03-26 18:51:39 +01:00
|
|
|
module.appProperties.AlwaysPackageNativeLibs = true
|
2018-11-12 19:13:39 +01:00
|
|
|
module.Module.dexpreopter.isTest = true
|
2018-05-22 20:11:52 +02:00
|
|
|
|
|
|
|
module.AddProperties(
|
|
|
|
&module.Module.properties,
|
|
|
|
&module.Module.deviceProperties,
|
2018-11-12 19:13:39 +01:00
|
|
|
&module.Module.dexpreoptProperties,
|
2018-05-22 20:11:52 +02:00
|
|
|
&module.Module.protoProperties,
|
|
|
|
&module.aaptProperties,
|
|
|
|
&module.appProperties,
|
2018-07-17 02:21:19 +02:00
|
|
|
&module.appTestProperties,
|
2019-03-01 00:35:54 +01:00
|
|
|
&module.overridableAppProperties,
|
2019-05-16 21:28:22 +02:00
|
|
|
&module.usesLibrary.usesLibraryProperties,
|
2018-07-17 02:21:19 +02:00
|
|
|
&module.testProperties)
|
2018-05-22 20:11:52 +02:00
|
|
|
|
2018-10-03 07:03:40 +02:00
|
|
|
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
|
|
|
android.InitDefaultableModule(module)
|
2019-06-06 17:45:58 +02:00
|
|
|
android.InitOverridableModule(module, &module.appProperties.Overrides)
|
2018-05-22 20:11:52 +02:00
|
|
|
return module
|
|
|
|
}
|
2018-10-05 00:21:03 +02:00
|
|
|
|
2018-10-05 00:22:03 +02:00
|
|
|
type appTestHelperAppProperties struct {
|
|
|
|
// list of compatibility suites (for example "cts", "vts") that the module should be
|
|
|
|
// installed into.
|
|
|
|
Test_suites []string `android:"arch_variant"`
|
2019-09-26 20:41:36 +02:00
|
|
|
|
|
|
|
// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
|
|
|
|
// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
|
|
|
|
// explicitly.
|
|
|
|
Auto_gen_config *bool
|
2018-10-05 00:22:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type AndroidTestHelperApp struct {
|
|
|
|
AndroidApp
|
|
|
|
|
|
|
|
appTestHelperAppProperties appTestHelperAppProperties
|
|
|
|
}
|
|
|
|
|
2019-11-21 19:41:00 +01:00
|
|
|
func (a *AndroidTestHelperApp) InstallInTestcases() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-02-12 23:41:32 +01:00
|
|
|
// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
|
|
|
|
// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
|
|
|
|
// test.
|
2018-10-05 00:22:03 +02:00
|
|
|
func AndroidTestHelperAppFactory() android.Module {
|
|
|
|
module := &AndroidTestHelperApp{}
|
|
|
|
|
2019-04-17 02:16:58 +02:00
|
|
|
module.Module.deviceProperties.Optimize.EnabledByDefault = true
|
2018-10-05 00:22:03 +02:00
|
|
|
|
|
|
|
module.Module.properties.Installable = proptools.BoolPtr(true)
|
2019-02-06 06:55:21 +01:00
|
|
|
module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
|
2019-03-26 18:51:39 +01:00
|
|
|
module.appProperties.AlwaysPackageNativeLibs = true
|
2018-11-12 19:13:39 +01:00
|
|
|
module.Module.dexpreopter.isTest = true
|
2018-10-05 00:22:03 +02:00
|
|
|
|
|
|
|
module.AddProperties(
|
|
|
|
&module.Module.properties,
|
|
|
|
&module.Module.deviceProperties,
|
2018-11-12 19:13:39 +01:00
|
|
|
&module.Module.dexpreoptProperties,
|
2018-10-05 00:22:03 +02:00
|
|
|
&module.Module.protoProperties,
|
|
|
|
&module.aaptProperties,
|
|
|
|
&module.appProperties,
|
2019-03-01 00:35:54 +01:00
|
|
|
&module.appTestHelperAppProperties,
|
2019-05-16 21:28:22 +02:00
|
|
|
&module.overridableAppProperties,
|
|
|
|
&module.usesLibrary.usesLibraryProperties)
|
2018-10-05 00:22:03 +02:00
|
|
|
|
|
|
|
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
|
|
|
android.InitDefaultableModule(module)
|
2020-01-10 16:06:01 +01:00
|
|
|
android.InitApexModule(module)
|
2018-10-05 00:22:03 +02:00
|
|
|
return module
|
|
|
|
}
|
|
|
|
|
2018-10-05 00:21:03 +02:00
|
|
|
type AndroidAppCertificate struct {
|
|
|
|
android.ModuleBase
|
|
|
|
properties AndroidAppCertificateProperties
|
2018-10-30 13:20:05 +01:00
|
|
|
Certificate Certificate
|
2018-10-05 00:21:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type AndroidAppCertificateProperties struct {
|
|
|
|
// Name of the certificate files. Extensions .x509.pem and .pk8 will be added to the name.
|
|
|
|
Certificate *string
|
|
|
|
}
|
|
|
|
|
2019-02-12 23:41:32 +01:00
|
|
|
// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
|
|
|
|
// the signing key.
|
2018-10-05 00:21:03 +02:00
|
|
|
func AndroidAppCertificateFactory() android.Module {
|
|
|
|
module := &AndroidAppCertificate{}
|
|
|
|
module.AddProperties(&module.properties)
|
|
|
|
android.InitAndroidModule(module)
|
|
|
|
return module
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
|
|
cert := String(c.properties.Certificate)
|
2018-10-30 13:20:05 +01:00
|
|
|
c.Certificate = Certificate{
|
2020-01-28 23:00:53 +01:00
|
|
|
Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"),
|
|
|
|
Key: android.PathForModuleSrc(ctx, cert+".pk8"),
|
2018-10-05 00:21:03 +02:00
|
|
|
}
|
|
|
|
}
|
2019-03-01 00:35:54 +01:00
|
|
|
|
|
|
|
type OverrideAndroidApp struct {
|
|
|
|
android.ModuleBase
|
|
|
|
android.OverrideModuleBase
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *OverrideAndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
|
|
// All the overrides happen in the base module.
|
|
|
|
// TODO(jungjw): Check the base module type.
|
|
|
|
}
|
|
|
|
|
|
|
|
// override_android_app is used to create an android_app module based on another android_app by overriding
|
|
|
|
// some of its properties.
|
|
|
|
func OverrideAndroidAppModuleFactory() android.Module {
|
|
|
|
m := &OverrideAndroidApp{}
|
|
|
|
m.AddProperties(&overridableAppProperties{})
|
|
|
|
|
2019-05-11 00:16:29 +02:00
|
|
|
android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
|
2019-03-01 00:35:54 +01:00
|
|
|
android.InitOverrideModule(m)
|
|
|
|
return m
|
|
|
|
}
|
2019-04-15 18:48:31 +02:00
|
|
|
|
2019-06-06 17:45:58 +02:00
|
|
|
type OverrideAndroidTest struct {
|
|
|
|
android.ModuleBase
|
|
|
|
android.OverrideModuleBase
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
|
|
// All the overrides happen in the base module.
|
|
|
|
// TODO(jungjw): Check the base module type.
|
|
|
|
}
|
|
|
|
|
|
|
|
// override_android_test is used to create an android_app module based on another android_test by overriding
|
|
|
|
// some of its properties.
|
|
|
|
func OverrideAndroidTestModuleFactory() android.Module {
|
|
|
|
m := &OverrideAndroidTest{}
|
|
|
|
m.AddProperties(&overridableAppProperties{})
|
|
|
|
m.AddProperties(&appTestProperties{})
|
|
|
|
|
|
|
|
android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
|
|
|
|
android.InitOverrideModule(m)
|
|
|
|
return m
|
|
|
|
}
|
|
|
|
|
2020-04-27 18:42:27 +02:00
|
|
|
type OverrideRuntimeResourceOverlay struct {
|
|
|
|
android.ModuleBase
|
|
|
|
android.OverrideModuleBase
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
|
|
// All the overrides happen in the base module.
|
|
|
|
// TODO(jungjw): Check the base module type.
|
|
|
|
}
|
|
|
|
|
|
|
|
// override_runtime_resource_overlay is used to create a module based on another
|
|
|
|
// runtime_resource_overlay module by overriding some of its properties.
|
|
|
|
func OverrideRuntimeResourceOverlayModuleFactory() android.Module {
|
|
|
|
m := &OverrideRuntimeResourceOverlay{}
|
|
|
|
m.AddProperties(&OverridableRuntimeResourceOverlayProperties{})
|
|
|
|
|
|
|
|
android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon)
|
|
|
|
android.InitOverrideModule(m)
|
|
|
|
return m
|
|
|
|
}
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
type AndroidAppImport struct {
|
|
|
|
android.ModuleBase
|
|
|
|
android.DefaultableModuleBase
|
2020-04-21 15:34:28 +02:00
|
|
|
android.ApexModuleBase
|
2019-04-15 18:48:31 +02:00
|
|
|
prebuilt android.Prebuilt
|
|
|
|
|
2019-08-13 23:11:33 +02:00
|
|
|
properties AndroidAppImportProperties
|
|
|
|
dpiVariants interface{}
|
|
|
|
archVariants interface{}
|
2019-04-15 18:48:31 +02:00
|
|
|
|
|
|
|
outputFile android.Path
|
2020-01-28 23:00:53 +01:00
|
|
|
certificate Certificate
|
2019-04-15 18:48:31 +02:00
|
|
|
|
|
|
|
dexpreopter
|
2019-05-16 21:28:22 +02:00
|
|
|
|
|
|
|
usesLibrary usesLibrary
|
2019-07-17 19:21:49 +02:00
|
|
|
|
2019-10-02 07:05:35 +02:00
|
|
|
installPath android.InstallPath
|
2019-04-15 18:48:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type AndroidAppImportProperties struct {
|
|
|
|
// A prebuilt apk to import
|
2019-06-11 21:25:34 +02:00
|
|
|
Apk *string
|
2019-04-26 23:31:50 +02:00
|
|
|
|
2019-08-22 23:25:58 +02:00
|
|
|
// The name of a certificate in the default certificate directory or an android_app_certificate
|
|
|
|
// module name in the form ":module". Should be empty if presigned or default_dev_cert is set.
|
2019-04-15 18:48:31 +02:00
|
|
|
Certificate *string
|
|
|
|
|
|
|
|
// Set this flag to true if the prebuilt apk is already signed. The certificate property must not
|
|
|
|
// be set for presigned modules.
|
|
|
|
Presigned *bool
|
|
|
|
|
2019-08-22 23:25:58 +02:00
|
|
|
// Sign with the default system dev certificate. Must be used judiciously. Most imported apps
|
|
|
|
// need to either specify a specific certificate or be presigned.
|
|
|
|
Default_dev_cert *bool
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
// Specifies that this app should be installed to the priv-app directory,
|
|
|
|
// where the system will grant it additional privileges not available to
|
|
|
|
// normal apps.
|
|
|
|
Privileged *bool
|
|
|
|
|
|
|
|
// Names of modules to be overridden. Listed modules can only be other binaries
|
|
|
|
// (in Make or Soong).
|
|
|
|
// This does not completely prevent installation of the overridden binaries, but if both
|
|
|
|
// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
|
|
|
|
// from PRODUCT_PACKAGES.
|
|
|
|
Overrides []string
|
2019-07-17 19:21:49 +02:00
|
|
|
|
|
|
|
// Optional name for the installed app. If unspecified, it is derived from the module name.
|
|
|
|
Filename *string
|
2019-04-15 18:48:31 +02:00
|
|
|
}
|
|
|
|
|
2020-01-31 18:10:36 +01:00
|
|
|
func (a *AndroidAppImport) IsInstallable() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-08-13 23:11:33 +02:00
|
|
|
// Updates properties with variant-specific values.
|
|
|
|
func (a *AndroidAppImport) processVariants(ctx android.LoadHookContext) {
|
2019-04-26 23:31:50 +02:00
|
|
|
config := ctx.Config()
|
2019-06-11 21:25:34 +02:00
|
|
|
|
|
|
|
dpiProps := reflect.ValueOf(a.dpiVariants).Elem().FieldByName("Dpi_variants")
|
|
|
|
// Try DPI variant matches in the reverse-priority order so that the highest priority match
|
|
|
|
// overwrites everything else.
|
|
|
|
// TODO(jungjw): Can we optimize this by making it priority order?
|
|
|
|
for i := len(config.ProductAAPTPrebuiltDPI()) - 1; i >= 0; i-- {
|
2019-08-13 23:11:33 +02:00
|
|
|
MergePropertiesFromVariant(ctx, &a.properties, dpiProps, config.ProductAAPTPrebuiltDPI()[i])
|
2019-04-26 23:31:50 +02:00
|
|
|
}
|
|
|
|
if config.ProductAAPTPreferredConfig() != "" {
|
2019-08-13 23:11:33 +02:00
|
|
|
MergePropertiesFromVariant(ctx, &a.properties, dpiProps, config.ProductAAPTPreferredConfig())
|
2019-04-26 23:31:50 +02:00
|
|
|
}
|
2019-08-13 23:11:33 +02:00
|
|
|
|
|
|
|
archProps := reflect.ValueOf(a.archVariants).Elem().FieldByName("Arch")
|
|
|
|
archType := ctx.Config().Targets[android.Android][0].Arch.ArchType
|
|
|
|
MergePropertiesFromVariant(ctx, &a.properties, archProps, archType.Name)
|
2019-06-11 21:25:34 +02:00
|
|
|
}
|
|
|
|
|
2019-12-31 03:43:07 +01:00
|
|
|
func MergePropertiesFromVariant(ctx android.EarlyModuleContext,
|
2019-08-13 23:11:33 +02:00
|
|
|
dst interface{}, variantGroup reflect.Value, variant string) {
|
2019-06-11 21:25:34 +02:00
|
|
|
src := variantGroup.FieldByName(proptools.FieldNameForProperty(variant))
|
|
|
|
if !src.IsValid() {
|
2019-08-13 23:11:33 +02:00
|
|
|
return
|
2019-04-26 23:31:50 +02:00
|
|
|
}
|
|
|
|
|
2019-06-11 21:25:34 +02:00
|
|
|
err := proptools.ExtendMatchingProperties([]interface{}{dst}, src.Interface(), nil, proptools.OrderAppend)
|
|
|
|
if err != nil {
|
|
|
|
if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
|
|
|
|
ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
|
|
|
|
} else {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
2019-04-26 23:31:50 +02:00
|
|
|
}
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
|
|
cert := android.SrcIsModule(String(a.properties.Certificate))
|
|
|
|
if cert != "" {
|
|
|
|
ctx.AddDependency(ctx.Module(), certificateTag, cert)
|
|
|
|
}
|
2019-05-16 21:28:22 +02:00
|
|
|
|
2019-06-07 11:44:37 +02:00
|
|
|
a.usesLibrary.deps(ctx, true)
|
2019-04-15 18:48:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
|
|
|
|
ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
|
2020-01-13 18:55:39 +01:00
|
|
|
// Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing
|
|
|
|
// with them may invalidate pre-existing signature data.
|
|
|
|
if ctx.InstallInTestcases() && Bool(a.properties.Presigned) {
|
|
|
|
ctx.Build(pctx, android.BuildParams{
|
|
|
|
Rule: android.Cp,
|
|
|
|
Output: outputPath,
|
|
|
|
Input: inputPath,
|
|
|
|
})
|
|
|
|
return
|
|
|
|
}
|
2019-04-15 18:48:31 +02:00
|
|
|
rule := android.NewRuleBuilder()
|
|
|
|
rule.Command().
|
|
|
|
Textf(`if (zipinfo %s 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
|
2019-07-09 02:08:34 +02:00
|
|
|
BuiltTool(ctx, "zip2zip").
|
2019-04-15 18:48:31 +02:00
|
|
|
FlagWithInput("-i ", inputPath).
|
|
|
|
FlagWithOutput("-o ", outputPath).
|
|
|
|
FlagWithArg("-0 ", "'lib/**/*.so'").
|
|
|
|
Textf(`; else cp -f %s %s; fi`, inputPath, outputPath)
|
|
|
|
rule.Build(pctx, ctx, "uncompress-embedded-jni-libs", "Uncompress embedded JIN libs")
|
|
|
|
}
|
|
|
|
|
2019-05-02 23:55:29 +02:00
|
|
|
// Returns whether this module should have the dex file stored uncompressed in the APK.
|
|
|
|
func (a *AndroidAppImport) shouldUncompressDex(ctx android.ModuleContext) bool {
|
|
|
|
if ctx.Config().UnbundledBuild() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// Uncompress dex in APKs of privileged apps
|
2019-10-17 05:54:30 +02:00
|
|
|
if ctx.Config().UncompressPrivAppDex() && a.Privileged() {
|
2019-05-02 23:55:29 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return shouldUncompressDex(ctx, &a.dexpreopter)
|
|
|
|
}
|
|
|
|
|
2019-05-09 23:36:34 +02:00
|
|
|
func (a *AndroidAppImport) uncompressDex(
|
|
|
|
ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
|
|
|
|
rule := android.NewRuleBuilder()
|
|
|
|
rule.Command().
|
|
|
|
Textf(`if (zipinfo %s '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
|
2019-07-09 02:08:34 +02:00
|
|
|
BuiltTool(ctx, "zip2zip").
|
2019-05-09 23:36:34 +02:00
|
|
|
FlagWithInput("-i ", inputPath).
|
|
|
|
FlagWithOutput("-o ", outputPath).
|
|
|
|
FlagWithArg("-0 ", "'classes*.dex'").
|
|
|
|
Textf(`; else cp -f %s %s; fi`, inputPath, outputPath)
|
|
|
|
rule.Build(pctx, ctx, "uncompress-dex", "Uncompress dex files")
|
|
|
|
}
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
2019-08-28 00:01:50 +02:00
|
|
|
a.generateAndroidBuildActions(ctx)
|
|
|
|
}
|
|
|
|
|
2020-03-23 12:21:11 +01:00
|
|
|
func (a *AndroidAppImport) InstallApkName() string {
|
|
|
|
return a.BaseModuleName()
|
|
|
|
}
|
|
|
|
|
2019-08-28 00:01:50 +02:00
|
|
|
func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext) {
|
2019-08-22 23:25:58 +02:00
|
|
|
numCertPropsSet := 0
|
|
|
|
if String(a.properties.Certificate) != "" {
|
|
|
|
numCertPropsSet++
|
|
|
|
}
|
|
|
|
if Bool(a.properties.Presigned) {
|
|
|
|
numCertPropsSet++
|
|
|
|
}
|
|
|
|
if Bool(a.properties.Default_dev_cert) {
|
|
|
|
numCertPropsSet++
|
2019-04-15 18:48:31 +02:00
|
|
|
}
|
2019-08-22 23:25:58 +02:00
|
|
|
if numCertPropsSet != 1 {
|
|
|
|
ctx.ModuleErrorf("One and only one of certficate, presigned, and default_dev_cert properties must be set")
|
2019-04-15 18:48:31 +02:00
|
|
|
}
|
|
|
|
|
2020-05-13 20:05:02 +02:00
|
|
|
_, certificates := collectAppDeps(ctx, a, false, false)
|
2019-04-15 18:48:31 +02:00
|
|
|
|
|
|
|
// TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
|
|
|
|
// TODO: LOCAL_PACKAGE_SPLITS
|
|
|
|
|
2019-06-11 21:25:34 +02:00
|
|
|
srcApk := a.prebuilt.SingleSourcePath(ctx)
|
2019-05-16 21:28:22 +02:00
|
|
|
|
|
|
|
if a.usesLibrary.enforceUsesLibraries() {
|
|
|
|
srcApk = a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
|
|
|
|
}
|
2019-04-15 18:48:31 +02:00
|
|
|
|
|
|
|
// TODO: Install or embed JNI libraries
|
|
|
|
|
|
|
|
// Uncompress JNI libraries in the apk
|
|
|
|
jnisUncompressed := android.PathForModuleOut(ctx, "jnis-uncompressed", ctx.ModuleName()+".apk")
|
|
|
|
a.uncompressEmbeddedJniLibs(ctx, srcApk, jnisUncompressed.OutputPath)
|
|
|
|
|
2019-11-22 03:38:16 +01:00
|
|
|
var installDir android.InstallPath
|
|
|
|
if Bool(a.properties.Privileged) {
|
|
|
|
installDir = android.PathForModuleInstall(ctx, "priv-app", a.BaseModuleName())
|
2020-01-13 18:55:39 +01:00
|
|
|
} else if ctx.InstallInTestcases() {
|
|
|
|
installDir = android.PathForModuleInstall(ctx, a.BaseModuleName(), ctx.DeviceConfig().DeviceArch())
|
2019-11-22 03:38:16 +01:00
|
|
|
} else {
|
|
|
|
installDir = android.PathForModuleInstall(ctx, "app", a.BaseModuleName())
|
|
|
|
}
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
a.dexpreopter.installPath = installDir.Join(ctx, a.BaseModuleName()+".apk")
|
|
|
|
a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned)
|
2019-05-02 23:55:29 +02:00
|
|
|
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
|
2019-05-16 21:28:22 +02:00
|
|
|
|
|
|
|
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
|
|
|
|
a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs
|
|
|
|
a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx)
|
|
|
|
a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx)
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
dexOutput := a.dexpreopter.dexpreopt(ctx, jnisUncompressed)
|
2019-05-09 23:36:34 +02:00
|
|
|
if a.dexpreopter.uncompressedDex {
|
|
|
|
dexUncompressed := android.PathForModuleOut(ctx, "dex-uncompressed", ctx.ModuleName()+".apk")
|
|
|
|
a.uncompressDex(ctx, dexOutput, dexUncompressed.OutputPath)
|
|
|
|
dexOutput = dexUncompressed
|
|
|
|
}
|
2019-04-15 18:48:31 +02:00
|
|
|
|
2020-03-23 12:21:11 +01:00
|
|
|
apkFilename := proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+".apk")
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
// Sign or align the package
|
|
|
|
// TODO: Handle EXTERNAL
|
|
|
|
if !Bool(a.properties.Presigned) {
|
2019-08-22 23:25:58 +02:00
|
|
|
// If the certificate property is empty at this point, default_dev_cert must be set to true.
|
|
|
|
// Which makes processMainCert's behavior for the empty cert string WAI.
|
|
|
|
certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
|
2019-04-15 18:48:31 +02:00
|
|
|
if len(certificates) != 1 {
|
|
|
|
ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates)
|
|
|
|
}
|
2020-01-28 23:00:53 +01:00
|
|
|
a.certificate = certificates[0]
|
2020-03-23 12:21:11 +01:00
|
|
|
signed := android.PathForModuleOut(ctx, "signed", apkFilename)
|
2020-05-07 22:24:05 +02:00
|
|
|
SignAppPackage(ctx, signed, dexOutput, certificates, nil)
|
2019-04-15 18:48:31 +02:00
|
|
|
a.outputFile = signed
|
|
|
|
} else {
|
2020-03-23 12:21:11 +01:00
|
|
|
alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename)
|
2019-04-15 18:48:31 +02:00
|
|
|
TransformZipAlign(ctx, alignedApk, dexOutput)
|
|
|
|
a.outputFile = alignedApk
|
2020-01-28 23:00:53 +01:00
|
|
|
a.certificate = presignedCertificate
|
2019-04-15 18:48:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Optionally compress the output apk.
|
|
|
|
|
2020-04-21 15:34:28 +02:00
|
|
|
if a.IsForPlatform() {
|
|
|
|
a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile)
|
|
|
|
}
|
2019-04-15 18:48:31 +02:00
|
|
|
|
|
|
|
// TODO: androidmk converter jni libs
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidAppImport) Prebuilt() *android.Prebuilt {
|
|
|
|
return &a.prebuilt
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidAppImport) Name() string {
|
|
|
|
return a.prebuilt.Name(a.ModuleBase.Name())
|
|
|
|
}
|
|
|
|
|
2019-10-27 01:29:22 +02:00
|
|
|
func (a *AndroidAppImport) OutputFile() android.Path {
|
|
|
|
return a.outputFile
|
|
|
|
}
|
|
|
|
|
2020-01-08 05:35:43 +01:00
|
|
|
func (a *AndroidAppImport) JacocoReportClassesFile() android.Path {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-01-28 23:00:53 +01:00
|
|
|
func (a *AndroidAppImport) Certificate() Certificate {
|
|
|
|
return a.certificate
|
|
|
|
}
|
|
|
|
|
2019-08-13 23:11:33 +02:00
|
|
|
var dpiVariantGroupType reflect.Type
|
|
|
|
var archVariantGroupType reflect.Type
|
|
|
|
|
|
|
|
func initAndroidAppImportVariantGroupTypes() {
|
|
|
|
dpiVariantGroupType = createVariantGroupType(supportedDpis, "Dpi_variants")
|
|
|
|
|
|
|
|
archNames := make([]string, len(android.ArchTypeList()))
|
|
|
|
for i, archType := range android.ArchTypeList() {
|
|
|
|
archNames[i] = archType.Name
|
|
|
|
}
|
|
|
|
archVariantGroupType = createVariantGroupType(archNames, "Arch")
|
|
|
|
}
|
2019-06-11 21:25:34 +02:00
|
|
|
|
2019-08-13 23:11:33 +02:00
|
|
|
// Populates all variant struct properties at creation time.
|
|
|
|
func (a *AndroidAppImport) populateAllVariantStructs() {
|
|
|
|
a.dpiVariants = reflect.New(dpiVariantGroupType).Interface()
|
|
|
|
a.AddProperties(a.dpiVariants)
|
|
|
|
|
|
|
|
a.archVariants = reflect.New(archVariantGroupType).Interface()
|
|
|
|
a.AddProperties(a.archVariants)
|
|
|
|
}
|
|
|
|
|
2019-10-17 05:54:30 +02:00
|
|
|
func (a *AndroidAppImport) Privileged() bool {
|
|
|
|
return Bool(a.properties.Privileged)
|
|
|
|
}
|
|
|
|
|
2020-04-21 15:34:28 +02:00
|
|
|
func (a *AndroidAppImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
|
|
|
|
// android_app_import might have extra dependencies via uses_libs property.
|
|
|
|
// Don't track the dependency as we don't automatically add those libraries
|
|
|
|
// to the classpath. It should be explicitly added to java_libs property of APEX
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-05-13 20:05:02 +02:00
|
|
|
func (a *AndroidAppImport) sdkVersion() sdkSpec {
|
|
|
|
return sdkSpecFrom("")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidAppImport) minSdkVersion() sdkSpec {
|
|
|
|
return sdkSpecFrom("")
|
|
|
|
}
|
|
|
|
|
2019-08-13 23:11:33 +02:00
|
|
|
func createVariantGroupType(variants []string, variantGroupName string) reflect.Type {
|
|
|
|
props := reflect.TypeOf((*AndroidAppImportProperties)(nil))
|
|
|
|
|
|
|
|
variantFields := make([]reflect.StructField, len(variants))
|
|
|
|
for i, variant := range variants {
|
|
|
|
variantFields[i] = reflect.StructField{
|
|
|
|
Name: proptools.FieldNameForProperty(variant),
|
2019-06-11 21:25:34 +02:00
|
|
|
Type: props,
|
|
|
|
}
|
|
|
|
}
|
2019-08-13 23:11:33 +02:00
|
|
|
|
|
|
|
variantGroupStruct := reflect.StructOf(variantFields)
|
|
|
|
return reflect.StructOf([]reflect.StructField{
|
2019-06-11 21:25:34 +02:00
|
|
|
{
|
2019-08-13 23:11:33 +02:00
|
|
|
Name: variantGroupName,
|
|
|
|
Type: variantGroupStruct,
|
2019-06-11 21:25:34 +02:00
|
|
|
},
|
2019-08-13 23:11:33 +02:00
|
|
|
})
|
2019-06-11 21:25:34 +02:00
|
|
|
}
|
|
|
|
|
2019-04-15 18:48:31 +02:00
|
|
|
// android_app_import imports a prebuilt apk with additional processing specified in the module.
|
2019-06-11 21:25:34 +02:00
|
|
|
// DPI-specific apk source files can be specified using dpi_variants. Example:
|
|
|
|
//
|
|
|
|
// android_app_import {
|
|
|
|
// name: "example_import",
|
|
|
|
// apk: "prebuilts/example.apk",
|
|
|
|
// dpi_variants: {
|
|
|
|
// mdpi: {
|
|
|
|
// apk: "prebuilts/example_mdpi.apk",
|
|
|
|
// },
|
|
|
|
// xhdpi: {
|
|
|
|
// apk: "prebuilts/example_xhdpi.apk",
|
|
|
|
// },
|
|
|
|
// },
|
|
|
|
// certificate: "PRESIGNED",
|
|
|
|
// }
|
2019-04-15 18:48:31 +02:00
|
|
|
func AndroidAppImportFactory() android.Module {
|
|
|
|
module := &AndroidAppImport{}
|
|
|
|
module.AddProperties(&module.properties)
|
|
|
|
module.AddProperties(&module.dexpreoptProperties)
|
2019-05-16 21:28:22 +02:00
|
|
|
module.AddProperties(&module.usesLibrary.usesLibraryProperties)
|
2019-08-13 23:11:33 +02:00
|
|
|
module.populateAllVariantStructs()
|
2019-06-11 21:25:34 +02:00
|
|
|
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
|
2019-08-13 23:11:33 +02:00
|
|
|
module.processVariants(ctx)
|
2019-06-11 21:25:34 +02:00
|
|
|
})
|
2019-04-15 18:48:31 +02:00
|
|
|
|
2020-04-21 15:34:28 +02:00
|
|
|
android.InitApexModule(module)
|
2019-04-15 18:48:31 +02:00
|
|
|
InitJavaModule(module, android.DeviceSupported)
|
2019-06-11 21:25:34 +02:00
|
|
|
android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
|
2019-04-15 18:48:31 +02:00
|
|
|
|
|
|
|
return module
|
|
|
|
}
|
2019-05-16 21:28:22 +02:00
|
|
|
|
2019-08-28 00:01:50 +02:00
|
|
|
type AndroidTestImport struct {
|
|
|
|
AndroidAppImport
|
|
|
|
|
|
|
|
testProperties testProperties
|
|
|
|
|
|
|
|
data android.Paths
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
|
|
a.generateAndroidBuildActions(ctx)
|
|
|
|
|
|
|
|
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
|
|
|
|
}
|
|
|
|
|
2020-01-13 18:55:39 +01:00
|
|
|
func (a *AndroidTestImport) InstallInTestcases() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-08-28 00:01:50 +02:00
|
|
|
// android_test_import imports a prebuilt test apk with additional processing specified in the
|
|
|
|
// module. DPI or arch variant configurations can be made as with android_app_import.
|
|
|
|
func AndroidTestImportFactory() android.Module {
|
|
|
|
module := &AndroidTestImport{}
|
|
|
|
module.AddProperties(&module.properties)
|
|
|
|
module.AddProperties(&module.dexpreoptProperties)
|
|
|
|
module.AddProperties(&module.usesLibrary.usesLibraryProperties)
|
|
|
|
module.AddProperties(&module.testProperties)
|
|
|
|
module.populateAllVariantStructs()
|
|
|
|
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
|
|
|
|
module.processVariants(ctx)
|
|
|
|
})
|
|
|
|
|
2020-05-07 07:29:10 +02:00
|
|
|
module.dexpreopter.isTest = true
|
|
|
|
|
2020-04-21 15:34:28 +02:00
|
|
|
android.InitApexModule(module)
|
2020-05-02 00:50:08 +02:00
|
|
|
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
|
|
|
android.InitDefaultableModule(module)
|
2019-08-28 00:01:50 +02:00
|
|
|
android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
|
|
|
|
|
|
|
|
return module
|
|
|
|
}
|
|
|
|
|
2020-01-18 19:33:43 +01:00
|
|
|
type RuntimeResourceOverlay struct {
|
|
|
|
android.ModuleBase
|
|
|
|
android.DefaultableModuleBase
|
2020-04-27 18:42:27 +02:00
|
|
|
android.OverridableModuleBase
|
2020-01-18 19:33:43 +01:00
|
|
|
aapt
|
|
|
|
|
2020-04-27 18:42:27 +02:00
|
|
|
properties RuntimeResourceOverlayProperties
|
|
|
|
overridableProperties OverridableRuntimeResourceOverlayProperties
|
2020-01-18 19:33:43 +01:00
|
|
|
|
2020-01-31 19:11:47 +01:00
|
|
|
certificate Certificate
|
|
|
|
|
2020-01-18 19:33:43 +01:00
|
|
|
outputFile android.Path
|
|
|
|
installDir android.InstallPath
|
|
|
|
}
|
|
|
|
|
|
|
|
type RuntimeResourceOverlayProperties struct {
|
|
|
|
// the name of a certificate in the default certificate directory or an android_app_certificate
|
|
|
|
// module name in the form ":module".
|
|
|
|
Certificate *string
|
|
|
|
|
|
|
|
// optional theme name. If specified, the overlay package will be applied
|
|
|
|
// only when the ro.boot.vendor.overlay.theme system property is set to the same value.
|
|
|
|
Theme *string
|
|
|
|
|
|
|
|
// if not blank, set to the version of the sdk to compile against.
|
|
|
|
// Defaults to compiling against the current platform.
|
|
|
|
Sdk_version *string
|
|
|
|
|
|
|
|
// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
|
|
|
|
// Defaults to sdk_version if not set.
|
|
|
|
Min_sdk_version *string
|
2020-04-10 01:15:30 +02:00
|
|
|
|
|
|
|
// list of android_library modules whose resources are extracted and linked against statically
|
|
|
|
Static_libs []string
|
|
|
|
|
|
|
|
// list of android_app modules whose resources are extracted and linked against
|
|
|
|
Resource_libs []string
|
2020-04-25 00:22:40 +02:00
|
|
|
|
|
|
|
// Names of modules to be overridden. Listed modules can only be other overlays
|
|
|
|
// (in Make or Soong).
|
|
|
|
// This does not completely prevent installation of the overridden overlays, but if both
|
|
|
|
// overlays would be installed by default (in PRODUCT_PACKAGES) the other overlay will be removed
|
|
|
|
// from PRODUCT_PACKAGES.
|
|
|
|
Overrides []string
|
2020-01-18 19:33:43 +01:00
|
|
|
}
|
|
|
|
|
2020-04-24 14:16:36 +02:00
|
|
|
// RuntimeResourceOverlayModule interface is used by the apex package to gather information from
|
|
|
|
// a RuntimeResourceOverlay module.
|
|
|
|
type RuntimeResourceOverlayModule interface {
|
|
|
|
android.Module
|
|
|
|
OutputFile() android.Path
|
|
|
|
Certificate() Certificate
|
|
|
|
Theme() string
|
|
|
|
}
|
|
|
|
|
2020-01-18 19:33:43 +01:00
|
|
|
func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
|
|
sdkDep := decodeSdkDep(ctx, sdkContext(r))
|
|
|
|
if sdkDep.hasFrameworkLibs() {
|
|
|
|
r.aapt.deps(ctx, sdkDep)
|
|
|
|
}
|
|
|
|
|
|
|
|
cert := android.SrcIsModule(String(r.properties.Certificate))
|
|
|
|
if cert != "" {
|
|
|
|
ctx.AddDependency(ctx.Module(), certificateTag, cert)
|
|
|
|
}
|
2020-04-10 01:15:30 +02:00
|
|
|
|
|
|
|
ctx.AddVariationDependencies(nil, staticLibTag, r.properties.Static_libs...)
|
|
|
|
ctx.AddVariationDependencies(nil, libTag, r.properties.Resource_libs...)
|
2020-01-18 19:33:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
|
|
// Compile and link resources
|
|
|
|
r.aapt.hasNoCode = true
|
2020-01-24 19:30:02 +01:00
|
|
|
// Do not remove resources without default values nor dedupe resource configurations with the same value
|
2020-04-27 18:42:27 +02:00
|
|
|
aaptLinkFlags := []string{"--no-resource-deduping", "--no-resource-removal"}
|
|
|
|
// Allow the override of "package name" and "overlay target package name"
|
|
|
|
manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
|
|
|
|
if overridden || r.overridableProperties.Package_name != nil {
|
|
|
|
// The product override variable has a priority over the package_name property.
|
|
|
|
if !overridden {
|
|
|
|
manifestPackageName = *r.overridableProperties.Package_name
|
|
|
|
}
|
|
|
|
aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName)
|
|
|
|
}
|
|
|
|
if r.overridableProperties.Target_package_name != nil {
|
|
|
|
aaptLinkFlags = append(aaptLinkFlags,
|
|
|
|
"--rename-overlay-target-package "+*r.overridableProperties.Target_package_name)
|
|
|
|
}
|
|
|
|
r.aapt.buildActions(ctx, r, aaptLinkFlags...)
|
2020-01-18 19:33:43 +01:00
|
|
|
|
|
|
|
// Sign the built package
|
2020-05-13 20:05:02 +02:00
|
|
|
_, certificates := collectAppDeps(ctx, r, false, false)
|
2020-01-18 19:33:43 +01:00
|
|
|
certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
|
|
|
|
signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
|
2020-05-07 22:24:05 +02:00
|
|
|
SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil)
|
2020-01-31 19:11:47 +01:00
|
|
|
r.certificate = certificates[0]
|
2020-01-18 19:33:43 +01:00
|
|
|
|
|
|
|
r.outputFile = signed
|
|
|
|
r.installDir = android.PathForModuleInstall(ctx, "overlay", String(r.properties.Theme))
|
|
|
|
ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile)
|
|
|
|
}
|
|
|
|
|
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
|
|
|
func (r *RuntimeResourceOverlay) sdkVersion() sdkSpec {
|
|
|
|
return sdkSpecFrom(String(r.properties.Sdk_version))
|
2020-01-18 19:33:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RuntimeResourceOverlay) systemModules() string {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
|
|
|
func (r *RuntimeResourceOverlay) minSdkVersion() sdkSpec {
|
2020-01-18 19:33:43 +01:00
|
|
|
if r.properties.Min_sdk_version != nil {
|
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
|
|
|
return sdkSpecFrom(*r.properties.Min_sdk_version)
|
2020-01-18 19:33:43 +01:00
|
|
|
}
|
|
|
|
return r.sdkVersion()
|
|
|
|
}
|
|
|
|
|
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
|
|
|
func (r *RuntimeResourceOverlay) targetSdkVersion() sdkSpec {
|
2020-01-18 19:33:43 +01:00
|
|
|
return r.sdkVersion()
|
|
|
|
}
|
|
|
|
|
2020-04-24 14:16:36 +02:00
|
|
|
func (r *RuntimeResourceOverlay) Certificate() Certificate {
|
|
|
|
return r.certificate
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RuntimeResourceOverlay) OutputFile() android.Path {
|
|
|
|
return r.outputFile
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RuntimeResourceOverlay) Theme() string {
|
|
|
|
return String(r.properties.Theme)
|
|
|
|
}
|
|
|
|
|
2020-01-18 19:33:43 +01:00
|
|
|
// runtime_resource_overlay generates a resource-only apk file that can overlay application and
|
|
|
|
// system resources at run time.
|
|
|
|
func RuntimeResourceOverlayFactory() android.Module {
|
|
|
|
module := &RuntimeResourceOverlay{}
|
|
|
|
module.AddProperties(
|
|
|
|
&module.properties,
|
2020-04-27 18:42:27 +02:00
|
|
|
&module.aaptProperties,
|
|
|
|
&module.overridableProperties)
|
2020-01-18 19:33:43 +01:00
|
|
|
|
2020-04-27 18:42:27 +02:00
|
|
|
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
|
|
|
android.InitDefaultableModule(module)
|
|
|
|
android.InitOverridableModule(module, &module.properties.Overrides)
|
2020-01-18 19:33:43 +01:00
|
|
|
return module
|
|
|
|
}
|
|
|
|
|
2019-05-16 21:28:22 +02:00
|
|
|
type UsesLibraryProperties struct {
|
|
|
|
// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
|
|
|
|
Uses_libs []string
|
|
|
|
|
|
|
|
// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
|
|
|
|
// required=false.
|
|
|
|
Optional_uses_libs []string
|
|
|
|
|
|
|
|
// If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
|
|
|
|
// to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
|
|
|
|
Enforce_uses_libs *bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
|
|
|
|
// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
|
|
|
|
// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
|
|
|
|
// with knowledge of their shared libraries.
|
|
|
|
type usesLibrary struct {
|
|
|
|
usesLibraryProperties UsesLibraryProperties
|
|
|
|
}
|
|
|
|
|
2019-06-07 11:44:37 +02:00
|
|
|
func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) {
|
2019-06-07 22:18:09 +02:00
|
|
|
if !ctx.Config().UnbundledBuild() {
|
|
|
|
ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...)
|
|
|
|
ctx.AddVariationDependencies(nil, usesLibTag, u.presentOptionalUsesLibs(ctx)...)
|
2019-06-07 11:44:37 +02:00
|
|
|
// Only add these extra dependencies if the module depends on framework libs. This avoids
|
|
|
|
// creating a cyclic dependency:
|
|
|
|
// e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
|
|
|
|
if hasFrameworkLibs {
|
2019-06-07 22:18:09 +02:00
|
|
|
// dexpreopt/dexpreopt.go needs the paths to the dex jars of these libraries in case construct_context.sh needs
|
|
|
|
// to pass them to dex2oat. Add them as a dependency so we can determine the path to the dex jar of each
|
|
|
|
// library to dexpreopt.
|
|
|
|
ctx.AddVariationDependencies(nil, usesLibTag,
|
|
|
|
"org.apache.http.legacy",
|
|
|
|
"android.hidl.base-V1.0-java",
|
|
|
|
"android.hidl.manager-V1.0-java")
|
|
|
|
}
|
2019-05-16 21:28:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// presentOptionalUsesLibs returns optional_uses_libs after filtering out MissingUsesLibraries, which don't exist in the
|
|
|
|
// build.
|
|
|
|
func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
|
|
|
|
optionalUsesLibs, _ := android.FilterList(u.usesLibraryProperties.Optional_uses_libs, ctx.Config().MissingUsesLibraries())
|
|
|
|
return optionalUsesLibs
|
|
|
|
}
|
|
|
|
|
|
|
|
// usesLibraryPaths returns a map of module names of shared library dependencies to the paths to their dex jars.
|
|
|
|
func (u *usesLibrary) usesLibraryPaths(ctx android.ModuleContext) map[string]android.Path {
|
|
|
|
usesLibPaths := make(map[string]android.Path)
|
|
|
|
|
|
|
|
if !ctx.Config().UnbundledBuild() {
|
|
|
|
ctx.VisitDirectDepsWithTag(usesLibTag, func(m android.Module) {
|
|
|
|
if lib, ok := m.(Dependency); ok {
|
|
|
|
if dexJar := lib.DexJar(); dexJar != nil {
|
|
|
|
usesLibPaths[ctx.OtherModuleName(m)] = dexJar
|
|
|
|
} else {
|
|
|
|
ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must produce a dex jar, does it have installable: true?",
|
|
|
|
ctx.OtherModuleName(m))
|
|
|
|
}
|
|
|
|
} else if ctx.Config().AllowMissingDependencies() {
|
|
|
|
ctx.AddMissingDependencies([]string{ctx.OtherModuleName(m)})
|
|
|
|
} else {
|
|
|
|
ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library",
|
|
|
|
ctx.OtherModuleName(m))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return usesLibPaths
|
|
|
|
}
|
|
|
|
|
|
|
|
// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
|
|
|
|
// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
|
|
|
|
// unconditionally in the future.
|
|
|
|
func (u *usesLibrary) enforceUsesLibraries() bool {
|
|
|
|
defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 ||
|
|
|
|
len(u.usesLibraryProperties.Optional_uses_libs) > 0
|
|
|
|
return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, defaultEnforceUsesLibs)
|
|
|
|
}
|
|
|
|
|
|
|
|
// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against the ones specified
|
|
|
|
// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the manifest.
|
|
|
|
func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path {
|
|
|
|
outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
|
|
|
|
|
|
|
|
rule := android.NewRuleBuilder()
|
2019-07-09 02:08:34 +02:00
|
|
|
cmd := rule.Command().BuiltTool(ctx, "manifest_check").
|
2019-05-16 21:28:22 +02:00
|
|
|
Flag("--enforce-uses-libraries").
|
|
|
|
Input(manifest).
|
|
|
|
FlagWithOutput("-o ", outputFile)
|
|
|
|
|
|
|
|
for _, lib := range u.usesLibraryProperties.Uses_libs {
|
|
|
|
cmd.FlagWithArg("--uses-library ", lib)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, lib := range u.usesLibraryProperties.Optional_uses_libs {
|
|
|
|
cmd.FlagWithArg("--optional-uses-library ", lib)
|
|
|
|
}
|
|
|
|
|
|
|
|
rule.Build(pctx, ctx, "verify_uses_libraries", "verify <uses-library>")
|
|
|
|
|
|
|
|
return outputFile
|
|
|
|
}
|
|
|
|
|
|
|
|
// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the ones specified
|
|
|
|
// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the APK.
|
|
|
|
func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path {
|
|
|
|
outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base())
|
|
|
|
|
|
|
|
rule := android.NewRuleBuilder()
|
|
|
|
aapt := ctx.Config().HostToolPath(ctx, "aapt")
|
|
|
|
rule.Command().
|
|
|
|
Textf("aapt_binary=%s", aapt.String()).Implicit(aapt).
|
|
|
|
Textf(`uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Uses_libs, " ")).
|
|
|
|
Textf(`optional_uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Optional_uses_libs, " ")).
|
|
|
|
Tool(android.PathForSource(ctx, "build/make/core/verify_uses_libraries.sh")).Input(apk)
|
|
|
|
rule.Command().Text("cp -f").Input(apk).Output(outputFile)
|
|
|
|
|
|
|
|
rule.Build(pctx, ctx, "verify_uses_libraries", "verify <uses-library>")
|
|
|
|
|
|
|
|
return outputFile
|
|
|
|
}
|