xref: /aosp_15_r20/build/soong/java/app_set.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2020 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage java
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Worker// This file contains the module implementation for android_app_set.
18*333d2b36SAndroid Build Coastguard Worker
19*333d2b36SAndroid Build Coastguard Workerimport (
20*333d2b36SAndroid Build Coastguard Worker	"strconv"
21*333d2b36SAndroid Build Coastguard Worker	"strings"
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
24*333d2b36SAndroid Build Coastguard Worker
25*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
26*333d2b36SAndroid Build Coastguard Worker)
27*333d2b36SAndroid Build Coastguard Worker
28*333d2b36SAndroid Build Coastguard Workerfunc init() {
29*333d2b36SAndroid Build Coastguard Worker	RegisterAppSetBuildComponents(android.InitRegistrationContext)
30*333d2b36SAndroid Build Coastguard Worker}
31*333d2b36SAndroid Build Coastguard Worker
32*333d2b36SAndroid Build Coastguard Workerfunc RegisterAppSetBuildComponents(ctx android.RegistrationContext) {
33*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("android_app_set", AndroidAppSetFactory)
34*333d2b36SAndroid Build Coastguard Worker}
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard Workertype AndroidAppSetProperties struct {
37*333d2b36SAndroid Build Coastguard Worker	// APK Set path
38*333d2b36SAndroid Build Coastguard Worker	Set *string `android:"path"`
39*333d2b36SAndroid Build Coastguard Worker
40*333d2b36SAndroid Build Coastguard Worker	// Specifies that this app should be installed to the priv-app directory,
41*333d2b36SAndroid Build Coastguard Worker	// where the system will grant it additional privileges not available to
42*333d2b36SAndroid Build Coastguard Worker	// normal apps.
43*333d2b36SAndroid Build Coastguard Worker	Privileged *bool
44*333d2b36SAndroid Build Coastguard Worker
45*333d2b36SAndroid Build Coastguard Worker	// APKs in this set use prerelease SDK version
46*333d2b36SAndroid Build Coastguard Worker	Prerelease *bool
47*333d2b36SAndroid Build Coastguard Worker
48*333d2b36SAndroid Build Coastguard Worker	// Names of modules to be overridden. Listed modules can only be other apps
49*333d2b36SAndroid Build Coastguard Worker	//	(in Make or Soong).
50*333d2b36SAndroid Build Coastguard Worker	Overrides []string
51*333d2b36SAndroid Build Coastguard Worker
52*333d2b36SAndroid Build Coastguard Worker	// Path to the .prebuilt_info file of the prebuilt app.
53*333d2b36SAndroid Build Coastguard Worker	// In case of mainline modules, the .prebuilt_info file contains the build_id that was used
54*333d2b36SAndroid Build Coastguard Worker	// to generate the prebuilt.
55*333d2b36SAndroid Build Coastguard Worker	Prebuilt_info *string `android:"path"`
56*333d2b36SAndroid Build Coastguard Worker}
57*333d2b36SAndroid Build Coastguard Worker
58*333d2b36SAndroid Build Coastguard Workertype AndroidAppSet struct {
59*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
60*333d2b36SAndroid Build Coastguard Worker	android.DefaultableModuleBase
61*333d2b36SAndroid Build Coastguard Worker	prebuilt android.Prebuilt
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Worker	properties    AndroidAppSetProperties
64*333d2b36SAndroid Build Coastguard Worker	packedOutput  android.WritablePath
65*333d2b36SAndroid Build Coastguard Worker	primaryOutput android.WritablePath
66*333d2b36SAndroid Build Coastguard Worker	apkcertsFile  android.ModuleOutPath
67*333d2b36SAndroid Build Coastguard Worker}
68*333d2b36SAndroid Build Coastguard Worker
69*333d2b36SAndroid Build Coastguard Workerfunc (as *AndroidAppSet) Name() string {
70*333d2b36SAndroid Build Coastguard Worker	return as.prebuilt.Name(as.ModuleBase.Name())
71*333d2b36SAndroid Build Coastguard Worker}
72*333d2b36SAndroid Build Coastguard Worker
73*333d2b36SAndroid Build Coastguard Workerfunc (as *AndroidAppSet) IsInstallable() bool {
74*333d2b36SAndroid Build Coastguard Worker	return true
75*333d2b36SAndroid Build Coastguard Worker}
76*333d2b36SAndroid Build Coastguard Worker
77*333d2b36SAndroid Build Coastguard Workerfunc (as *AndroidAppSet) Prebuilt() *android.Prebuilt {
78*333d2b36SAndroid Build Coastguard Worker	return &as.prebuilt
79*333d2b36SAndroid Build Coastguard Worker}
80*333d2b36SAndroid Build Coastguard Worker
81*333d2b36SAndroid Build Coastguard Workerfunc (as *AndroidAppSet) Privileged() bool {
82*333d2b36SAndroid Build Coastguard Worker	return Bool(as.properties.Privileged)
83*333d2b36SAndroid Build Coastguard Worker}
84*333d2b36SAndroid Build Coastguard Worker
85*333d2b36SAndroid Build Coastguard Workerfunc (as *AndroidAppSet) OutputFile() android.Path {
86*333d2b36SAndroid Build Coastguard Worker	return as.primaryOutput
87*333d2b36SAndroid Build Coastguard Worker}
88*333d2b36SAndroid Build Coastguard Worker
89*333d2b36SAndroid Build Coastguard Workerfunc (as *AndroidAppSet) PackedAdditionalOutputs() android.Path {
90*333d2b36SAndroid Build Coastguard Worker	return as.packedOutput
91*333d2b36SAndroid Build Coastguard Worker}
92*333d2b36SAndroid Build Coastguard Worker
93*333d2b36SAndroid Build Coastguard Workerfunc (as *AndroidAppSet) APKCertsFile() android.Path {
94*333d2b36SAndroid Build Coastguard Worker	return as.apkcertsFile
95*333d2b36SAndroid Build Coastguard Worker}
96*333d2b36SAndroid Build Coastguard Worker
97*333d2b36SAndroid Build Coastguard Workervar TargetCpuAbi = map[string]string{
98*333d2b36SAndroid Build Coastguard Worker	"arm":   "ARMEABI_V7A",
99*333d2b36SAndroid Build Coastguard Worker	"arm64": "ARM64_V8A",
100*333d2b36SAndroid Build Coastguard Worker	// TODO: use "RISCV64" when that is supported in bundles
101*333d2b36SAndroid Build Coastguard Worker	"riscv64": "ARM64_V8A",
102*333d2b36SAndroid Build Coastguard Worker	"x86":     "X86",
103*333d2b36SAndroid Build Coastguard Worker	"x86_64":  "X86_64",
104*333d2b36SAndroid Build Coastguard Worker}
105*333d2b36SAndroid Build Coastguard Worker
106*333d2b36SAndroid Build Coastguard Workerfunc SupportedAbis(ctx android.ModuleContext, excludeNativeBridgeAbis bool) []string {
107*333d2b36SAndroid Build Coastguard Worker	abiName := func(targetIdx int, deviceArch string) string {
108*333d2b36SAndroid Build Coastguard Worker		if abi, found := TargetCpuAbi[deviceArch]; found {
109*333d2b36SAndroid Build Coastguard Worker			return abi
110*333d2b36SAndroid Build Coastguard Worker		}
111*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("Target %d has invalid Arch: %s", targetIdx, deviceArch)
112*333d2b36SAndroid Build Coastguard Worker		return "BAD_ABI"
113*333d2b36SAndroid Build Coastguard Worker	}
114*333d2b36SAndroid Build Coastguard Worker
115*333d2b36SAndroid Build Coastguard Worker	var result []string
116*333d2b36SAndroid Build Coastguard Worker	for i, target := range ctx.Config().Targets[android.Android] {
117*333d2b36SAndroid Build Coastguard Worker		if target.NativeBridge == android.NativeBridgeEnabled && excludeNativeBridgeAbis {
118*333d2b36SAndroid Build Coastguard Worker			continue
119*333d2b36SAndroid Build Coastguard Worker		}
120*333d2b36SAndroid Build Coastguard Worker		result = append(result, abiName(i, target.Arch.ArchType.String()))
121*333d2b36SAndroid Build Coastguard Worker	}
122*333d2b36SAndroid Build Coastguard Worker	return result
123*333d2b36SAndroid Build Coastguard Worker}
124*333d2b36SAndroid Build Coastguard Worker
125*333d2b36SAndroid Build Coastguard Workertype prebuiltInfoProps struct {
126*333d2b36SAndroid Build Coastguard Worker	baseModuleName string
127*333d2b36SAndroid Build Coastguard Worker	isPrebuilt     bool
128*333d2b36SAndroid Build Coastguard Worker	prebuiltInfo   *string
129*333d2b36SAndroid Build Coastguard Worker}
130*333d2b36SAndroid Build Coastguard Worker
131*333d2b36SAndroid Build Coastguard Worker// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
132*333d2b36SAndroid Build Coastguard Worker// with information about whether source or prebuilt of an apex was used during the build.
133*333d2b36SAndroid Build Coastguard Workerfunc providePrebuiltInfo(ctx android.ModuleContext, p prebuiltInfoProps) {
134*333d2b36SAndroid Build Coastguard Worker	info := android.PrebuiltInfo{
135*333d2b36SAndroid Build Coastguard Worker		Name:        p.baseModuleName,
136*333d2b36SAndroid Build Coastguard Worker		Is_prebuilt: p.isPrebuilt,
137*333d2b36SAndroid Build Coastguard Worker	}
138*333d2b36SAndroid Build Coastguard Worker	// If Prebuilt_info information is available in the soong module definition, add it to prebuilt_info.json.
139*333d2b36SAndroid Build Coastguard Worker	if p.prebuiltInfo != nil {
140*333d2b36SAndroid Build Coastguard Worker		prebuiltInfoFile := android.PathForModuleSrc(ctx, *p.prebuiltInfo)
141*333d2b36SAndroid Build Coastguard Worker		info.Prebuilt_info_file_path = prebuiltInfoFile.String()
142*333d2b36SAndroid Build Coastguard Worker	}
143*333d2b36SAndroid Build Coastguard Worker	android.SetProvider(ctx, android.PrebuiltInfoProvider, info)
144*333d2b36SAndroid Build Coastguard Worker}
145*333d2b36SAndroid Build Coastguard Worker
146*333d2b36SAndroid Build Coastguard Workerfunc (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
147*333d2b36SAndroid Build Coastguard Worker	as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
148*333d2b36SAndroid Build Coastguard Worker	as.primaryOutput = android.PathForModuleOut(ctx, as.BaseModuleName()+".apk")
149*333d2b36SAndroid Build Coastguard Worker	as.apkcertsFile = android.PathForModuleOut(ctx, "apkcerts.txt")
150*333d2b36SAndroid Build Coastguard Worker	// We are assuming here that the install file in the APK
151*333d2b36SAndroid Build Coastguard Worker	// set has `.apk` suffix. If it doesn't the build will fail.
152*333d2b36SAndroid Build Coastguard Worker	// APK sets containing APEX files are handled elsewhere.
153*333d2b36SAndroid Build Coastguard Worker	screenDensities := "all"
154*333d2b36SAndroid Build Coastguard Worker	if dpis := ctx.Config().ProductAAPTPrebuiltDPI(); len(dpis) > 0 {
155*333d2b36SAndroid Build Coastguard Worker		screenDensities = strings.ToUpper(strings.Join(dpis, ","))
156*333d2b36SAndroid Build Coastguard Worker	}
157*333d2b36SAndroid Build Coastguard Worker	// TODO(asmundak): handle locales.
158*333d2b36SAndroid Build Coastguard Worker	// TODO(asmundak): do we support device features
159*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx,
160*333d2b36SAndroid Build Coastguard Worker		android.BuildParams{
161*333d2b36SAndroid Build Coastguard Worker			Rule:            extractMatchingApks,
162*333d2b36SAndroid Build Coastguard Worker			Description:     "Extract APKs from APK set",
163*333d2b36SAndroid Build Coastguard Worker			Output:          as.primaryOutput,
164*333d2b36SAndroid Build Coastguard Worker			ImplicitOutputs: android.WritablePaths{as.packedOutput, as.apkcertsFile},
165*333d2b36SAndroid Build Coastguard Worker			Inputs:          android.Paths{as.prebuilt.SingleSourcePath(ctx)},
166*333d2b36SAndroid Build Coastguard Worker			Args: map[string]string{
167*333d2b36SAndroid Build Coastguard Worker				"abis":              strings.Join(SupportedAbis(ctx, false), ","),
168*333d2b36SAndroid Build Coastguard Worker				"allow-prereleased": strconv.FormatBool(proptools.Bool(as.properties.Prerelease)),
169*333d2b36SAndroid Build Coastguard Worker				"screen-densities":  screenDensities,
170*333d2b36SAndroid Build Coastguard Worker				"sdk-version":       ctx.Config().PlatformSdkVersion().String(),
171*333d2b36SAndroid Build Coastguard Worker				"skip-sdk-check":    strconv.FormatBool(ctx.Config().IsEnvTrue("SOONG_SKIP_APPSET_SDK_CHECK")),
172*333d2b36SAndroid Build Coastguard Worker				"stem":              as.BaseModuleName(),
173*333d2b36SAndroid Build Coastguard Worker				"apkcerts":          as.apkcertsFile.String(),
174*333d2b36SAndroid Build Coastguard Worker				"partition":         as.PartitionTag(ctx.DeviceConfig()),
175*333d2b36SAndroid Build Coastguard Worker				"zip":               as.packedOutput.String(),
176*333d2b36SAndroid Build Coastguard Worker			},
177*333d2b36SAndroid Build Coastguard Worker		})
178*333d2b36SAndroid Build Coastguard Worker
179*333d2b36SAndroid Build Coastguard Worker	var installDir android.InstallPath
180*333d2b36SAndroid Build Coastguard Worker	if as.Privileged() {
181*333d2b36SAndroid Build Coastguard Worker		installDir = android.PathForModuleInstall(ctx, "priv-app", as.BaseModuleName())
182*333d2b36SAndroid Build Coastguard Worker	} else {
183*333d2b36SAndroid Build Coastguard Worker		installDir = android.PathForModuleInstall(ctx, "app", as.BaseModuleName())
184*333d2b36SAndroid Build Coastguard Worker	}
185*333d2b36SAndroid Build Coastguard Worker	ctx.InstallFileWithExtraFilesZip(installDir, as.BaseModuleName()+".apk", as.primaryOutput, as.packedOutput)
186*333d2b36SAndroid Build Coastguard Worker
187*333d2b36SAndroid Build Coastguard Worker	providePrebuiltInfo(ctx,
188*333d2b36SAndroid Build Coastguard Worker		prebuiltInfoProps{
189*333d2b36SAndroid Build Coastguard Worker			baseModuleName: as.BaseModuleName(),
190*333d2b36SAndroid Build Coastguard Worker			isPrebuilt:     true,
191*333d2b36SAndroid Build Coastguard Worker			prebuiltInfo:   as.properties.Prebuilt_info,
192*333d2b36SAndroid Build Coastguard Worker		},
193*333d2b36SAndroid Build Coastguard Worker	)
194*333d2b36SAndroid Build Coastguard Worker
195*333d2b36SAndroid Build Coastguard Worker}
196*333d2b36SAndroid Build Coastguard Worker
197*333d2b36SAndroid Build Coastguard Workerfunc (as *AndroidAppSet) InstallBypassMake() bool { return true }
198*333d2b36SAndroid Build Coastguard Worker
199*333d2b36SAndroid Build Coastguard Worker// android_app_set extracts a set of APKs based on the target device
200*333d2b36SAndroid Build Coastguard Worker// configuration and installs this set as "split APKs".
201*333d2b36SAndroid Build Coastguard Worker// The extracted set always contains an APK whose name is
202*333d2b36SAndroid Build Coastguard Worker// _module_name_.apk and every split APK matching target device.
203*333d2b36SAndroid Build Coastguard Worker// The extraction of the density-specific splits depends on
204*333d2b36SAndroid Build Coastguard Worker// PRODUCT_AAPT_PREBUILT_DPI variable. If present (its value should
205*333d2b36SAndroid Build Coastguard Worker// be a list density names: LDPI, MDPI, HDPI, etc.), only listed
206*333d2b36SAndroid Build Coastguard Worker// splits will be extracted. Otherwise all density-specific splits
207*333d2b36SAndroid Build Coastguard Worker// will be extracted.
208*333d2b36SAndroid Build Coastguard Workerfunc AndroidAppSetFactory() android.Module {
209*333d2b36SAndroid Build Coastguard Worker	module := &AndroidAppSet{}
210*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties)
211*333d2b36SAndroid Build Coastguard Worker	InitJavaModule(module, android.DeviceSupported)
212*333d2b36SAndroid Build Coastguard Worker	android.InitSingleSourcePrebuiltModule(module, &module.properties, "Set")
213*333d2b36SAndroid Build Coastguard Worker	return module
214*333d2b36SAndroid Build Coastguard Worker}
215