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
|
|
|
|
|
2020-12-21 21:29:12 +01:00
|
|
|
// This file contains the module implementations for android_app, android_test, and some more
|
|
|
|
// related module types, including their override variants.
|
2015-04-13 22:58:27 +02:00
|
|
|
|
|
|
|
import (
|
2019-04-26 23:31:50 +02:00
|
|
|
"path/filepath"
|
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"
|
2021-07-28 12:21:31 +02:00
|
|
|
"android/soong/bazel"
|
2018-10-03 07:03:40 +02:00
|
|
|
"android/soong/cc"
|
2020-06-03 15:57:22 +02:00
|
|
|
"android/soong/dexpreopt"
|
2018-08-08 01:49:25 +02:00
|
|
|
"android/soong/tradefed"
|
2015-04-13 22:58:27 +02:00
|
|
|
)
|
|
|
|
|
2017-11-23 01:19:37 +01:00
|
|
|
func init() {
|
2019-12-18 20:51:55 +01:00
|
|
|
RegisterAppBuildComponents(android.InitRegistrationContext)
|
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)
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2021-03-10 00:02:31 +01:00
|
|
|
// Name of the signing certificate lineage file or filegroup module.
|
|
|
|
Lineage *string `android:"path"`
|
2020-05-07 22:24:05 +02:00
|
|
|
|
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
|
2020-06-18 21:44:06 +02:00
|
|
|
|
|
|
|
// Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
|
|
|
|
Rename_resources_package *bool
|
2019-03-01 00:35:54 +01:00
|
|
|
}
|
|
|
|
|
2015-05-11 22:39:40 +02:00
|
|
|
type AndroidApp struct {
|
Initial bp2build converter for android_app.
The only supported attributes at this point are:
- srcs
- manifest
- package_name
- resource_dirs
as they most easily map to bazel's android_binary's srcs, manifest, custom_package, and resource_files respectively.
Allow-listing all apps that use these fields, along with sdk_version and dex_preopt. The latter 2 are ignored by the converter,
- sdk_version because we're currently relying on a single pre-built SDK,
- dex_preopt because,
1. though it is not supported in Bazel builds yet, it doesn't prevent the apps from building, and
2. the apps being converted only use the dex_preopt attribute to disable dex_preopt, which is what is happening anyway.
Change-Id: I4a4f771eeb8f60a1cd4844b2ac1ce3df7c070e73
Test: ./build/bazel/scripts/run_presubmits.sh
Bug: 198224074
Bug: 203688791
2021-10-29 16:52:59 +02:00
|
|
|
android.BazelModuleBase
|
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
|
|
|
|
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-07-06 23:15:24 +02:00
|
|
|
jniLibs []jniLib
|
|
|
|
installPathForJNISymbols android.Path
|
|
|
|
embeddedJniLibs bool
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-05-28 01:36:07 +02:00
|
|
|
var PresignedCertificate = Certificate{presigned: true}
|
2020-01-28 23:00:53 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
2021-04-02 01:45:46 +02:00
|
|
|
if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
|
2019-05-07 00:48:44 +02:00
|
|
|
ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
|
|
|
|
}
|
|
|
|
|
2021-03-29 13:11:58 +02:00
|
|
|
sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
|
2019-06-07 11:44:37 +02:00
|
|
|
if sdkDep.hasFrameworkLibs() {
|
|
|
|
a.aapt.deps(ctx, sdkDep)
|
2015-04-13 22:58:27 +02:00
|
|
|
}
|
2018-10-03 07:03:40 +02:00
|
|
|
|
2021-04-02 01:45:46 +02:00
|
|
|
usesSDK := a.SdkVersion(ctx).Specified() && a.SdkVersion(ctx).Kind != android.SdkCorePlatform
|
2020-05-08 20:20:24 +02:00
|
|
|
|
|
|
|
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")
|
|
|
|
}
|
|
|
|
|
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"})
|
|
|
|
}
|
2020-10-10 03:59:49 +02:00
|
|
|
ctx.AddFarVariationDependencies(variation, jniLibTag, a.appProperties.Jni_libs...)
|
2018-10-03 07:03:40 +02:00
|
|
|
}
|
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-28 15:57:42 +02:00
|
|
|
if a.Updatable() {
|
2021-04-02 01:45:46 +02:00
|
|
|
if !a.SdkVersion(ctx).Stable() {
|
|
|
|
ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.SdkVersion(ctx))
|
2020-04-08 20:09:30 +02:00
|
|
|
}
|
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-15 04:03:39 +02:00
|
|
|
|
2021-04-02 01:45:46 +02:00
|
|
|
if minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx); err == nil {
|
2020-04-29 07:01:06 +02:00
|
|
|
a.checkJniLibsSdkVersion(ctx, minSdkVersion)
|
2021-12-02 14:59:35 +01:00
|
|
|
android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
|
2020-04-29 07:01:06 +02:00
|
|
|
} 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)
|
2021-03-11 02:02:43 +01:00
|
|
|
// and sdkLinkType is checked with dependencies so we can be sure that the whole dependency tree
|
2020-04-29 07:01:06 +02:00
|
|
|
// will meet the requirements.
|
2021-03-31 11:17:53 +02:00
|
|
|
func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
|
2020-04-29 07:01:06 +02:00
|
|
|
// 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)
|
2020-05-20 10:12:13 +02:00
|
|
|
// The domain of cc.sdk_version is "current" and <number>
|
2021-03-29 13:11:58 +02:00
|
|
|
// We can rely on android.SdkSpec to convert it to <number> so that "current" is
|
|
|
|
// handled properly regardless of sdk finalization.
|
2021-04-02 01:45:46 +02:00
|
|
|
jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.SdkVersion()).EffectiveVersion(ctx)
|
2021-03-31 11:17:53 +02:00
|
|
|
if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
|
2020-04-29 07:01:06 +02:00
|
|
|
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 {
|
2021-04-02 01:45:46 +02:00
|
|
|
minSdkVersion, err := a.MinSdkVersion(ctx).EffectiveVersion(ctx)
|
2019-02-06 06:55:21 +01:00
|
|
|
if err != nil {
|
2021-04-02 01:45:46 +02:00
|
|
|
ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.MinSdkVersion(ctx), err)
|
2019-02-06 06:55:21 +01:00
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
2021-03-31 11:17:53 +02:00
|
|
|
return (minSdkVersion.FinalOrFutureInt() >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) ||
|
2020-09-16 03:30:11 +02:00
|
|
|
!apexInfo.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 {
|
2020-09-16 03:30:11 +02:00
|
|
|
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
2019-05-07 00:48:44 +02:00
|
|
|
return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) ||
|
2020-09-16 03:30:11 +02:00
|
|
|
!apexInfo.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs
|
2019-05-07 00:48:44 +02:00
|
|
|
}
|
|
|
|
|
2020-06-18 21:44:06 +02:00
|
|
|
func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
|
|
|
|
aaptFlags := []string{"--rename-manifest-package " + packageName}
|
|
|
|
if renameResourcesPackage {
|
|
|
|
// Required to rename the package name in the resources table.
|
|
|
|
aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
|
|
|
|
}
|
|
|
|
return aaptFlags
|
|
|
|
}
|
|
|
|
|
2020-02-28 08:51:07 +01:00
|
|
|
func (a *AndroidApp) OverriddenManifestPackageName() string {
|
|
|
|
return a.overriddenManifestPackageName
|
|
|
|
}
|
|
|
|
|
2020-06-18 21:44:06 +02:00
|
|
|
func (a *AndroidApp) renameResourcesPackage() bool {
|
|
|
|
return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
|
|
|
|
}
|
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
|
2021-03-30 03:38:26 +02:00
|
|
|
usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
|
2021-04-02 01:45:46 +02:00
|
|
|
if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
|
2021-03-30 03:38:26 +02:00
|
|
|
usePlatformAPI = true
|
|
|
|
}
|
|
|
|
a.aapt.usesNonSdkApis = usePlatformAPI
|
2019-02-18 19:24:16 +01:00
|
|
|
|
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
|
|
|
|
}
|
2020-06-18 21:44:06 +02:00
|
|
|
aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
|
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
|
2020-02-12 02:27:19 +01:00
|
|
|
a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
|
2021-03-29 13:11:58 +02:00
|
|
|
a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, 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
|
|
|
|
2020-07-06 23:15:24 +02:00
|
|
|
func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
|
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
|
|
|
}
|
2020-07-06 23:15:24 +02:00
|
|
|
|
|
|
|
return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
|
|
|
|
}
|
|
|
|
|
2020-11-03 16:55:11 +01:00
|
|
|
func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
|
2020-07-06 23:15:24 +02:00
|
|
|
a.dexpreopter.installPath = a.installPath(ctx)
|
2021-01-14 18:52:43 +01:00
|
|
|
a.dexpreopter.isApp = true
|
2020-07-10 00:16:41 +02:00
|
|
|
if a.dexProperties.Uncompress_dex == nil {
|
2020-05-20 23:20:28 +02:00
|
|
|
// If the value was not force-set by the user, use reasonable default based on the module.
|
2020-07-10 00:16:41 +02:00
|
|
|
a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
|
2020-05-20 23:20:28 +02:00
|
|
|
}
|
2020-07-10 00:16:41 +02:00
|
|
|
a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
|
2019-05-16 21:28:22 +02:00
|
|
|
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
|
2020-10-08 13:53:58 +02:00
|
|
|
a.dexpreopter.classLoaderContexts = a.classLoaderContexts
|
2019-05-16 21:28:22 +02:00
|
|
|
a.dexpreopter.manifestFile = a.mergedManifestFile
|
2021-11-11 01:42:38 +01:00
|
|
|
a.dexpreopter.preventInstall = a.appProperties.PreventInstall
|
2019-05-16 21:28:22 +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
|
|
|
|
2021-09-15 04:34:04 +02:00
|
|
|
return a.dexJarFile.PathOrNil()
|
2019-01-23 01:40:58 +01:00
|
|
|
}
|
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 {
|
2020-07-06 23:15:24 +02:00
|
|
|
a.jniLibs = jniLibs
|
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")
|
2021-11-12 03:59:15 +01:00
|
|
|
a.installPathForJNISymbols = a.installPath(ctx)
|
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 ||
|
2020-10-10 02:25:15 +02:00
|
|
|
ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType == jni.target.Arch.ArchType {
|
2020-04-07 22:07:55 +02:00
|
|
|
a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
|
|
|
|
}
|
2020-03-26 22:01:48 +01:00
|
|
|
}
|
|
|
|
}
|
2020-07-06 23:15:24 +02:00
|
|
|
a.embeddedJniLibs = true
|
2018-10-03 07:03:40 +02:00
|
|
|
}
|
|
|
|
}
|
2019-01-23 01:40:58 +01:00
|
|
|
return jniJarFile
|
|
|
|
}
|
2018-10-03 07:03:40 +02:00
|
|
|
|
2020-07-06 23:15:24 +02:00
|
|
|
func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
|
|
|
|
var jniSymbols android.RuleBuilderInstalls
|
|
|
|
for _, jniLib := range a.jniLibs {
|
|
|
|
if jniLib.unstrippedFile != nil {
|
|
|
|
jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
|
|
|
|
From: jniLib.unstrippedFile,
|
|
|
|
To: filepath.Join(installPath, targetToJniDir(jniLib.target), jniLib.unstrippedFile.Base()),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return jniSymbols
|
|
|
|
}
|
|
|
|
|
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.
|
2020-09-14 12:43:17 +02:00
|
|
|
if child.Target().Os.Class == android.Host {
|
2019-06-18 02:40:56 +02:00
|
|
|
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()
|
2020-06-11 20:32:11 +02:00
|
|
|
allowed := ctx.Config().EnforceSystemCertificateAllowList()
|
2019-01-07 04:07:27 +01:00
|
|
|
|
2020-06-11 20:32:11 +02:00
|
|
|
if enforceSystemCert && !inList(m.Name(), allowed) {
|
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
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() {
|
|
|
|
a.hideApexVariantFromMake = true
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2020-10-08 13:53:58 +02:00
|
|
|
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
|
2020-11-03 16:55:11 +01:00
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
// Process all building blocks, from AAPT to certificates.
|
|
|
|
a.aaptBuildActions(ctx)
|
|
|
|
|
2020-08-19 17:32:54 +02:00
|
|
|
// The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
|
|
|
|
a.usesLibrary.freezeEnforceUsesLibraries()
|
|
|
|
|
|
|
|
// Add implicit SDK libraries to <uses-library> list.
|
2021-08-12 17:16:11 +02:00
|
|
|
requiredUsesLibs, optionalUsesLibs := a.classLoaderContexts.UsesLibs()
|
|
|
|
for _, usesLib := range requiredUsesLibs {
|
|
|
|
a.usesLibrary.addLib(usesLib, false)
|
|
|
|
}
|
|
|
|
for _, usesLib := range optionalUsesLibs {
|
|
|
|
a.usesLibrary.addLib(usesLib, true)
|
2020-08-19 17:32:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check that the <uses-library> list is coherent with the manifest.
|
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)
|
|
|
|
|
2020-06-03 05:09:13 +02:00
|
|
|
a.linter.mergedManifest = a.aapt.mergedManifestFile
|
|
|
|
a.linter.manifest = a.aapt.manifestPath
|
|
|
|
a.linter.resources = a.aapt.resourceFiles
|
2020-07-03 20:56:24 +02:00
|
|
|
a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
|
2020-06-03 05:09:13 +02:00
|
|
|
|
2020-11-03 16:55:11 +01:00
|
|
|
dexJarFile := a.dexBuildActions(ctx)
|
2019-01-23 01:40:58 +01:00
|
|
|
|
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-03-25 04:32:24 +01:00
|
|
|
v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
|
|
|
|
var v4SignatureFile android.WritablePath = nil
|
|
|
|
if v4SigningRequested {
|
|
|
|
v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
|
|
|
|
}
|
2020-05-07 22:24:05 +02:00
|
|
|
var lineageFile android.Path
|
|
|
|
if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
|
|
|
|
lineageFile = android.PathForModuleSrc(ctx, lineage)
|
|
|
|
}
|
2020-05-07 22:24:05 +02:00
|
|
|
CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile)
|
2017-11-23 01:19:37 +01:00
|
|
|
a.outputFile = packageFile
|
2020-03-25 04:32:24 +01:00
|
|
|
if v4SigningRequested {
|
|
|
|
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
|
|
|
|
}
|
2017-11-23 01:19:37 +01:00
|
|
|
|
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-03-25 04:32:24 +01:00
|
|
|
if v4SigningRequested {
|
|
|
|
v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
|
|
|
|
}
|
2020-05-07 22:24:05 +02:00
|
|
|
CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile)
|
2019-03-20 00:03:11 +01:00
|
|
|
a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
|
2020-03-25 04:32:24 +01:00
|
|
|
if v4SigningRequested {
|
|
|
|
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
|
|
|
|
}
|
2019-03-20 00:03:11 +01:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
|
|
|
|
2019-01-23 01:40:58 +01:00
|
|
|
// Install the app package.
|
2021-11-11 01:42:38 +01:00
|
|
|
if (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() &&
|
|
|
|
!a.appProperties.PreventInstall {
|
|
|
|
|
2021-11-03 22:08:20 +01:00
|
|
|
var extraInstalledPaths android.Paths
|
2019-11-13 07:01:01 +01:00
|
|
|
for _, extra := range a.extraOutputFiles {
|
2021-11-03 22:08:20 +01:00
|
|
|
installed := ctx.InstallFile(a.installDir, extra.Base(), extra)
|
|
|
|
extraInstalledPaths = append(extraInstalledPaths, installed)
|
2019-11-13 07:01:01 +01:00
|
|
|
}
|
2021-11-03 22:08:20 +01:00
|
|
|
ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
|
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 {
|
2021-04-02 01:45:46 +02:00
|
|
|
SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
|
|
|
|
MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
|
2020-05-13 20:05:02 +02:00
|
|
|
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 {
|
2021-04-02 01:45:46 +02:00
|
|
|
checkNativeSdkVersion = app.SdkVersion(ctx).Specified() &&
|
|
|
|
app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx)
|
2020-05-13 20:05:02 +02:00
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
2020-07-29 21:59:39 +02:00
|
|
|
if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
|
2018-10-03 07:03:40 +02:00
|
|
|
if dep, ok := module.(*cc.Module); ok {
|
2020-10-30 04:47:22 +01:00
|
|
|
if dep.IsNdk(ctx.Config()) || dep.IsStubs() {
|
2019-12-18 01:46:18 +01:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-10-03 07:03:40 +02:00
|
|
|
lib := dep.OutputFile()
|
2021-09-15 02:32:49 +02:00
|
|
|
if lib.Valid() {
|
|
|
|
path := lib.Path()
|
|
|
|
if seenModulePaths[path.String()] {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
seenModulePaths[path.String()] = true
|
2019-12-18 01:46:18 +01:00
|
|
|
|
2021-09-15 02:32:49 +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
|
|
|
jniLibs = append(jniLibs, jniLib{
|
2020-07-06 23:15:24 +02:00
|
|
|
name: ctx.OtherModuleName(module),
|
|
|
|
path: path,
|
|
|
|
target: module.Target(),
|
|
|
|
coverageFile: dep.CoverageOutputFile(),
|
|
|
|
unstrippedFile: dep.UnstrippedOutputFile(),
|
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-15 04:03:39 +02:00
|
|
|
func (a *AndroidApp) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
|
2020-04-27 20:05:28 +02:00
|
|
|
ctx.WalkDeps(func(child, parent android.Module) bool {
|
|
|
|
isExternal := !a.DepIsInSameApex(ctx, child)
|
|
|
|
if am, ok := child.(android.ApexModule); ok {
|
2020-04-15 04:03:39 +02:00
|
|
|
if !do(ctx, parent, am, isExternal) {
|
|
|
|
return false
|
|
|
|
}
|
2020-04-27 20:05:28 +02:00
|
|
|
}
|
|
|
|
return !isExternal
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
|
|
|
|
if ctx.Host() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
depsInfo := android.DepNameToDepInfoMap{}
|
2020-04-15 04:03:39 +02:00
|
|
|
a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
|
2020-04-27 20:05:28 +02:00
|
|
|
depName := to.Name()
|
2021-03-11 19:03:42 +01:00
|
|
|
|
|
|
|
// Skip dependencies that are only available to APEXes; they are developed with updatability
|
|
|
|
// in mind and don't need manual approval.
|
|
|
|
if to.(android.ApexModule).NotAvailableForPlatform() {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2020-04-27 20:05:28 +02:00
|
|
|
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)"
|
2021-04-02 01:45:46 +02:00
|
|
|
if m, ok := to.(interface {
|
|
|
|
MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
|
|
|
|
}); ok {
|
|
|
|
if v := m.MinSdkVersion(ctx); !v.ApiLevel.IsNone() {
|
|
|
|
toMinSdkVersion = v.ApiLevel.String()
|
2020-04-27 20:05:28 +02:00
|
|
|
}
|
2021-04-02 01:45:46 +02:00
|
|
|
} else if m, ok := to.(interface{ MinSdkVersion() string }); ok {
|
|
|
|
// TODO(b/175678607) eliminate the use of MinSdkVersion returning
|
|
|
|
// string
|
|
|
|
if v := m.MinSdkVersion(); v != "" {
|
2021-03-29 13:11:58 +02:00
|
|
|
toMinSdkVersion = v
|
|
|
|
}
|
2020-04-27 20:05:28 +02:00
|
|
|
}
|
|
|
|
depsInfo[depName] = android.ApexModuleDepInfo{
|
|
|
|
To: depName,
|
|
|
|
From: []string{from.Name()},
|
|
|
|
IsExternal: externalDep,
|
|
|
|
MinSdkVersion: toMinSdkVersion,
|
|
|
|
}
|
|
|
|
}
|
2020-04-15 04:03:39 +02:00
|
|
|
return true
|
2020-04-27 20:05:28 +02:00
|
|
|
})
|
|
|
|
|
2021-04-02 01:45:46 +02:00
|
|
|
a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depsInfo)
|
2020-04-27 20:05:28 +02:00
|
|
|
}
|
|
|
|
|
2020-04-28 15:57:42 +02:00
|
|
|
func (a *AndroidApp) Updatable() bool {
|
2020-09-16 03:30:11 +02:00
|
|
|
return Bool(a.appProperties.Updatable)
|
2020-04-28 15:57:42 +02:00
|
|
|
}
|
|
|
|
|
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
|
2020-08-13 20:37:22 +02:00
|
|
|
case ".export-package.apk":
|
|
|
|
return []android.Path{a.exportPackage}, nil
|
2019-08-19 07:56:02 +02:00
|
|
|
}
|
|
|
|
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 {
|
2020-06-17 02:51:46 +02:00
|
|
|
return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
|
2020-03-26 22:01:48 +01:00
|
|
|
}
|
|
|
|
|
2021-04-01 15:49:36 +02:00
|
|
|
func (a *AndroidApp) SetPreventInstall() {
|
2020-03-26 22:01:48 +01:00
|
|
|
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{}
|
|
|
|
|
2020-07-10 00:16:41 +02:00
|
|
|
module.Module.dexProperties.Optimize.EnabledByDefault = true
|
|
|
|
module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
|
2017-12-28 21:23:20 +01:00
|
|
|
|
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
|
|
|
|
2020-06-16 01:09:53 +02:00
|
|
|
module.addHostAndDeviceProperties()
|
2017-06-24 00:06:31 +02:00
|
|
|
module.AddProperties(
|
2018-03-28 23:58:31 +02:00
|
|
|
&module.aaptProperties,
|
2019-03-01 00:35:54 +01:00
|
|
|
&module.appProperties,
|
2020-09-01 18:33:48 +02:00
|
|
|
&module.overridableAppProperties)
|
2017-06-24 00:06:31 +02:00
|
|
|
|
2021-01-05 13:04:17 +01:00
|
|
|
module.usesLibrary.enforce = true
|
|
|
|
|
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)
|
2021-11-01 20:32:43 +01:00
|
|
|
android.InitBazelModule(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
|
|
|
|
2020-08-15 21:24:26 +02:00
|
|
|
testConfig android.Path
|
|
|
|
extraTestConfigs android.Paths
|
|
|
|
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) {
|
2020-04-30 08:57:06 +02:00
|
|
|
var configs []tradefed.Config
|
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-04-30 08:57:06 +02:00
|
|
|
for _, module := range a.testProperties.Test_mainline_modules {
|
|
|
|
configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
|
|
|
|
}
|
|
|
|
|
2020-01-14 19:27:18 +01:00
|
|
|
testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
|
2020-04-30 08:57:06 +02:00
|
|
|
a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config, configs)
|
2020-01-14 19:27:18 +01:00
|
|
|
a.testConfig = a.FixTestConfig(ctx, testConfig)
|
2020-08-15 21:24:26 +02:00
|
|
|
a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
|
2020-01-14 19:27:18 +01:00
|
|
|
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")
|
2020-11-17 02:32:30 +01:00
|
|
|
rule := android.NewRuleBuilder(pctx, ctx)
|
|
|
|
command := rule.Command().BuiltTool("test_config_fixer").Input(testConfig).Output(fixedConfig)
|
2020-01-14 19:27:18 +01:00
|
|
|
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 {
|
2020-11-17 02:32:30 +01:00
|
|
|
rule.Build("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{}
|
|
|
|
|
2020-07-10 00:16:41 +02:00
|
|
|
module.Module.dexProperties.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
|
2020-06-03 05:09:13 +02:00
|
|
|
module.Module.linter.test = true
|
2018-05-22 20:11:52 +02:00
|
|
|
|
2020-06-16 01:09:53 +02:00
|
|
|
module.addHostAndDeviceProperties()
|
2018-05-22 20:11:52 +02:00
|
|
|
module.AddProperties(
|
|
|
|
&module.aaptProperties,
|
|
|
|
&module.appProperties,
|
2018-07-17 02:21:19 +02:00
|
|
|
&module.appTestProperties,
|
2019-03-01 00:35:54 +01:00
|
|
|
&module.overridableAppProperties,
|
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
|
2021-09-25 00:47:17 +02:00
|
|
|
|
|
|
|
// Install the test into a folder named for the module in all test suites.
|
|
|
|
Per_testcase_directory *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{}
|
|
|
|
|
2020-07-10 00:16:41 +02:00
|
|
|
module.Module.dexProperties.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
|
2020-06-03 05:09:13 +02:00
|
|
|
module.Module.linter.test = true
|
2018-10-05 00:22:03 +02:00
|
|
|
|
2020-06-16 01:09:53 +02:00
|
|
|
module.addHostAndDeviceProperties()
|
2018-10-05 00:22:03 +02:00
|
|
|
module.AddProperties(
|
|
|
|
&module.aaptProperties,
|
|
|
|
&module.appProperties,
|
2019-03-01 00:35:54 +01:00
|
|
|
&module.appTestHelperAppProperties,
|
2020-09-01 18:33:48 +02:00
|
|
|
&module.overridableAppProperties)
|
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
|
2021-07-27 07:34:59 +02:00
|
|
|
android.BazelModuleBase
|
|
|
|
|
2018-10-05 00:21:03 +02:00
|
|
|
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)
|
2021-07-27 07:34:59 +02:00
|
|
|
android.InitBazelModule(module)
|
2018-10-05 00:21:03 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-06-05 19:27:23 +02:00
|
|
|
func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
|
2019-03-01 00:35:54 +01:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2020-06-05 19:27:23 +02:00
|
|
|
func (i *OverrideAndroidTest) GenerateAndroidBuildActions(_ android.ModuleContext) {
|
2019-06-06 17:45:58 +02:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
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
|
2020-09-01 18:33:48 +02:00
|
|
|
|
2020-09-09 15:08:23 +02:00
|
|
|
// Optional name of the <uses-library> provided by this module. This is needed for non-SDK
|
|
|
|
// libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
|
|
|
|
// normally is the same as the module name, but there are exceptions.
|
|
|
|
Provides_uses_lib *string
|
2019-05-16 21:28:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2021-01-05 13:04:17 +01:00
|
|
|
|
|
|
|
// Whether to enforce verify_uses_library check.
|
|
|
|
enforce bool
|
2019-05-16 21:28:22 +02:00
|
|
|
}
|
|
|
|
|
2020-08-19 17:32:54 +02:00
|
|
|
func (u *usesLibrary) addLib(lib string, optional bool) {
|
|
|
|
if !android.InList(lib, u.usesLibraryProperties.Uses_libs) && !android.InList(lib, u.usesLibraryProperties.Optional_uses_libs) {
|
|
|
|
if optional {
|
|
|
|
u.usesLibraryProperties.Optional_uses_libs = append(u.usesLibraryProperties.Optional_uses_libs, lib)
|
|
|
|
} else {
|
|
|
|
u.usesLibraryProperties.Uses_libs = append(u.usesLibraryProperties.Uses_libs, lib)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-07 11:44:37 +02:00
|
|
|
func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) {
|
2021-06-08 04:35:00 +02:00
|
|
|
if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
|
2021-08-20 16:39:12 +02:00
|
|
|
reqTag := makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false, false)
|
|
|
|
ctx.AddVariationDependencies(nil, reqTag, u.usesLibraryProperties.Uses_libs...)
|
|
|
|
|
|
|
|
optTag := makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true, false)
|
|
|
|
ctx.AddVariationDependencies(nil, optTag, 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 {
|
2021-08-20 16:39:12 +02:00
|
|
|
// Add implicit <uses-library> dependencies on compatibility libraries. Some of them are
|
|
|
|
// optional, and some required --- this depends on the most common usage of the library
|
|
|
|
// and may be wrong for some apps (they need explicit `uses_libs`/`optional_uses_libs`).
|
|
|
|
|
|
|
|
compat28OptTag := makeUsesLibraryDependencyTag(28, true, true)
|
|
|
|
ctx.AddVariationDependencies(nil, compat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
|
|
|
|
|
|
|
|
compat29ReqTag := makeUsesLibraryDependencyTag(29, false, true)
|
|
|
|
ctx.AddVariationDependencies(nil, compat29ReqTag, dexpreopt.CompatUsesLibs29...)
|
|
|
|
|
|
|
|
compat30OptTag := makeUsesLibraryDependencyTag(30, true, true)
|
|
|
|
ctx.AddVariationDependencies(nil, compat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
|
2019-06-07 22:18:09 +02:00
|
|
|
}
|
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
|
|
|
|
}
|
|
|
|
|
2021-02-26 12:38:21 +01:00
|
|
|
// Helper function to replace string in a list.
|
|
|
|
func replaceInList(list []string, oldstr, newstr string) {
|
|
|
|
for i, str := range list {
|
|
|
|
if str == oldstr {
|
|
|
|
list[i] = newstr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-15 15:59:34 +02:00
|
|
|
// Returns a map of module names of shared library dependencies to the paths to their dex jars on
|
|
|
|
// host and on device.
|
2020-11-03 16:15:46 +01:00
|
|
|
func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
|
|
|
|
clcMap := make(dexpreopt.ClassLoaderContextMap)
|
2021-07-15 15:59:34 +02:00
|
|
|
|
|
|
|
// Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
|
|
|
|
// UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
|
|
|
|
if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
|
|
|
|
return clcMap
|
2019-05-16 21:28:22 +02:00
|
|
|
}
|
|
|
|
|
2021-07-15 15:59:34 +02:00
|
|
|
ctx.VisitDirectDeps(func(m android.Module) {
|
|
|
|
tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
|
|
|
|
if !isUsesLibTag {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-07-15 16:05:48 +02:00
|
|
|
dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
|
2021-07-15 15:59:34 +02:00
|
|
|
|
2021-07-15 15:34:40 +02:00
|
|
|
// Skip stub libraries. A dependency on the implementation library has been added earlier,
|
|
|
|
// so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
|
|
|
|
// from implementation libraries by their name, which is different as it has a suffix.
|
|
|
|
if comp, ok := m.(SdkLibraryComponentDependency); ok {
|
|
|
|
if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-15 15:59:34 +02:00
|
|
|
if lib, ok := m.(UsesLibraryDependency); ok {
|
2021-07-15 16:05:48 +02:00
|
|
|
libName := dep
|
2021-07-15 15:59:34 +02:00
|
|
|
if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
|
2021-07-15 16:05:48 +02:00
|
|
|
libName = *ulib.ProvidesUsesLib()
|
2021-07-15 15:59:34 +02:00
|
|
|
// Replace module name with library name in `uses_libs`/`optional_uses_libs` in
|
|
|
|
// order to pass verify_uses_libraries check (which compares these properties
|
|
|
|
// against library names written in the manifest).
|
|
|
|
replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName)
|
|
|
|
replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
|
|
|
|
}
|
2021-08-20 16:39:12 +02:00
|
|
|
clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, tag.implicit,
|
2021-09-15 04:34:04 +02:00
|
|
|
lib.DexJarBuildPath().PathOrNil(), lib.DexJarInstallPath(),
|
|
|
|
lib.ClassLoaderContexts())
|
2021-07-15 15:59:34 +02:00
|
|
|
} else if ctx.Config().AllowMissingDependencies() {
|
|
|
|
ctx.AddMissingDependencies([]string{dep})
|
|
|
|
} else {
|
|
|
|
ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
|
|
|
|
}
|
|
|
|
})
|
2020-11-03 16:15:46 +01:00
|
|
|
return clcMap
|
2019-05-16 21:28:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2021-01-05 13:04:17 +01:00
|
|
|
return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
|
2019-05-16 21:28:22 +02:00
|
|
|
}
|
|
|
|
|
2020-08-19 17:32:54 +02:00
|
|
|
// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
|
|
|
|
func (u *usesLibrary) freezeEnforceUsesLibraries() {
|
|
|
|
enforce := u.enforceUsesLibraries()
|
|
|
|
u.usesLibraryProperties.Enforce_uses_libs = &enforce
|
|
|
|
}
|
|
|
|
|
2021-03-03 17:38:37 +01:00
|
|
|
// verifyUsesLibraries checks the <uses-library> tags in the manifest against the ones specified
|
|
|
|
// in the `uses_libs`/`optional_uses_libs` properties. The input can be either an XML manifest, or
|
|
|
|
// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
|
|
|
|
// extension: APKs are supposed to end with '.apk').
|
|
|
|
func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
|
2021-03-16 16:34:50 +01:00
|
|
|
outputFile android.WritablePath) android.Path {
|
2021-03-03 17:38:37 +01:00
|
|
|
|
Add non-fatal mode for verify_uses_libraries check.
The new mode is enabled with environment variable
RELAX_USES_LIBRARY_CHECK. If the variable is set to true, then a
verify_uses_libraries check failure does not fail the build, instead it
sets a special compiler filter "extract" for dexpreopt, which means that
the DEX file will be extracted, but it won't be compiled to native code.
Class loader context will be set to empty in this case (not &, as it is
going to be deprecated soon).
If the variable RELAX_USES_LIBRARY_CHECK is unset or set to something
other than "true", then the old behaviour of the verify_uses_libraries
check is preserved.
The intended use case for this flag is to have a smoother migration path
for the Java modules that need to add <uses-library> information in
the build files. The flag allows to quickly silence build errors. This
flag should be used with caution and only as a temporary measure, as it
masks real errors and affects performance.
verify_uses_libraries check is reworked so that it writes the error
message to a status file (which is used instead of the former timestamp
file). Currently the stored error message is not used, but it may be
used later to produce a warning. Dexpreopt command checks if the status
file exists and is nonempty; if that is the case, then compiler filter
is set to "extract".
Bug: 132357300
Test: Manually add some mismatch between the libraries in the Android.bp
and Android.mk files for dexpreopted apps, build with
RELAX_USES_LIBRARY_CHECK=true and obsserve that the build doesn't
fail and they are compiled with compiler-filter "extract".
Unset RELAX_USES_LIBRARY_CHECK and observe that the build fails.
Change-Id: Ibb5d993a25b1df1d2e70b7d5aafc6997f9d64e67
2021-02-17 17:23:28 +01:00
|
|
|
statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
|
2019-05-16 21:28:22 +02:00
|
|
|
|
2021-03-04 13:37:50 +01:00
|
|
|
// Disable verify_uses_libraries check if dexpreopt is globally disabled. Without dexpreopt the
|
|
|
|
// check is not necessary, and although it is good to have, it is difficult to maintain on
|
|
|
|
// non-linux build platforms where dexpreopt is generally disabled (the check may fail due to
|
|
|
|
// various unrelated reasons, such as a failure to get manifest from an APK).
|
2021-03-29 15:57:34 +02:00
|
|
|
global := dexpreopt.GetGlobalConfig(ctx)
|
|
|
|
if global.DisablePreopt || global.OnlyPreoptBootImageAndSystemServer {
|
2021-03-16 16:34:50 +01:00
|
|
|
return inputFile
|
2021-03-04 13:37:50 +01:00
|
|
|
}
|
|
|
|
|
2020-11-17 02:32:30 +01:00
|
|
|
rule := android.NewRuleBuilder(pctx, ctx)
|
|
|
|
cmd := rule.Command().BuiltTool("manifest_check").
|
2019-05-16 21:28:22 +02:00
|
|
|
Flag("--enforce-uses-libraries").
|
2021-03-03 17:38:37 +01:00
|
|
|
Input(inputFile).
|
Add non-fatal mode for verify_uses_libraries check.
The new mode is enabled with environment variable
RELAX_USES_LIBRARY_CHECK. If the variable is set to true, then a
verify_uses_libraries check failure does not fail the build, instead it
sets a special compiler filter "extract" for dexpreopt, which means that
the DEX file will be extracted, but it won't be compiled to native code.
Class loader context will be set to empty in this case (not &, as it is
going to be deprecated soon).
If the variable RELAX_USES_LIBRARY_CHECK is unset or set to something
other than "true", then the old behaviour of the verify_uses_libraries
check is preserved.
The intended use case for this flag is to have a smoother migration path
for the Java modules that need to add <uses-library> information in
the build files. The flag allows to quickly silence build errors. This
flag should be used with caution and only as a temporary measure, as it
masks real errors and affects performance.
verify_uses_libraries check is reworked so that it writes the error
message to a status file (which is used instead of the former timestamp
file). Currently the stored error message is not used, but it may be
used later to produce a warning. Dexpreopt command checks if the status
file exists and is nonempty; if that is the case, then compiler filter
is set to "extract".
Bug: 132357300
Test: Manually add some mismatch between the libraries in the Android.bp
and Android.mk files for dexpreopted apps, build with
RELAX_USES_LIBRARY_CHECK=true and obsserve that the build doesn't
fail and they are compiled with compiler-filter "extract".
Unset RELAX_USES_LIBRARY_CHECK and observe that the build fails.
Change-Id: Ibb5d993a25b1df1d2e70b7d5aafc6997f9d64e67
2021-02-17 17:23:28 +01:00
|
|
|
FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
|
2021-03-03 17:38:37 +01:00
|
|
|
FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt"))
|
|
|
|
|
|
|
|
if outputFile != nil {
|
|
|
|
cmd.FlagWithOutput("-o ", outputFile)
|
|
|
|
}
|
2019-05-16 21:28:22 +02:00
|
|
|
|
Add non-fatal mode for verify_uses_libraries check.
The new mode is enabled with environment variable
RELAX_USES_LIBRARY_CHECK. If the variable is set to true, then a
verify_uses_libraries check failure does not fail the build, instead it
sets a special compiler filter "extract" for dexpreopt, which means that
the DEX file will be extracted, but it won't be compiled to native code.
Class loader context will be set to empty in this case (not &, as it is
going to be deprecated soon).
If the variable RELAX_USES_LIBRARY_CHECK is unset or set to something
other than "true", then the old behaviour of the verify_uses_libraries
check is preserved.
The intended use case for this flag is to have a smoother migration path
for the Java modules that need to add <uses-library> information in
the build files. The flag allows to quickly silence build errors. This
flag should be used with caution and only as a temporary measure, as it
masks real errors and affects performance.
verify_uses_libraries check is reworked so that it writes the error
message to a status file (which is used instead of the former timestamp
file). Currently the stored error message is not used, but it may be
used later to produce a warning. Dexpreopt command checks if the status
file exists and is nonempty; if that is the case, then compiler filter
is set to "extract".
Bug: 132357300
Test: Manually add some mismatch between the libraries in the Android.bp
and Android.mk files for dexpreopted apps, build with
RELAX_USES_LIBRARY_CHECK=true and obsserve that the build doesn't
fail and they are compiled with compiler-filter "extract".
Unset RELAX_USES_LIBRARY_CHECK and observe that the build fails.
Change-Id: Ibb5d993a25b1df1d2e70b7d5aafc6997f9d64e67
2021-02-17 17:23:28 +01:00
|
|
|
if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
|
|
|
|
cmd.Flag("--enforce-uses-libraries-relax")
|
|
|
|
}
|
|
|
|
|
2019-05-16 21:28:22 +02:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2020-11-17 02:32:30 +01:00
|
|
|
rule.Build("verify_uses_libraries", "verify <uses-library>")
|
2021-03-16 16:34:50 +01:00
|
|
|
return outputFile
|
2021-03-03 17:38:37 +01:00
|
|
|
}
|
2019-05-16 21:28:22 +02:00
|
|
|
|
2021-03-03 17:38:37 +01:00
|
|
|
// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
|
|
|
|
// the build system and 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")
|
2021-03-16 16:34:50 +01:00
|
|
|
return u.verifyUsesLibraries(ctx, manifest, outputFile)
|
2019-05-16 21:28:22 +02:00
|
|
|
}
|
|
|
|
|
2021-03-03 17:38:37 +01:00
|
|
|
// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
|
|
|
|
// system and returns the path to a copy of the APK.
|
2019-05-16 21:28:22 +02:00
|
|
|
func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path {
|
2021-03-03 17:38:37 +01:00
|
|
|
u.verifyUsesLibraries(ctx, apk, nil) // for APKs manifest_check does not write output file
|
2019-05-16 21:28:22 +02:00
|
|
|
outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base())
|
|
|
|
return outputFile
|
|
|
|
}
|
2021-07-28 12:21:31 +02:00
|
|
|
|
|
|
|
// For Bazel / bp2build
|
|
|
|
|
|
|
|
type bazelAndroidAppCertificateAttributes struct {
|
|
|
|
Certificate string
|
|
|
|
}
|
|
|
|
|
2021-11-01 20:32:43 +01:00
|
|
|
func (m *AndroidAppCertificate) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
|
|
|
|
androidAppCertificateBp2Build(ctx, m)
|
2021-07-28 12:21:31 +02:00
|
|
|
}
|
|
|
|
|
2021-11-01 20:32:43 +01:00
|
|
|
func androidAppCertificateBp2Build(ctx android.TopDownMutatorContext, module *AndroidAppCertificate) {
|
2021-07-28 12:21:31 +02:00
|
|
|
var certificate string
|
|
|
|
if module.properties.Certificate != nil {
|
|
|
|
certificate = *module.properties.Certificate
|
|
|
|
}
|
|
|
|
|
|
|
|
attrs := &bazelAndroidAppCertificateAttributes{
|
|
|
|
Certificate: certificate,
|
|
|
|
}
|
|
|
|
|
|
|
|
props := bazel.BazelTargetModuleProperties{
|
|
|
|
Rule_class: "android_app_certificate",
|
|
|
|
Bzl_load_location: "//build/bazel/rules:android_app_certificate.bzl",
|
|
|
|
}
|
|
|
|
|
2021-08-31 22:30:36 +02:00
|
|
|
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
|
2021-07-28 12:21:31 +02:00
|
|
|
}
|
Initial bp2build converter for android_app.
The only supported attributes at this point are:
- srcs
- manifest
- package_name
- resource_dirs
as they most easily map to bazel's android_binary's srcs, manifest, custom_package, and resource_files respectively.
Allow-listing all apps that use these fields, along with sdk_version and dex_preopt. The latter 2 are ignored by the converter,
- sdk_version because we're currently relying on a single pre-built SDK,
- dex_preopt because,
1. though it is not supported in Bazel builds yet, it doesn't prevent the apps from building, and
2. the apps being converted only use the dex_preopt attribute to disable dex_preopt, which is what is happening anyway.
Change-Id: I4a4f771eeb8f60a1cd4844b2ac1ce3df7c070e73
Test: ./build/bazel/scripts/run_presubmits.sh
Bug: 198224074
Bug: 203688791
2021-10-29 16:52:59 +02:00
|
|
|
|
|
|
|
type bazelAndroidAppAttributes struct {
|
|
|
|
Srcs bazel.LabelListAttribute
|
|
|
|
Manifest bazel.Label
|
|
|
|
Custom_package *string
|
|
|
|
Resource_files bazel.LabelListAttribute
|
|
|
|
}
|
|
|
|
|
2021-11-01 20:32:43 +01:00
|
|
|
// ConvertWithBp2build is used to convert android_app to Bazel.
|
|
|
|
func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
|
Initial bp2build converter for android_app.
The only supported attributes at this point are:
- srcs
- manifest
- package_name
- resource_dirs
as they most easily map to bazel's android_binary's srcs, manifest, custom_package, and resource_files respectively.
Allow-listing all apps that use these fields, along with sdk_version and dex_preopt. The latter 2 are ignored by the converter,
- sdk_version because we're currently relying on a single pre-built SDK,
- dex_preopt because,
1. though it is not supported in Bazel builds yet, it doesn't prevent the apps from building, and
2. the apps being converted only use the dex_preopt attribute to disable dex_preopt, which is what is happening anyway.
Change-Id: I4a4f771eeb8f60a1cd4844b2ac1ce3df7c070e73
Test: ./build/bazel/scripts/run_presubmits.sh
Bug: 198224074
Bug: 203688791
2021-10-29 16:52:59 +02:00
|
|
|
//TODO(b/209577426): Support multiple arch variants
|
|
|
|
srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Srcs, a.properties.Exclude_srcs))
|
|
|
|
|
|
|
|
manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
|
|
|
|
|
|
|
|
resourceFiles := bazel.LabelList{
|
|
|
|
Includes: []bazel.Label{},
|
|
|
|
}
|
|
|
|
for _, dir := range android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") {
|
|
|
|
files := android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir))
|
|
|
|
resourceFiles.Includes = append(resourceFiles.Includes, files...)
|
|
|
|
}
|
|
|
|
|
|
|
|
attrs := &bazelAndroidAppAttributes{
|
|
|
|
Srcs: srcs,
|
|
|
|
Manifest: android.BazelLabelForModuleSrcSingle(ctx, manifest),
|
|
|
|
// TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
|
|
|
|
Custom_package: a.overridableAppProperties.Package_name,
|
|
|
|
Resource_files: bazel.MakeLabelListAttribute(resourceFiles),
|
|
|
|
}
|
|
|
|
props := bazel.BazelTargetModuleProperties{Rule_class: "android_binary",
|
|
|
|
Bzl_load_location: "@rules_android//rules:rules.bzl"}
|
|
|
|
|
|
|
|
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, attrs)
|
|
|
|
|
|
|
|
}
|