diff options
Diffstat (limited to 'java/app_set.go')
-rw-r--r-- | java/app_set.go | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/java/app_set.go b/java/app_set.go new file mode 100644 index 000000000..6b25638da --- /dev/null +++ b/java/app_set.go @@ -0,0 +1,162 @@ +// 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 + installFile string + 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.packedOutput +} + +func (as *AndroidAppSet) InstallFile() string { + return as.installFile +} + +func (as *AndroidAppSet) APKCertsFile() android.Path { + return as.apkcertsFile +} + +var TargetCpuAbi = map[string]string{ + "arm": "ARMEABI_V7A", + "arm64": "ARM64_V8A", + "x86": "X86", + "x86_64": "X86_64", +} + +func SupportedAbis(ctx android.ModuleContext) []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] { + 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.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. + as.installFile = as.BaseModuleName() + ".apk" + 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.packedOutput, + ImplicitOutput: as.apkcertsFile, + Inputs: android.Paths{as.prebuilt.SingleSourcePath(ctx)}, + Args: map[string]string{ + "abis": strings.Join(SupportedAbis(ctx), ","), + "allow-prereleased": strconv.FormatBool(proptools.Bool(as.properties.Prerelease)), + "screen-densities": screenDensities, + "sdk-version": ctx.Config().PlatformSdkVersion().String(), + "stem": as.BaseModuleName(), + "apkcerts": as.apkcertsFile.String(), + "partition": as.PartitionTag(ctx.DeviceConfig()), + }, + }) +} + +// 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 +} |