123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- // Copyright 2020 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 implementation for android_app_set.
- import (
- "strconv"
- "strings"
- "github.com/google/blueprint/proptools"
- "android/soong/android"
- )
- func init() {
- RegisterAppSetBuildComponents(android.InitRegistrationContext)
- }
- func RegisterAppSetBuildComponents(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("android_app_set", AndroidAppSetFactory)
- }
- type AndroidAppSetProperties struct {
- // APK Set path
- Set *string
- // 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
- // APKs in this set use prerelease SDK version
- Prerelease *bool
- // Names of modules to be overridden. Listed modules can only be other apps
- // (in Make or Soong).
- Overrides []string
- }
- type AndroidAppSet struct {
- android.ModuleBase
- android.DefaultableModuleBase
- prebuilt android.Prebuilt
- properties AndroidAppSetProperties
- packedOutput android.WritablePath
- primaryOutput android.WritablePath
- apkcertsFile android.ModuleOutPath
- }
- func (as *AndroidAppSet) Name() string {
- return as.prebuilt.Name(as.ModuleBase.Name())
- }
- func (as *AndroidAppSet) IsInstallable() bool {
- return true
- }
- func (as *AndroidAppSet) Prebuilt() *android.Prebuilt {
- return &as.prebuilt
- }
- func (as *AndroidAppSet) Privileged() bool {
- return Bool(as.properties.Privileged)
- }
- func (as *AndroidAppSet) OutputFile() android.Path {
- return as.primaryOutput
- }
- func (as *AndroidAppSet) PackedAdditionalOutputs() android.Path {
- return as.packedOutput
- }
- func (as *AndroidAppSet) APKCertsFile() android.Path {
- return as.apkcertsFile
- }
- var TargetCpuAbi = map[string]string{
- "arm": "ARMEABI_V7A",
- "arm64": "ARM64_V8A",
- // TODO: use "RISCV64" when that is supported in bundles
- "riscv64": "ARM64_V8A",
- "x86": "X86",
- "x86_64": "X86_64",
- }
- func SupportedAbis(ctx android.ModuleContext, excludeNativeBridgeAbis bool) []string {
- abiName := func(targetIdx int, deviceArch string) string {
- if abi, found := TargetCpuAbi[deviceArch]; found {
- return abi
- }
- ctx.ModuleErrorf("Target %d has invalid Arch: %s", targetIdx, deviceArch)
- return "BAD_ABI"
- }
- var result []string
- for i, target := range ctx.Config().Targets[android.Android] {
- if target.NativeBridge == android.NativeBridgeEnabled && excludeNativeBridgeAbis {
- continue
- }
- result = append(result, abiName(i, target.Arch.ArchType.String()))
- }
- return result
- }
- func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
- as.primaryOutput = android.PathForModuleOut(ctx, as.BaseModuleName()+".apk")
- as.apkcertsFile = android.PathForModuleOut(ctx, "apkcerts.txt")
- // We are assuming here that the install file in the APK
- // set has `.apk` suffix. If it doesn't the build will fail.
- // APK sets containing APEX files are handled elsewhere.
- screenDensities := "all"
- if dpis := ctx.Config().ProductAAPTPrebuiltDPI(); len(dpis) > 0 {
- screenDensities = strings.ToUpper(strings.Join(dpis, ","))
- }
- // TODO(asmundak): handle locales.
- // TODO(asmundak): do we support device features
- ctx.Build(pctx,
- android.BuildParams{
- Rule: extractMatchingApks,
- Description: "Extract APKs from APK set",
- Output: as.primaryOutput,
- ImplicitOutputs: android.WritablePaths{as.packedOutput, as.apkcertsFile},
- Inputs: android.Paths{as.prebuilt.SingleSourcePath(ctx)},
- Args: map[string]string{
- "abis": strings.Join(SupportedAbis(ctx, false), ","),
- "allow-prereleased": strconv.FormatBool(proptools.Bool(as.properties.Prerelease)),
- "screen-densities": screenDensities,
- "sdk-version": ctx.Config().PlatformSdkVersion().String(),
- "skip-sdk-check": strconv.FormatBool(ctx.Config().IsEnvTrue("SOONG_SKIP_APPSET_SDK_CHECK")),
- "stem": as.BaseModuleName(),
- "apkcerts": as.apkcertsFile.String(),
- "partition": as.PartitionTag(ctx.DeviceConfig()),
- "zip": as.packedOutput.String(),
- },
- })
- var installDir android.InstallPath
- if as.Privileged() {
- installDir = android.PathForModuleInstall(ctx, "priv-app", as.BaseModuleName())
- } else {
- installDir = android.PathForModuleInstall(ctx, "app", as.BaseModuleName())
- }
- ctx.InstallFileWithExtraFilesZip(installDir, as.BaseModuleName()+".apk", as.primaryOutput, as.packedOutput)
- }
- func (as *AndroidAppSet) InstallBypassMake() bool { return true }
- // android_app_set extracts a set of APKs based on the target device
- // configuration and installs this set as "split APKs".
- // The extracted set always contains an APK whose name is
- // _module_name_.apk and every split APK matching target device.
- // The extraction of the density-specific splits depends on
- // PRODUCT_AAPT_PREBUILT_DPI variable. If present (its value should
- // be a list density names: LDPI, MDPI, HDPI, etc.), only listed
- // splits will be extracted. Otherwise all density-specific splits
- // will be extracted.
- func AndroidAppSetFactory() android.Module {
- module := &AndroidAppSet{}
- module.AddProperties(&module.properties)
- InitJavaModule(module, android.DeviceSupported)
- android.InitSingleSourcePrebuiltModule(module, &module.properties, "Set")
- return module
- }
|