xref: /aosp_15_r20/build/soong/java/hiddenapi_modular.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2021 The Android Open Source Project
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 Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker	"strings"
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
22*333d2b36SAndroid Build Coastguard Worker	"android/soong/dexpreopt"
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
25*333d2b36SAndroid Build Coastguard Worker)
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker// Contains support for processing hiddenAPI in a modular fashion.
28*333d2b36SAndroid Build Coastguard Worker
29*333d2b36SAndroid Build Coastguard Worker// HiddenAPIScope encapsulates all the information that the hidden API processing needs about API
30*333d2b36SAndroid Build Coastguard Worker// scopes, i.e. what is called android.SdkKind and apiScope. It does not just use those as they do
31*333d2b36SAndroid Build Coastguard Worker// not provide the information needed by hidden API processing.
32*333d2b36SAndroid Build Coastguard Workertype HiddenAPIScope struct {
33*333d2b36SAndroid Build Coastguard Worker	// The name of the scope, used for debug purposes.
34*333d2b36SAndroid Build Coastguard Worker	name string
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard Worker	// The corresponding android.SdkKind, used for retrieving paths from java_sdk_library* modules.
37*333d2b36SAndroid Build Coastguard Worker	sdkKind android.SdkKind
38*333d2b36SAndroid Build Coastguard Worker
39*333d2b36SAndroid Build Coastguard Worker	// The option needed to passed to "hiddenapi list".
40*333d2b36SAndroid Build Coastguard Worker	hiddenAPIListOption string
41*333d2b36SAndroid Build Coastguard Worker
42*333d2b36SAndroid Build Coastguard Worker	// The names of the source stub library modules that contain the API provided by the platform,
43*333d2b36SAndroid Build Coastguard Worker	// i.e. by modules that are not in an APEX.
44*333d2b36SAndroid Build Coastguard Worker	nonUpdatableSourceModule string
45*333d2b36SAndroid Build Coastguard Worker
46*333d2b36SAndroid Build Coastguard Worker	// The names of from-text stub library modules that contain the API provided by the platform,
47*333d2b36SAndroid Build Coastguard Worker	// i.e. by modules that are not in an APEX.
48*333d2b36SAndroid Build Coastguard Worker	nonUpdatableFromTextModule string
49*333d2b36SAndroid Build Coastguard Worker
50*333d2b36SAndroid Build Coastguard Worker	// The names of the prebuilt stub library modules that contain the API provided by the platform,
51*333d2b36SAndroid Build Coastguard Worker	// i.e. by modules that are not in an APEX.
52*333d2b36SAndroid Build Coastguard Worker	nonUpdatablePrebuiltModule string
53*333d2b36SAndroid Build Coastguard Worker}
54*333d2b36SAndroid Build Coastguard Worker
55*333d2b36SAndroid Build Coastguard Worker// initHiddenAPIScope initializes the scope.
56*333d2b36SAndroid Build Coastguard Workerfunc initHiddenAPIScope(apiScope *HiddenAPIScope) *HiddenAPIScope {
57*333d2b36SAndroid Build Coastguard Worker	sdkKind := apiScope.sdkKind
58*333d2b36SAndroid Build Coastguard Worker	// The platform does not provide a core platform API.
59*333d2b36SAndroid Build Coastguard Worker	if sdkKind != android.SdkCorePlatform {
60*333d2b36SAndroid Build Coastguard Worker		kindAsString := sdkKind.String()
61*333d2b36SAndroid Build Coastguard Worker		var insert string
62*333d2b36SAndroid Build Coastguard Worker		if sdkKind == android.SdkPublic {
63*333d2b36SAndroid Build Coastguard Worker			insert = ""
64*333d2b36SAndroid Build Coastguard Worker		} else {
65*333d2b36SAndroid Build Coastguard Worker			insert = "." + strings.ReplaceAll(kindAsString, "-", "_")
66*333d2b36SAndroid Build Coastguard Worker		}
67*333d2b36SAndroid Build Coastguard Worker
68*333d2b36SAndroid Build Coastguard Worker		nonUpdatableModule := "android-non-updatable"
69*333d2b36SAndroid Build Coastguard Worker
70*333d2b36SAndroid Build Coastguard Worker		// Construct the name of the android-non-updatable source module for this scope.
71*333d2b36SAndroid Build Coastguard Worker		apiScope.nonUpdatableSourceModule = fmt.Sprintf("%s.stubs%s", nonUpdatableModule, insert)
72*333d2b36SAndroid Build Coastguard Worker
73*333d2b36SAndroid Build Coastguard Worker		prebuiltModuleName := func(name string, kind string) string {
74*333d2b36SAndroid Build Coastguard Worker			return fmt.Sprintf("sdk_%s_current_%s", kind, name)
75*333d2b36SAndroid Build Coastguard Worker		}
76*333d2b36SAndroid Build Coastguard Worker
77*333d2b36SAndroid Build Coastguard Worker		// Construct the name of the android-non-updatable prebuilt module for this scope.
78*333d2b36SAndroid Build Coastguard Worker		apiScope.nonUpdatablePrebuiltModule = prebuiltModuleName(nonUpdatableModule, kindAsString)
79*333d2b36SAndroid Build Coastguard Worker	}
80*333d2b36SAndroid Build Coastguard Worker
81*333d2b36SAndroid Build Coastguard Worker	return apiScope
82*333d2b36SAndroid Build Coastguard Worker}
83*333d2b36SAndroid Build Coastguard Worker
84*333d2b36SAndroid Build Coastguard Worker// android-non-updatable takes the name of a module and returns a possibly scope specific name of
85*333d2b36SAndroid Build Coastguard Worker// the module.
86*333d2b36SAndroid Build Coastguard Workerfunc (l *HiddenAPIScope) scopeSpecificStubModule(ctx android.BaseModuleContext, name string) string {
87*333d2b36SAndroid Build Coastguard Worker	// The android-non-updatable is not a java_sdk_library but there are separate stub libraries for
88*333d2b36SAndroid Build Coastguard Worker	// each scope.
89*333d2b36SAndroid Build Coastguard Worker	// TODO(b/192067200): Remove special handling of android-non-updatable.
90*333d2b36SAndroid Build Coastguard Worker	if name == "android-non-updatable" {
91*333d2b36SAndroid Build Coastguard Worker		if ctx.Config().AlwaysUsePrebuiltSdks() {
92*333d2b36SAndroid Build Coastguard Worker			return l.nonUpdatablePrebuiltModule
93*333d2b36SAndroid Build Coastguard Worker		} else {
94*333d2b36SAndroid Build Coastguard Worker			if l.nonUpdatableFromTextModule != "" && ctx.Config().BuildFromTextStub() {
95*333d2b36SAndroid Build Coastguard Worker				return l.nonUpdatableFromTextModule
96*333d2b36SAndroid Build Coastguard Worker			}
97*333d2b36SAndroid Build Coastguard Worker			return l.nonUpdatableSourceModule
98*333d2b36SAndroid Build Coastguard Worker		}
99*333d2b36SAndroid Build Coastguard Worker	} else {
100*333d2b36SAndroid Build Coastguard Worker		// Assume that the module is either a java_sdk_library (or equivalent) and so will provide
101*333d2b36SAndroid Build Coastguard Worker		// separate stub jars for each scope or is a java_library (or equivalent) in which case it will
102*333d2b36SAndroid Build Coastguard Worker		// have the same stub jar for each scope.
103*333d2b36SAndroid Build Coastguard Worker		return name
104*333d2b36SAndroid Build Coastguard Worker	}
105*333d2b36SAndroid Build Coastguard Worker}
106*333d2b36SAndroid Build Coastguard Worker
107*333d2b36SAndroid Build Coastguard Workerfunc (l *HiddenAPIScope) String() string {
108*333d2b36SAndroid Build Coastguard Worker	return fmt.Sprintf("HiddenAPIScope{%s}", l.name)
109*333d2b36SAndroid Build Coastguard Worker}
110*333d2b36SAndroid Build Coastguard Worker
111*333d2b36SAndroid Build Coastguard Workervar (
112*333d2b36SAndroid Build Coastguard Worker	PublicHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{
113*333d2b36SAndroid Build Coastguard Worker		name:                "public",
114*333d2b36SAndroid Build Coastguard Worker		sdkKind:             android.SdkPublic,
115*333d2b36SAndroid Build Coastguard Worker		hiddenAPIListOption: "--public-stub-classpath",
116*333d2b36SAndroid Build Coastguard Worker	})
117*333d2b36SAndroid Build Coastguard Worker	SystemHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{
118*333d2b36SAndroid Build Coastguard Worker		name:                "system",
119*333d2b36SAndroid Build Coastguard Worker		sdkKind:             android.SdkSystem,
120*333d2b36SAndroid Build Coastguard Worker		hiddenAPIListOption: "--system-stub-classpath",
121*333d2b36SAndroid Build Coastguard Worker	})
122*333d2b36SAndroid Build Coastguard Worker	TestHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{
123*333d2b36SAndroid Build Coastguard Worker		name:                "test",
124*333d2b36SAndroid Build Coastguard Worker		sdkKind:             android.SdkTest,
125*333d2b36SAndroid Build Coastguard Worker		hiddenAPIListOption: "--test-stub-classpath",
126*333d2b36SAndroid Build Coastguard Worker	})
127*333d2b36SAndroid Build Coastguard Worker	ModuleLibHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{
128*333d2b36SAndroid Build Coastguard Worker		name:                       "module-lib",
129*333d2b36SAndroid Build Coastguard Worker		sdkKind:                    android.SdkModule,
130*333d2b36SAndroid Build Coastguard Worker		nonUpdatableFromTextModule: "android-non-updatable.stubs.test_module_lib",
131*333d2b36SAndroid Build Coastguard Worker	})
132*333d2b36SAndroid Build Coastguard Worker	CorePlatformHiddenAPIScope = initHiddenAPIScope(&HiddenAPIScope{
133*333d2b36SAndroid Build Coastguard Worker		name:                "core-platform",
134*333d2b36SAndroid Build Coastguard Worker		sdkKind:             android.SdkCorePlatform,
135*333d2b36SAndroid Build Coastguard Worker		hiddenAPIListOption: "--core-platform-stub-classpath",
136*333d2b36SAndroid Build Coastguard Worker	})
137*333d2b36SAndroid Build Coastguard Worker
138*333d2b36SAndroid Build Coastguard Worker	// hiddenAPIRelevantSdkKinds lists all the android.SdkKind instances that are needed by the hidden
139*333d2b36SAndroid Build Coastguard Worker	// API processing.
140*333d2b36SAndroid Build Coastguard Worker	//
141*333d2b36SAndroid Build Coastguard Worker	// These are roughly in order from narrowest API surface to widest. Widest means the API stubs
142*333d2b36SAndroid Build Coastguard Worker	// with the biggest API surface, e.g. test is wider than system is wider than public.
143*333d2b36SAndroid Build Coastguard Worker	//
144*333d2b36SAndroid Build Coastguard Worker	// Core platform is considered wider than system/module-lib because those modules that provide
145*333d2b36SAndroid Build Coastguard Worker	// core platform APIs either do not have any system/module-lib APIs at all, or if they do it is
146*333d2b36SAndroid Build Coastguard Worker	// because the core platform API is being converted to system/module-lib APIs. In either case the
147*333d2b36SAndroid Build Coastguard Worker	// system/module-lib APIs are subsets of the core platform API.
148*333d2b36SAndroid Build Coastguard Worker	//
149*333d2b36SAndroid Build Coastguard Worker	// This is not strictly in order from narrowest to widest as the Test API is wider than system but
150*333d2b36SAndroid Build Coastguard Worker	// is neither wider or narrower than the module-lib or core platform APIs. However, this works
151*333d2b36SAndroid Build Coastguard Worker	// well enough at the moment.
152*333d2b36SAndroid Build Coastguard Worker	// TODO(b/191644675): Correctly reflect the sub/superset relationships between APIs.
153*333d2b36SAndroid Build Coastguard Worker	hiddenAPIScopes = []*HiddenAPIScope{
154*333d2b36SAndroid Build Coastguard Worker		PublicHiddenAPIScope,
155*333d2b36SAndroid Build Coastguard Worker		SystemHiddenAPIScope,
156*333d2b36SAndroid Build Coastguard Worker		TestHiddenAPIScope,
157*333d2b36SAndroid Build Coastguard Worker		ModuleLibHiddenAPIScope,
158*333d2b36SAndroid Build Coastguard Worker		CorePlatformHiddenAPIScope,
159*333d2b36SAndroid Build Coastguard Worker	}
160*333d2b36SAndroid Build Coastguard Worker
161*333d2b36SAndroid Build Coastguard Worker	// The HiddenAPIScope instances that are supported by a java_sdk_library.
162*333d2b36SAndroid Build Coastguard Worker	//
163*333d2b36SAndroid Build Coastguard Worker	// CorePlatformHiddenAPIScope is not used as the java_sdk_library does not have special support
164*333d2b36SAndroid Build Coastguard Worker	// for core_platform API, instead it is implemented as a customized form of PublicHiddenAPIScope.
165*333d2b36SAndroid Build Coastguard Worker	hiddenAPISdkLibrarySupportedScopes = []*HiddenAPIScope{
166*333d2b36SAndroid Build Coastguard Worker		PublicHiddenAPIScope,
167*333d2b36SAndroid Build Coastguard Worker		SystemHiddenAPIScope,
168*333d2b36SAndroid Build Coastguard Worker		TestHiddenAPIScope,
169*333d2b36SAndroid Build Coastguard Worker		ModuleLibHiddenAPIScope,
170*333d2b36SAndroid Build Coastguard Worker	}
171*333d2b36SAndroid Build Coastguard Worker
172*333d2b36SAndroid Build Coastguard Worker	// The HiddenAPIScope instances that are supported by the `hiddenapi list`.
173*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagScopes = []*HiddenAPIScope{
174*333d2b36SAndroid Build Coastguard Worker		PublicHiddenAPIScope,
175*333d2b36SAndroid Build Coastguard Worker		SystemHiddenAPIScope,
176*333d2b36SAndroid Build Coastguard Worker		TestHiddenAPIScope,
177*333d2b36SAndroid Build Coastguard Worker		CorePlatformHiddenAPIScope,
178*333d2b36SAndroid Build Coastguard Worker	}
179*333d2b36SAndroid Build Coastguard Worker)
180*333d2b36SAndroid Build Coastguard Worker
181*333d2b36SAndroid Build Coastguard Workertype hiddenAPIStubsDependencyTag struct {
182*333d2b36SAndroid Build Coastguard Worker	blueprint.BaseDependencyTag
183*333d2b36SAndroid Build Coastguard Worker
184*333d2b36SAndroid Build Coastguard Worker	// The api scope for which this dependency was added.
185*333d2b36SAndroid Build Coastguard Worker	apiScope *HiddenAPIScope
186*333d2b36SAndroid Build Coastguard Worker
187*333d2b36SAndroid Build Coastguard Worker	// Indicates that the dependency is not for an API provided by the current bootclasspath fragment
188*333d2b36SAndroid Build Coastguard Worker	// but is an additional API provided by a module that is not part of the current bootclasspath
189*333d2b36SAndroid Build Coastguard Worker	// fragment.
190*333d2b36SAndroid Build Coastguard Worker	fromAdditionalDependency bool
191*333d2b36SAndroid Build Coastguard Worker}
192*333d2b36SAndroid Build Coastguard Worker
193*333d2b36SAndroid Build Coastguard Workerfunc (b hiddenAPIStubsDependencyTag) ExcludeFromApexContents() {
194*333d2b36SAndroid Build Coastguard Worker}
195*333d2b36SAndroid Build Coastguard Worker
196*333d2b36SAndroid Build Coastguard Workerfunc (b hiddenAPIStubsDependencyTag) ReplaceSourceWithPrebuilt() bool {
197*333d2b36SAndroid Build Coastguard Worker	return false
198*333d2b36SAndroid Build Coastguard Worker}
199*333d2b36SAndroid Build Coastguard Worker
200*333d2b36SAndroid Build Coastguard Workerfunc (b hiddenAPIStubsDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType {
201*333d2b36SAndroid Build Coastguard Worker	// Do not add additional dependencies to the sdk.
202*333d2b36SAndroid Build Coastguard Worker	if b.fromAdditionalDependency {
203*333d2b36SAndroid Build Coastguard Worker		return nil
204*333d2b36SAndroid Build Coastguard Worker	}
205*333d2b36SAndroid Build Coastguard Worker
206*333d2b36SAndroid Build Coastguard Worker	// If the module is a java_sdk_library then treat it as if it was specific in the java_sdk_libs
207*333d2b36SAndroid Build Coastguard Worker	// property, otherwise treat if it was specified in the java_header_libs property.
208*333d2b36SAndroid Build Coastguard Worker	if javaSdkLibrarySdkMemberType.IsInstance(child) {
209*333d2b36SAndroid Build Coastguard Worker		return javaSdkLibrarySdkMemberType
210*333d2b36SAndroid Build Coastguard Worker	}
211*333d2b36SAndroid Build Coastguard Worker
212*333d2b36SAndroid Build Coastguard Worker	return javaHeaderLibsSdkMemberType
213*333d2b36SAndroid Build Coastguard Worker}
214*333d2b36SAndroid Build Coastguard Worker
215*333d2b36SAndroid Build Coastguard Workerfunc (b hiddenAPIStubsDependencyTag) ExportMember() bool {
216*333d2b36SAndroid Build Coastguard Worker	// Export the module added via this dependency tag from the sdk.
217*333d2b36SAndroid Build Coastguard Worker	return true
218*333d2b36SAndroid Build Coastguard Worker}
219*333d2b36SAndroid Build Coastguard Worker
220*333d2b36SAndroid Build Coastguard Worker// Avoid having to make stubs content explicitly visible to dependent modules.
221*333d2b36SAndroid Build Coastguard Worker//
222*333d2b36SAndroid Build Coastguard Worker// This is a temporary workaround to make it easier to migrate to bootclasspath_fragment modules
223*333d2b36SAndroid Build Coastguard Worker// with proper dependencies.
224*333d2b36SAndroid Build Coastguard Worker// TODO(b/177892522): Remove this and add needed visibility.
225*333d2b36SAndroid Build Coastguard Workerfunc (b hiddenAPIStubsDependencyTag) ExcludeFromVisibilityEnforcement() {
226*333d2b36SAndroid Build Coastguard Worker}
227*333d2b36SAndroid Build Coastguard Worker
228*333d2b36SAndroid Build Coastguard Workervar _ android.ExcludeFromVisibilityEnforcementTag = hiddenAPIStubsDependencyTag{}
229*333d2b36SAndroid Build Coastguard Workervar _ android.ReplaceSourceWithPrebuilt = hiddenAPIStubsDependencyTag{}
230*333d2b36SAndroid Build Coastguard Workervar _ android.ExcludeFromApexContentsTag = hiddenAPIStubsDependencyTag{}
231*333d2b36SAndroid Build Coastguard Workervar _ android.SdkMemberDependencyTag = hiddenAPIStubsDependencyTag{}
232*333d2b36SAndroid Build Coastguard Worker
233*333d2b36SAndroid Build Coastguard Worker// hiddenAPIComputeMonolithicStubLibModules computes the set of module names that provide stubs
234*333d2b36SAndroid Build Coastguard Worker// needed to produce the hidden API monolithic stub flags file.
235*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIComputeMonolithicStubLibModules(config android.Config) map[*HiddenAPIScope][]string {
236*333d2b36SAndroid Build Coastguard Worker	var publicStubModules []string
237*333d2b36SAndroid Build Coastguard Worker	var systemStubModules []string
238*333d2b36SAndroid Build Coastguard Worker	var testStubModules []string
239*333d2b36SAndroid Build Coastguard Worker	var corePlatformStubModules []string
240*333d2b36SAndroid Build Coastguard Worker
241*333d2b36SAndroid Build Coastguard Worker	if config.AlwaysUsePrebuiltSdks() {
242*333d2b36SAndroid Build Coastguard Worker		// Build configuration mandates using prebuilt stub modules
243*333d2b36SAndroid Build Coastguard Worker		publicStubModules = append(publicStubModules, "sdk_public_current_android")
244*333d2b36SAndroid Build Coastguard Worker		systemStubModules = append(systemStubModules, "sdk_system_current_android")
245*333d2b36SAndroid Build Coastguard Worker		testStubModules = append(testStubModules, "sdk_test_current_android")
246*333d2b36SAndroid Build Coastguard Worker	} else {
247*333d2b36SAndroid Build Coastguard Worker		// Use stub modules built from source
248*333d2b36SAndroid Build Coastguard Worker		if config.ReleaseHiddenApiExportableStubs() {
249*333d2b36SAndroid Build Coastguard Worker			publicStubModules = append(publicStubModules, android.SdkPublic.DefaultExportableJavaLibraryName())
250*333d2b36SAndroid Build Coastguard Worker			systemStubModules = append(systemStubModules, android.SdkSystem.DefaultExportableJavaLibraryName())
251*333d2b36SAndroid Build Coastguard Worker			testStubModules = append(testStubModules, android.SdkTest.DefaultExportableJavaLibraryName())
252*333d2b36SAndroid Build Coastguard Worker		} else {
253*333d2b36SAndroid Build Coastguard Worker			publicStubModules = append(publicStubModules, android.SdkPublic.DefaultJavaLibraryName())
254*333d2b36SAndroid Build Coastguard Worker			systemStubModules = append(systemStubModules, android.SdkSystem.DefaultJavaLibraryName())
255*333d2b36SAndroid Build Coastguard Worker			testStubModules = append(testStubModules, android.SdkTest.DefaultJavaLibraryName())
256*333d2b36SAndroid Build Coastguard Worker		}
257*333d2b36SAndroid Build Coastguard Worker	}
258*333d2b36SAndroid Build Coastguard Worker	// We do not have prebuilts of the core platform api yet
259*333d2b36SAndroid Build Coastguard Worker	if config.ReleaseHiddenApiExportableStubs() {
260*333d2b36SAndroid Build Coastguard Worker		corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs.exportable")
261*333d2b36SAndroid Build Coastguard Worker	} else {
262*333d2b36SAndroid Build Coastguard Worker		corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs")
263*333d2b36SAndroid Build Coastguard Worker	}
264*333d2b36SAndroid Build Coastguard Worker
265*333d2b36SAndroid Build Coastguard Worker	// Allow products to define their own stubs for custom product jars that apps can use.
266*333d2b36SAndroid Build Coastguard Worker	publicStubModules = append(publicStubModules, config.ProductHiddenAPIStubs()...)
267*333d2b36SAndroid Build Coastguard Worker	systemStubModules = append(systemStubModules, config.ProductHiddenAPIStubsSystem()...)
268*333d2b36SAndroid Build Coastguard Worker	testStubModules = append(testStubModules, config.ProductHiddenAPIStubsTest()...)
269*333d2b36SAndroid Build Coastguard Worker	if config.IsEnvTrue("EMMA_INSTRUMENT") {
270*333d2b36SAndroid Build Coastguard Worker		// Add jacoco-stubs to public, system and test. It doesn't make any real difference as public
271*333d2b36SAndroid Build Coastguard Worker		// allows everyone access but it is needed to ensure consistent flags between the
272*333d2b36SAndroid Build Coastguard Worker		// bootclasspath fragment generated flags and the platform_bootclasspath generated flags.
273*333d2b36SAndroid Build Coastguard Worker		publicStubModules = append(publicStubModules, "jacoco-stubs")
274*333d2b36SAndroid Build Coastguard Worker		systemStubModules = append(systemStubModules, "jacoco-stubs")
275*333d2b36SAndroid Build Coastguard Worker		testStubModules = append(testStubModules, "jacoco-stubs")
276*333d2b36SAndroid Build Coastguard Worker	}
277*333d2b36SAndroid Build Coastguard Worker
278*333d2b36SAndroid Build Coastguard Worker	m := map[*HiddenAPIScope][]string{}
279*333d2b36SAndroid Build Coastguard Worker	m[PublicHiddenAPIScope] = publicStubModules
280*333d2b36SAndroid Build Coastguard Worker	m[SystemHiddenAPIScope] = systemStubModules
281*333d2b36SAndroid Build Coastguard Worker	m[TestHiddenAPIScope] = testStubModules
282*333d2b36SAndroid Build Coastguard Worker	m[CorePlatformHiddenAPIScope] = corePlatformStubModules
283*333d2b36SAndroid Build Coastguard Worker	return m
284*333d2b36SAndroid Build Coastguard Worker}
285*333d2b36SAndroid Build Coastguard Worker
286*333d2b36SAndroid Build Coastguard Worker// hiddenAPIAddStubLibDependencies adds dependencies onto the modules specified in
287*333d2b36SAndroid Build Coastguard Worker// apiScopeToStubLibModules. It adds them in a well known order and uses a HiddenAPIScope specific
288*333d2b36SAndroid Build Coastguard Worker// tag to identify the source of the dependency.
289*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, apiScopeToStubLibModules map[*HiddenAPIScope][]string) {
290*333d2b36SAndroid Build Coastguard Worker	module := ctx.Module()
291*333d2b36SAndroid Build Coastguard Worker	for _, apiScope := range hiddenAPIScopes {
292*333d2b36SAndroid Build Coastguard Worker		modules := apiScopeToStubLibModules[apiScope]
293*333d2b36SAndroid Build Coastguard Worker		ctx.AddDependency(module, hiddenAPIStubsDependencyTag{apiScope: apiScope}, modules...)
294*333d2b36SAndroid Build Coastguard Worker	}
295*333d2b36SAndroid Build Coastguard Worker}
296*333d2b36SAndroid Build Coastguard Worker
297*333d2b36SAndroid Build Coastguard Worker// hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if
298*333d2b36SAndroid Build Coastguard Worker// available, or reports an error.
299*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path {
300*333d2b36SAndroid Build Coastguard Worker	var dexJar OptionalDexJarPath
301*333d2b36SAndroid Build Coastguard Worker	if sdkLibrary, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
302*333d2b36SAndroid Build Coastguard Worker		if ctx.Config().ReleaseHiddenApiExportableStubs() {
303*333d2b36SAndroid Build Coastguard Worker			dexJar = sdkLibrary.ExportableStubDexJarPaths[kind]
304*333d2b36SAndroid Build Coastguard Worker		} else {
305*333d2b36SAndroid Build Coastguard Worker			dexJar = sdkLibrary.EverythingStubDexJarPaths[kind]
306*333d2b36SAndroid Build Coastguard Worker		}
307*333d2b36SAndroid Build Coastguard Worker	} else if j, ok := module.(UsesLibraryDependency); ok {
308*333d2b36SAndroid Build Coastguard Worker		dexJar = j.DexJarBuildPath(ctx)
309*333d2b36SAndroid Build Coastguard Worker	} else {
310*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("dependency %s of module type %s does not support providing a dex jar", module, ctx.OtherModuleType(module))
311*333d2b36SAndroid Build Coastguard Worker		return nil
312*333d2b36SAndroid Build Coastguard Worker	}
313*333d2b36SAndroid Build Coastguard Worker
314*333d2b36SAndroid Build Coastguard Worker	if !dexJar.Valid() {
315*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("dependency %s does not provide a dex jar: %s", module, dexJar.InvalidReason())
316*333d2b36SAndroid Build Coastguard Worker		return nil
317*333d2b36SAndroid Build Coastguard Worker	}
318*333d2b36SAndroid Build Coastguard Worker	return dexJar.Path()
319*333d2b36SAndroid Build Coastguard Worker}
320*333d2b36SAndroid Build Coastguard Worker
321*333d2b36SAndroid Build Coastguard Worker// HIDDENAPI_STUB_FLAGS_IMPL_FLAGS is the set of flags that identify implementation only signatures,
322*333d2b36SAndroid Build Coastguard Worker// i.e. those signatures that are not part of any API (including the hidden API).
323*333d2b36SAndroid Build Coastguard Workervar HIDDENAPI_STUB_FLAGS_IMPL_FLAGS = []string{}
324*333d2b36SAndroid Build Coastguard Worker
325*333d2b36SAndroid Build Coastguard Workervar HIDDENAPI_FLAGS_CSV_IMPL_FLAGS = []string{"blocked"}
326*333d2b36SAndroid Build Coastguard Worker
327*333d2b36SAndroid Build Coastguard Worker// buildRuleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file.
328*333d2b36SAndroid Build Coastguard Worker//
329*333d2b36SAndroid Build Coastguard Worker// The rule is initialized but not built so that the caller can modify it and select an appropriate
330*333d2b36SAndroid Build Coastguard Worker// name.
331*333d2b36SAndroid Build Coastguard Workerfunc buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput, stubFlagSubsets SignatureCsvSubsets) {
332*333d2b36SAndroid Build Coastguard Worker	// Singleton rule which applies hiddenapi on all boot class path dex files.
333*333d2b36SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
334*333d2b36SAndroid Build Coastguard Worker
335*333d2b36SAndroid Build Coastguard Worker	tempPath := tempPathForRestat(ctx, outputPath)
336*333d2b36SAndroid Build Coastguard Worker
337*333d2b36SAndroid Build Coastguard Worker	// Find the widest API stubs provided by the fragments on which this depends, if any.
338*333d2b36SAndroid Build Coastguard Worker	dependencyStubDexJars := input.DependencyStubDexJarsByScope.StubDexJarsForWidestAPIScope()
339*333d2b36SAndroid Build Coastguard Worker
340*333d2b36SAndroid Build Coastguard Worker	// Add widest API stubs from the additional dependencies of this, if any.
341*333d2b36SAndroid Build Coastguard Worker	dependencyStubDexJars = append(dependencyStubDexJars, input.AdditionalStubDexJarsByScope.StubDexJarsForWidestAPIScope()...)
342*333d2b36SAndroid Build Coastguard Worker
343*333d2b36SAndroid Build Coastguard Worker	command := rule.Command().
344*333d2b36SAndroid Build Coastguard Worker		Tool(ctx.Config().HostToolPath(ctx, "hiddenapi")).
345*333d2b36SAndroid Build Coastguard Worker		Text("list").
346*333d2b36SAndroid Build Coastguard Worker		FlagForEachInput("--dependency-stub-dex=", dependencyStubDexJars).
347*333d2b36SAndroid Build Coastguard Worker		FlagForEachInput("--boot-dex=", bootDexJars)
348*333d2b36SAndroid Build Coastguard Worker
349*333d2b36SAndroid Build Coastguard Worker	// If no module stub flags paths are provided then this must be being called for a
350*333d2b36SAndroid Build Coastguard Worker	// bootclasspath_fragment and not the whole platform_bootclasspath.
351*333d2b36SAndroid Build Coastguard Worker	if stubFlagSubsets == nil {
352*333d2b36SAndroid Build Coastguard Worker		// This is being run on a fragment of the bootclasspath.
353*333d2b36SAndroid Build Coastguard Worker		command.Flag("--fragment")
354*333d2b36SAndroid Build Coastguard Worker	}
355*333d2b36SAndroid Build Coastguard Worker
356*333d2b36SAndroid Build Coastguard Worker	// Iterate over the api scopes in a fixed order.
357*333d2b36SAndroid Build Coastguard Worker	for _, apiScope := range hiddenAPIFlagScopes {
358*333d2b36SAndroid Build Coastguard Worker		// Merge in the stub dex jar paths for this api scope from the fragments on which it depends.
359*333d2b36SAndroid Build Coastguard Worker		// They will be needed to resolve dependencies from this fragment's stubs to classes in the
360*333d2b36SAndroid Build Coastguard Worker		// other fragment's APIs.
361*333d2b36SAndroid Build Coastguard Worker		var paths android.Paths
362*333d2b36SAndroid Build Coastguard Worker		paths = append(paths, input.DependencyStubDexJarsByScope.StubDexJarsForScope(apiScope)...)
363*333d2b36SAndroid Build Coastguard Worker		paths = append(paths, input.AdditionalStubDexJarsByScope.StubDexJarsForScope(apiScope)...)
364*333d2b36SAndroid Build Coastguard Worker		paths = append(paths, input.StubDexJarsByScope.StubDexJarsForScope(apiScope)...)
365*333d2b36SAndroid Build Coastguard Worker		if len(paths) > 0 {
366*333d2b36SAndroid Build Coastguard Worker			option := apiScope.hiddenAPIListOption
367*333d2b36SAndroid Build Coastguard Worker			command.FlagWithInputList(option+"=", paths, ":")
368*333d2b36SAndroid Build Coastguard Worker		}
369*333d2b36SAndroid Build Coastguard Worker	}
370*333d2b36SAndroid Build Coastguard Worker
371*333d2b36SAndroid Build Coastguard Worker	// Add the output path.
372*333d2b36SAndroid Build Coastguard Worker	command.FlagWithOutput("--out-api-flags=", tempPath)
373*333d2b36SAndroid Build Coastguard Worker
374*333d2b36SAndroid Build Coastguard Worker	// If there are stub flag files that have been generated by fragments on which this depends then
375*333d2b36SAndroid Build Coastguard Worker	// use them to validate the stub flag file generated by the rules created by this method.
376*333d2b36SAndroid Build Coastguard Worker	if !ctx.Config().DisableVerifyOverlaps() && len(stubFlagSubsets) > 0 {
377*333d2b36SAndroid Build Coastguard Worker		validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, stubFlagSubsets,
378*333d2b36SAndroid Build Coastguard Worker			HIDDENAPI_STUB_FLAGS_IMPL_FLAGS)
379*333d2b36SAndroid Build Coastguard Worker
380*333d2b36SAndroid Build Coastguard Worker		// Add the file that indicates that the file generated by this is valid.
381*333d2b36SAndroid Build Coastguard Worker		//
382*333d2b36SAndroid Build Coastguard Worker		// This will cause the validation rule above to be run any time that the output of this rule
383*333d2b36SAndroid Build Coastguard Worker		// changes but the validation will run in parallel with other rules that depend on this file.
384*333d2b36SAndroid Build Coastguard Worker		command.Validation(validFile)
385*333d2b36SAndroid Build Coastguard Worker	}
386*333d2b36SAndroid Build Coastguard Worker
387*333d2b36SAndroid Build Coastguard Worker	commitChangeForRestat(rule, tempPath, outputPath)
388*333d2b36SAndroid Build Coastguard Worker
389*333d2b36SAndroid Build Coastguard Worker	rule.Build(name, desc)
390*333d2b36SAndroid Build Coastguard Worker}
391*333d2b36SAndroid Build Coastguard Worker
392*333d2b36SAndroid Build Coastguard Worker// HiddenAPIFlagFileProperties contains paths to the flag files that can be used to augment the
393*333d2b36SAndroid Build Coastguard Worker// information obtained from annotations within the source code in order to create the complete set
394*333d2b36SAndroid Build Coastguard Worker// of flags that should be applied to the dex implementation jars on the bootclasspath.
395*333d2b36SAndroid Build Coastguard Worker//
396*333d2b36SAndroid Build Coastguard Worker// Each property contains a list of paths. With the exception of the Unsupported_packages the paths
397*333d2b36SAndroid Build Coastguard Worker// of each property reference a plain text file that contains a java signature per line. The flags
398*333d2b36SAndroid Build Coastguard Worker// for each of those signatures will be updated in a property specific way.
399*333d2b36SAndroid Build Coastguard Worker//
400*333d2b36SAndroid Build Coastguard Worker// The Unsupported_packages property contains a list of paths, each of which is a plain text file
401*333d2b36SAndroid Build Coastguard Worker// with one Java package per line. All members of all classes within that package (but not nested
402*333d2b36SAndroid Build Coastguard Worker// packages) will be updated in a property specific way.
403*333d2b36SAndroid Build Coastguard Workertype HiddenAPIFlagFileProperties struct {
404*333d2b36SAndroid Build Coastguard Worker	Hidden_api struct {
405*333d2b36SAndroid Build Coastguard Worker		// Marks each signature in the referenced files as being unsupported.
406*333d2b36SAndroid Build Coastguard Worker		Unsupported []string `android:"path"`
407*333d2b36SAndroid Build Coastguard Worker
408*333d2b36SAndroid Build Coastguard Worker		// Marks each signature in the referenced files as being unsupported because it has been
409*333d2b36SAndroid Build Coastguard Worker		// removed. Any conflicts with other flags are ignored.
410*333d2b36SAndroid Build Coastguard Worker		Removed []string `android:"path"`
411*333d2b36SAndroid Build Coastguard Worker
412*333d2b36SAndroid Build Coastguard Worker		// Marks each signature in the referenced files as being supported only for
413*333d2b36SAndroid Build Coastguard Worker		// targetSdkVersion <= R and low priority.
414*333d2b36SAndroid Build Coastguard Worker		Max_target_r_low_priority []string `android:"path"`
415*333d2b36SAndroid Build Coastguard Worker
416*333d2b36SAndroid Build Coastguard Worker		// Marks each signature in the referenced files as being supported only for
417*333d2b36SAndroid Build Coastguard Worker		// targetSdkVersion <= Q.
418*333d2b36SAndroid Build Coastguard Worker		Max_target_q []string `android:"path"`
419*333d2b36SAndroid Build Coastguard Worker
420*333d2b36SAndroid Build Coastguard Worker		// Marks each signature in the referenced files as being supported only for
421*333d2b36SAndroid Build Coastguard Worker		// targetSdkVersion <= P.
422*333d2b36SAndroid Build Coastguard Worker		Max_target_p []string `android:"path"`
423*333d2b36SAndroid Build Coastguard Worker
424*333d2b36SAndroid Build Coastguard Worker		// Marks each signature in the referenced files as being supported only for
425*333d2b36SAndroid Build Coastguard Worker		// targetSdkVersion <= O
426*333d2b36SAndroid Build Coastguard Worker		// and low priority. Any conflicts with other flags are ignored.
427*333d2b36SAndroid Build Coastguard Worker		Max_target_o_low_priority []string `android:"path"`
428*333d2b36SAndroid Build Coastguard Worker
429*333d2b36SAndroid Build Coastguard Worker		// Marks each signature in the referenced files as being blocked.
430*333d2b36SAndroid Build Coastguard Worker		Blocked []string `android:"path"`
431*333d2b36SAndroid Build Coastguard Worker
432*333d2b36SAndroid Build Coastguard Worker		// Marks each signature in every package in the referenced files as being unsupported.
433*333d2b36SAndroid Build Coastguard Worker		Unsupported_packages []string `android:"path"`
434*333d2b36SAndroid Build Coastguard Worker	}
435*333d2b36SAndroid Build Coastguard Worker}
436*333d2b36SAndroid Build Coastguard Worker
437*333d2b36SAndroid Build Coastguard Workertype hiddenAPIFlagFileCategory int
438*333d2b36SAndroid Build Coastguard Worker
439*333d2b36SAndroid Build Coastguard Workerconst (
440*333d2b36SAndroid Build Coastguard Worker	// The flag file category for removed members of the API.
441*333d2b36SAndroid Build Coastguard Worker	//
442*333d2b36SAndroid Build Coastguard Worker	// This is extracted from HiddenAPIFlagFileCategories as it is needed to add the dex signatures
443*333d2b36SAndroid Build Coastguard Worker	// list of removed API members that are generated automatically from the removed.txt files provided
444*333d2b36SAndroid Build Coastguard Worker	// by API stubs.
445*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryRemoved hiddenAPIFlagFileCategory = iota
446*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryUnsupported
447*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryMaxTargetRLowPriority
448*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryMaxTargetQ
449*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryMaxTargetP
450*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryMaxTargetOLowPriority
451*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryBlocked
452*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryUnsupportedPackages
453*333d2b36SAndroid Build Coastguard Worker)
454*333d2b36SAndroid Build Coastguard Worker
455*333d2b36SAndroid Build Coastguard Workerfunc (c hiddenAPIFlagFileCategory) PropertyName() string {
456*333d2b36SAndroid Build Coastguard Worker	switch c {
457*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryRemoved:
458*333d2b36SAndroid Build Coastguard Worker		return "removed"
459*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryUnsupported:
460*333d2b36SAndroid Build Coastguard Worker		return "unsupported"
461*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetRLowPriority:
462*333d2b36SAndroid Build Coastguard Worker		return "max_target_r_low_priority"
463*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetQ:
464*333d2b36SAndroid Build Coastguard Worker		return "max_target_q"
465*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetP:
466*333d2b36SAndroid Build Coastguard Worker		return "max_target_p"
467*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetOLowPriority:
468*333d2b36SAndroid Build Coastguard Worker		return "max_target_o_low_priority"
469*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryBlocked:
470*333d2b36SAndroid Build Coastguard Worker		return "blocked"
471*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryUnsupportedPackages:
472*333d2b36SAndroid Build Coastguard Worker		return "unsupported_packages"
473*333d2b36SAndroid Build Coastguard Worker	default:
474*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Sprintf("Unknown hidden api flag file category type: %d", c))
475*333d2b36SAndroid Build Coastguard Worker	}
476*333d2b36SAndroid Build Coastguard Worker}
477*333d2b36SAndroid Build Coastguard Worker
478*333d2b36SAndroid Build Coastguard Worker// propertyValueReader retrieves the value of the property for this category from the set of properties.
479*333d2b36SAndroid Build Coastguard Workerfunc (c hiddenAPIFlagFileCategory) propertyValueReader(properties *HiddenAPIFlagFileProperties) []string {
480*333d2b36SAndroid Build Coastguard Worker	switch c {
481*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryRemoved:
482*333d2b36SAndroid Build Coastguard Worker		return properties.Hidden_api.Removed
483*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryUnsupported:
484*333d2b36SAndroid Build Coastguard Worker		return properties.Hidden_api.Unsupported
485*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetRLowPriority:
486*333d2b36SAndroid Build Coastguard Worker		return properties.Hidden_api.Max_target_r_low_priority
487*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetQ:
488*333d2b36SAndroid Build Coastguard Worker		return properties.Hidden_api.Max_target_q
489*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetP:
490*333d2b36SAndroid Build Coastguard Worker		return properties.Hidden_api.Max_target_p
491*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetOLowPriority:
492*333d2b36SAndroid Build Coastguard Worker		return properties.Hidden_api.Max_target_o_low_priority
493*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryBlocked:
494*333d2b36SAndroid Build Coastguard Worker		return properties.Hidden_api.Blocked
495*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryUnsupportedPackages:
496*333d2b36SAndroid Build Coastguard Worker		return properties.Hidden_api.Unsupported_packages
497*333d2b36SAndroid Build Coastguard Worker	default:
498*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Sprintf("Unknown hidden api flag file category type: %d", c))
499*333d2b36SAndroid Build Coastguard Worker	}
500*333d2b36SAndroid Build Coastguard Worker}
501*333d2b36SAndroid Build Coastguard Worker
502*333d2b36SAndroid Build Coastguard Worker// commandMutator adds the appropriate command line options for this category to the supplied command
503*333d2b36SAndroid Build Coastguard Workerfunc (c hiddenAPIFlagFileCategory) commandMutator(command *android.RuleBuilderCommand, path android.Path) {
504*333d2b36SAndroid Build Coastguard Worker	switch c {
505*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryRemoved:
506*333d2b36SAndroid Build Coastguard Worker		command.FlagWithInput("--unsupported ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "removed")
507*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryUnsupported:
508*333d2b36SAndroid Build Coastguard Worker		command.FlagWithInput("--unsupported ", path)
509*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetRLowPriority:
510*333d2b36SAndroid Build Coastguard Worker		command.FlagWithInput("--max-target-r ", path).FlagWithArg("--tag ", "lo-prio")
511*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetQ:
512*333d2b36SAndroid Build Coastguard Worker		command.FlagWithInput("--max-target-q ", path)
513*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetP:
514*333d2b36SAndroid Build Coastguard Worker		command.FlagWithInput("--max-target-p ", path)
515*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryMaxTargetOLowPriority:
516*333d2b36SAndroid Build Coastguard Worker		command.FlagWithInput("--max-target-o ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "lo-prio")
517*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryBlocked:
518*333d2b36SAndroid Build Coastguard Worker		command.FlagWithInput("--blocked ", path)
519*333d2b36SAndroid Build Coastguard Worker	case hiddenAPIFlagFileCategoryUnsupportedPackages:
520*333d2b36SAndroid Build Coastguard Worker		command.FlagWithInput("--unsupported ", path).Flag("--packages ")
521*333d2b36SAndroid Build Coastguard Worker	default:
522*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Sprintf("Unknown hidden api flag file category type: %d", c))
523*333d2b36SAndroid Build Coastguard Worker	}
524*333d2b36SAndroid Build Coastguard Worker}
525*333d2b36SAndroid Build Coastguard Worker
526*333d2b36SAndroid Build Coastguard Workertype hiddenAPIFlagFileCategories []hiddenAPIFlagFileCategory
527*333d2b36SAndroid Build Coastguard Worker
528*333d2b36SAndroid Build Coastguard Workervar HiddenAPIFlagFileCategories = hiddenAPIFlagFileCategories{
529*333d2b36SAndroid Build Coastguard Worker	// See HiddenAPIFlagFileProperties.Unsupported
530*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryUnsupported,
531*333d2b36SAndroid Build Coastguard Worker	// See HiddenAPIFlagFileProperties.Removed
532*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryRemoved,
533*333d2b36SAndroid Build Coastguard Worker	// See HiddenAPIFlagFileProperties.Max_target_r_low_priority
534*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryMaxTargetRLowPriority,
535*333d2b36SAndroid Build Coastguard Worker	// See HiddenAPIFlagFileProperties.Max_target_q
536*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryMaxTargetQ,
537*333d2b36SAndroid Build Coastguard Worker	// See HiddenAPIFlagFileProperties.Max_target_p
538*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryMaxTargetP,
539*333d2b36SAndroid Build Coastguard Worker	// See HiddenAPIFlagFileProperties.Max_target_o_low_priority
540*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryMaxTargetOLowPriority,
541*333d2b36SAndroid Build Coastguard Worker	// See HiddenAPIFlagFileProperties.Blocked
542*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryBlocked,
543*333d2b36SAndroid Build Coastguard Worker	// See HiddenAPIFlagFileProperties.Unsupported_packages
544*333d2b36SAndroid Build Coastguard Worker	hiddenAPIFlagFileCategoryUnsupportedPackages,
545*333d2b36SAndroid Build Coastguard Worker}
546*333d2b36SAndroid Build Coastguard Worker
547*333d2b36SAndroid Build Coastguard Worker// FlagFilesByCategory maps a hiddenAPIFlagFileCategory to the paths to the files in that category.
548*333d2b36SAndroid Build Coastguard Workertype FlagFilesByCategory map[hiddenAPIFlagFileCategory]android.Paths
549*333d2b36SAndroid Build Coastguard Worker
550*333d2b36SAndroid Build Coastguard Worker// append the supplied flags files to the corresponding category in this map.
551*333d2b36SAndroid Build Coastguard Workerfunc (s FlagFilesByCategory) append(other FlagFilesByCategory) {
552*333d2b36SAndroid Build Coastguard Worker	for _, category := range HiddenAPIFlagFileCategories {
553*333d2b36SAndroid Build Coastguard Worker		s[category] = append(s[category], other[category]...)
554*333d2b36SAndroid Build Coastguard Worker	}
555*333d2b36SAndroid Build Coastguard Worker}
556*333d2b36SAndroid Build Coastguard Worker
557*333d2b36SAndroid Build Coastguard Worker// sort the paths for each category in this map.
558*333d2b36SAndroid Build Coastguard Workerfunc (s FlagFilesByCategory) sort() {
559*333d2b36SAndroid Build Coastguard Worker	for category, value := range s {
560*333d2b36SAndroid Build Coastguard Worker		s[category] = android.SortedUniquePaths(value)
561*333d2b36SAndroid Build Coastguard Worker	}
562*333d2b36SAndroid Build Coastguard Worker}
563*333d2b36SAndroid Build Coastguard Worker
564*333d2b36SAndroid Build Coastguard Worker// HiddenAPIInfo contains information provided by the hidden API processing.
565*333d2b36SAndroid Build Coastguard Worker//
566*333d2b36SAndroid Build Coastguard Worker// That includes paths resolved from HiddenAPIFlagFileProperties and also generated by hidden API
567*333d2b36SAndroid Build Coastguard Worker// processing.
568*333d2b36SAndroid Build Coastguard Workertype HiddenAPIInfo struct {
569*333d2b36SAndroid Build Coastguard Worker	// FlagFilesByCategory maps from the flag file category to the paths containing information for
570*333d2b36SAndroid Build Coastguard Worker	// that category.
571*333d2b36SAndroid Build Coastguard Worker	FlagFilesByCategory FlagFilesByCategory
572*333d2b36SAndroid Build Coastguard Worker
573*333d2b36SAndroid Build Coastguard Worker	// The paths to the stub dex jars for each of the *HiddenAPIScope in hiddenAPIScopes provided by
574*333d2b36SAndroid Build Coastguard Worker	// this fragment and the fragments on which this depends.
575*333d2b36SAndroid Build Coastguard Worker	TransitiveStubDexJarsByScope StubDexJarsByModule
576*333d2b36SAndroid Build Coastguard Worker
577*333d2b36SAndroid Build Coastguard Worker	// The output from the hidden API processing needs to be made available to other modules.
578*333d2b36SAndroid Build Coastguard Worker	HiddenAPIFlagOutput
579*333d2b36SAndroid Build Coastguard Worker}
580*333d2b36SAndroid Build Coastguard Worker
581*333d2b36SAndroid Build Coastguard Workerfunc newHiddenAPIInfo() *HiddenAPIInfo {
582*333d2b36SAndroid Build Coastguard Worker	info := HiddenAPIInfo{
583*333d2b36SAndroid Build Coastguard Worker		FlagFilesByCategory:          FlagFilesByCategory{},
584*333d2b36SAndroid Build Coastguard Worker		TransitiveStubDexJarsByScope: StubDexJarsByModule{},
585*333d2b36SAndroid Build Coastguard Worker	}
586*333d2b36SAndroid Build Coastguard Worker	return &info
587*333d2b36SAndroid Build Coastguard Worker}
588*333d2b36SAndroid Build Coastguard Worker
589*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIInfo) mergeFromFragmentDeps(ctx android.ModuleContext, fragments []android.Module) {
590*333d2b36SAndroid Build Coastguard Worker	// Merge all the information from the fragments. The fragments form a DAG so it is possible that
591*333d2b36SAndroid Build Coastguard Worker	// this will introduce duplicates so they will be resolved after processing all the fragments.
592*333d2b36SAndroid Build Coastguard Worker	for _, fragment := range fragments {
593*333d2b36SAndroid Build Coastguard Worker		if info, ok := android.OtherModuleProvider(ctx, fragment, HiddenAPIInfoProvider); ok {
594*333d2b36SAndroid Build Coastguard Worker			i.TransitiveStubDexJarsByScope.addStubDexJarsByModule(info.TransitiveStubDexJarsByScope)
595*333d2b36SAndroid Build Coastguard Worker		}
596*333d2b36SAndroid Build Coastguard Worker	}
597*333d2b36SAndroid Build Coastguard Worker}
598*333d2b36SAndroid Build Coastguard Worker
599*333d2b36SAndroid Build Coastguard Worker// StubFlagSubset returns a SignatureCsvSubset that contains a path to a filtered-stub-flags.csv
600*333d2b36SAndroid Build Coastguard Worker// file and a path to a signature-patterns.csv file that defines a subset of the monolithic stub
601*333d2b36SAndroid Build Coastguard Worker// flags file, i.e. out/soong/hiddenapi/hiddenapi-stub-flags.txt, against which it will be compared.
602*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIInfo) StubFlagSubset() SignatureCsvSubset {
603*333d2b36SAndroid Build Coastguard Worker	return SignatureCsvSubset{i.FilteredStubFlagsPath, i.SignaturePatternsPath}
604*333d2b36SAndroid Build Coastguard Worker}
605*333d2b36SAndroid Build Coastguard Worker
606*333d2b36SAndroid Build Coastguard Worker// FlagSubset returns a SignatureCsvSubset that contains a path to a filtered-flags.csv file and a
607*333d2b36SAndroid Build Coastguard Worker// path to a signature-patterns.csv file that defines a subset of the monolithic flags file, i.e.
608*333d2b36SAndroid Build Coastguard Worker// out/soong/hiddenapi/hiddenapi-flags.csv, against which it will be compared.
609*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIInfo) FlagSubset() SignatureCsvSubset {
610*333d2b36SAndroid Build Coastguard Worker	return SignatureCsvSubset{i.FilteredFlagsPath, i.SignaturePatternsPath}
611*333d2b36SAndroid Build Coastguard Worker}
612*333d2b36SAndroid Build Coastguard Worker
613*333d2b36SAndroid Build Coastguard Workervar HiddenAPIInfoProvider = blueprint.NewProvider[HiddenAPIInfo]()
614*333d2b36SAndroid Build Coastguard Worker
615*333d2b36SAndroid Build Coastguard Worker// HiddenAPIInfoForSdk contains information provided by the hidden API processing for use
616*333d2b36SAndroid Build Coastguard Worker// by the sdk snapshot.
617*333d2b36SAndroid Build Coastguard Worker//
618*333d2b36SAndroid Build Coastguard Worker// That includes paths resolved from HiddenAPIFlagFileProperties and also generated by hidden API
619*333d2b36SAndroid Build Coastguard Worker// processing.
620*333d2b36SAndroid Build Coastguard Workertype HiddenAPIInfoForSdk struct {
621*333d2b36SAndroid Build Coastguard Worker	// FlagFilesByCategory maps from the flag file category to the paths containing information for
622*333d2b36SAndroid Build Coastguard Worker	// that category.
623*333d2b36SAndroid Build Coastguard Worker	FlagFilesByCategory FlagFilesByCategory
624*333d2b36SAndroid Build Coastguard Worker
625*333d2b36SAndroid Build Coastguard Worker	// The output from the hidden API processing needs to be made available to other modules.
626*333d2b36SAndroid Build Coastguard Worker	HiddenAPIFlagOutput
627*333d2b36SAndroid Build Coastguard Worker}
628*333d2b36SAndroid Build Coastguard Worker
629*333d2b36SAndroid Build Coastguard Worker// Provides hidden API info for the sdk snapshot.
630*333d2b36SAndroid Build Coastguard Workervar HiddenAPIInfoForSdkProvider = blueprint.NewProvider[HiddenAPIInfoForSdk]()
631*333d2b36SAndroid Build Coastguard Worker
632*333d2b36SAndroid Build Coastguard Worker// ModuleStubDexJars contains the stub dex jars provided by a single module.
633*333d2b36SAndroid Build Coastguard Worker//
634*333d2b36SAndroid Build Coastguard Worker// It maps a *HiddenAPIScope to the path to stub dex jars appropriate for that scope. See
635*333d2b36SAndroid Build Coastguard Worker// hiddenAPIScopes for a list of the acceptable *HiddenAPIScope values.
636*333d2b36SAndroid Build Coastguard Workertype ModuleStubDexJars map[*HiddenAPIScope]android.Path
637*333d2b36SAndroid Build Coastguard Worker
638*333d2b36SAndroid Build Coastguard Worker// stubDexJarForWidestAPIScope returns the stub dex jars for the widest API scope provided by this
639*333d2b36SAndroid Build Coastguard Worker// map.
640*333d2b36SAndroid Build Coastguard Worker//
641*333d2b36SAndroid Build Coastguard Worker// The relative width of APIs is determined by their order in hiddenAPIScopes.
642*333d2b36SAndroid Build Coastguard Workerfunc (s ModuleStubDexJars) stubDexJarForWidestAPIScope() android.Path {
643*333d2b36SAndroid Build Coastguard Worker	for i := len(hiddenAPIScopes) - 1; i >= 0; i-- {
644*333d2b36SAndroid Build Coastguard Worker		apiScope := hiddenAPIScopes[i]
645*333d2b36SAndroid Build Coastguard Worker		if stubsForAPIScope, ok := s[apiScope]; ok {
646*333d2b36SAndroid Build Coastguard Worker			return stubsForAPIScope
647*333d2b36SAndroid Build Coastguard Worker		}
648*333d2b36SAndroid Build Coastguard Worker	}
649*333d2b36SAndroid Build Coastguard Worker
650*333d2b36SAndroid Build Coastguard Worker	return nil
651*333d2b36SAndroid Build Coastguard Worker}
652*333d2b36SAndroid Build Coastguard Worker
653*333d2b36SAndroid Build Coastguard Worker// StubDexJarsByModule contains the stub dex jars provided by a set of modules.
654*333d2b36SAndroid Build Coastguard Worker//
655*333d2b36SAndroid Build Coastguard Worker// It maps a module name to the path to the stub dex jars provided by that module.
656*333d2b36SAndroid Build Coastguard Workertype StubDexJarsByModule map[string]ModuleStubDexJars
657*333d2b36SAndroid Build Coastguard Worker
658*333d2b36SAndroid Build Coastguard Worker// addStubDexJar adds a stub dex jar path provided by the specified module for the specified scope.
659*333d2b36SAndroid Build Coastguard Workerfunc (s StubDexJarsByModule) addStubDexJar(ctx android.ModuleContext, module android.Module, scope *HiddenAPIScope, stubDexJar android.Path) {
660*333d2b36SAndroid Build Coastguard Worker	name := android.RemoveOptionalPrebuiltPrefix(module.Name())
661*333d2b36SAndroid Build Coastguard Worker
662*333d2b36SAndroid Build Coastguard Worker	// Each named module provides one dex jar for each scope. However, in some cases different API
663*333d2b36SAndroid Build Coastguard Worker	// versions of a single classes are provided by separate modules. e.g. the core platform
664*333d2b36SAndroid Build Coastguard Worker	// version of java.lang.Object is provided by the legacy.art.module.platform.api module but the
665*333d2b36SAndroid Build Coastguard Worker	// public version is provided by the art.module.public.api module. In those cases it is necessary
666*333d2b36SAndroid Build Coastguard Worker	// to treat all those modules as they were the same name, otherwise it will result in multiple
667*333d2b36SAndroid Build Coastguard Worker	// definitions of a single class being passed to hidden API processing which will cause an error.
668*333d2b36SAndroid Build Coastguard Worker	if name == scope.nonUpdatablePrebuiltModule || name == scope.nonUpdatableSourceModule || name == scope.nonUpdatableFromTextModule {
669*333d2b36SAndroid Build Coastguard Worker		// Treat all *android-non-updatable* modules as if they were part of an android-non-updatable
670*333d2b36SAndroid Build Coastguard Worker		// java_sdk_library.
671*333d2b36SAndroid Build Coastguard Worker		// TODO(b/192067200): Remove once android-non-updatable is a java_sdk_library or equivalent.
672*333d2b36SAndroid Build Coastguard Worker		name = "android-non-updatable"
673*333d2b36SAndroid Build Coastguard Worker	} else if name == "legacy.art.module.platform.api" {
674*333d2b36SAndroid Build Coastguard Worker		// Treat legacy.art.module.platform.api as if it was an API scope provided by the
675*333d2b36SAndroid Build Coastguard Worker		// art.module.public.api java_sdk_library which will be the case once the former has been
676*333d2b36SAndroid Build Coastguard Worker		// migrated to a module_lib API.
677*333d2b36SAndroid Build Coastguard Worker		name = "art.module.public.api"
678*333d2b36SAndroid Build Coastguard Worker	} else if name == "legacy.i18n.module.platform.api" {
679*333d2b36SAndroid Build Coastguard Worker		// Treat legacy.i18n.module.platform.api as if it was an API scope provided by the
680*333d2b36SAndroid Build Coastguard Worker		// i18n.module.public.api java_sdk_library which will be the case once the former has been
681*333d2b36SAndroid Build Coastguard Worker		// migrated to a module_lib API.
682*333d2b36SAndroid Build Coastguard Worker		name = "i18n.module.public.api"
683*333d2b36SAndroid Build Coastguard Worker	} else if name == "conscrypt.module.platform.api" {
684*333d2b36SAndroid Build Coastguard Worker		// Treat conscrypt.module.platform.api as if it was an API scope provided by the
685*333d2b36SAndroid Build Coastguard Worker		// conscrypt.module.public.api java_sdk_library which will be the case once the former has been
686*333d2b36SAndroid Build Coastguard Worker		// migrated to a module_lib API.
687*333d2b36SAndroid Build Coastguard Worker		name = "conscrypt.module.public.api"
688*333d2b36SAndroid Build Coastguard Worker	} else if d, ok := module.(SdkLibraryComponentDependency); ok {
689*333d2b36SAndroid Build Coastguard Worker		sdkLibraryName := d.SdkLibraryName()
690*333d2b36SAndroid Build Coastguard Worker		if sdkLibraryName != nil {
691*333d2b36SAndroid Build Coastguard Worker			// The module is a component of a java_sdk_library so use the name of the java_sdk_library.
692*333d2b36SAndroid Build Coastguard Worker			// e.g. if this module is `foo.system.stubs` and is part of the `foo` java_sdk_library then
693*333d2b36SAndroid Build Coastguard Worker			// use `foo` as the name.
694*333d2b36SAndroid Build Coastguard Worker			name = *sdkLibraryName
695*333d2b36SAndroid Build Coastguard Worker		}
696*333d2b36SAndroid Build Coastguard Worker	}
697*333d2b36SAndroid Build Coastguard Worker	stubDexJarsByScope := s[name]
698*333d2b36SAndroid Build Coastguard Worker	if stubDexJarsByScope == nil {
699*333d2b36SAndroid Build Coastguard Worker		stubDexJarsByScope = ModuleStubDexJars{}
700*333d2b36SAndroid Build Coastguard Worker		s[name] = stubDexJarsByScope
701*333d2b36SAndroid Build Coastguard Worker	}
702*333d2b36SAndroid Build Coastguard Worker	stubDexJarsByScope[scope] = stubDexJar
703*333d2b36SAndroid Build Coastguard Worker}
704*333d2b36SAndroid Build Coastguard Worker
705*333d2b36SAndroid Build Coastguard Worker// addStubDexJarsByModule adds the stub dex jars in the supplied StubDexJarsByModule to this map.
706*333d2b36SAndroid Build Coastguard Workerfunc (s StubDexJarsByModule) addStubDexJarsByModule(other StubDexJarsByModule) {
707*333d2b36SAndroid Build Coastguard Worker	for module, stubDexJarsByScope := range other {
708*333d2b36SAndroid Build Coastguard Worker		s[module] = stubDexJarsByScope
709*333d2b36SAndroid Build Coastguard Worker	}
710*333d2b36SAndroid Build Coastguard Worker}
711*333d2b36SAndroid Build Coastguard Worker
712*333d2b36SAndroid Build Coastguard Worker// StubDexJarsForWidestAPIScope returns a list of stub dex jars containing the widest API scope
713*333d2b36SAndroid Build Coastguard Worker// provided by each module.
714*333d2b36SAndroid Build Coastguard Worker//
715*333d2b36SAndroid Build Coastguard Worker// The relative width of APIs is determined by their order in hiddenAPIScopes.
716*333d2b36SAndroid Build Coastguard Workerfunc (s StubDexJarsByModule) StubDexJarsForWidestAPIScope() android.Paths {
717*333d2b36SAndroid Build Coastguard Worker	stubDexJars := android.Paths{}
718*333d2b36SAndroid Build Coastguard Worker	modules := android.SortedKeys(s)
719*333d2b36SAndroid Build Coastguard Worker	for _, module := range modules {
720*333d2b36SAndroid Build Coastguard Worker		stubDexJarsByScope := s[module]
721*333d2b36SAndroid Build Coastguard Worker
722*333d2b36SAndroid Build Coastguard Worker		stubDexJars = append(stubDexJars, stubDexJarsByScope.stubDexJarForWidestAPIScope())
723*333d2b36SAndroid Build Coastguard Worker	}
724*333d2b36SAndroid Build Coastguard Worker
725*333d2b36SAndroid Build Coastguard Worker	return stubDexJars
726*333d2b36SAndroid Build Coastguard Worker}
727*333d2b36SAndroid Build Coastguard Worker
728*333d2b36SAndroid Build Coastguard Worker// StubDexJarsForScope returns a list of stub dex jars containing the stub dex jars provided by each
729*333d2b36SAndroid Build Coastguard Worker// module for the specified scope.
730*333d2b36SAndroid Build Coastguard Worker//
731*333d2b36SAndroid Build Coastguard Worker// If a module does not provide a stub dex jar for the supplied scope then it does not contribute to
732*333d2b36SAndroid Build Coastguard Worker// the returned list.
733*333d2b36SAndroid Build Coastguard Workerfunc (s StubDexJarsByModule) StubDexJarsForScope(scope *HiddenAPIScope) android.Paths {
734*333d2b36SAndroid Build Coastguard Worker	stubDexJars := android.Paths{}
735*333d2b36SAndroid Build Coastguard Worker	modules := android.SortedKeys(s)
736*333d2b36SAndroid Build Coastguard Worker	for _, module := range modules {
737*333d2b36SAndroid Build Coastguard Worker		stubDexJarsByScope := s[module]
738*333d2b36SAndroid Build Coastguard Worker		// Not every module will have the same set of
739*333d2b36SAndroid Build Coastguard Worker		if jars, ok := stubDexJarsByScope[scope]; ok {
740*333d2b36SAndroid Build Coastguard Worker			stubDexJars = append(stubDexJars, jars)
741*333d2b36SAndroid Build Coastguard Worker		}
742*333d2b36SAndroid Build Coastguard Worker	}
743*333d2b36SAndroid Build Coastguard Worker
744*333d2b36SAndroid Build Coastguard Worker	return stubDexJars
745*333d2b36SAndroid Build Coastguard Worker}
746*333d2b36SAndroid Build Coastguard Worker
747*333d2b36SAndroid Build Coastguard Workertype HiddenAPIPropertyInfo struct {
748*333d2b36SAndroid Build Coastguard Worker	// FlagFilesByCategory contains the flag files that override the initial flags that are derived
749*333d2b36SAndroid Build Coastguard Worker	// from the stub dex files.
750*333d2b36SAndroid Build Coastguard Worker	FlagFilesByCategory FlagFilesByCategory
751*333d2b36SAndroid Build Coastguard Worker
752*333d2b36SAndroid Build Coastguard Worker	// See HiddenAPIFlagFileProperties.Package_prefixes
753*333d2b36SAndroid Build Coastguard Worker	PackagePrefixes []string
754*333d2b36SAndroid Build Coastguard Worker
755*333d2b36SAndroid Build Coastguard Worker	// See HiddenAPIFlagFileProperties.Single_packages
756*333d2b36SAndroid Build Coastguard Worker	SinglePackages []string
757*333d2b36SAndroid Build Coastguard Worker
758*333d2b36SAndroid Build Coastguard Worker	// See HiddenAPIFlagFileProperties.Split_packages
759*333d2b36SAndroid Build Coastguard Worker	SplitPackages []string
760*333d2b36SAndroid Build Coastguard Worker}
761*333d2b36SAndroid Build Coastguard Worker
762*333d2b36SAndroid Build Coastguard Workervar hiddenAPIPropertyInfoProvider = blueprint.NewProvider[HiddenAPIPropertyInfo]()
763*333d2b36SAndroid Build Coastguard Worker
764*333d2b36SAndroid Build Coastguard Worker// newHiddenAPIPropertyInfo creates a new initialized HiddenAPIPropertyInfo struct.
765*333d2b36SAndroid Build Coastguard Workerfunc newHiddenAPIPropertyInfo() HiddenAPIPropertyInfo {
766*333d2b36SAndroid Build Coastguard Worker	return HiddenAPIPropertyInfo{
767*333d2b36SAndroid Build Coastguard Worker		FlagFilesByCategory: FlagFilesByCategory{},
768*333d2b36SAndroid Build Coastguard Worker	}
769*333d2b36SAndroid Build Coastguard Worker}
770*333d2b36SAndroid Build Coastguard Worker
771*333d2b36SAndroid Build Coastguard Worker// extractFlagFilesFromProperties extracts the paths to flag files that are specified in the
772*333d2b36SAndroid Build Coastguard Worker// supplied properties and stores them in this struct.
773*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIPropertyInfo) extractFlagFilesFromProperties(ctx android.ModuleContext, p *HiddenAPIFlagFileProperties) {
774*333d2b36SAndroid Build Coastguard Worker	for _, category := range HiddenAPIFlagFileCategories {
775*333d2b36SAndroid Build Coastguard Worker		paths := android.PathsForModuleSrc(ctx, category.propertyValueReader(p))
776*333d2b36SAndroid Build Coastguard Worker		i.FlagFilesByCategory[category] = paths
777*333d2b36SAndroid Build Coastguard Worker	}
778*333d2b36SAndroid Build Coastguard Worker}
779*333d2b36SAndroid Build Coastguard Worker
780*333d2b36SAndroid Build Coastguard Worker// extractPackageRulesFromProperties extracts the package rules that are specified in the supplied
781*333d2b36SAndroid Build Coastguard Worker// properties and stores them in this struct.
782*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIPropertyInfo) extractPackageRulesFromProperties(p *HiddenAPIPackageProperties) {
783*333d2b36SAndroid Build Coastguard Worker	i.PackagePrefixes = p.Hidden_api.Package_prefixes
784*333d2b36SAndroid Build Coastguard Worker	i.SinglePackages = p.Hidden_api.Single_packages
785*333d2b36SAndroid Build Coastguard Worker	i.SplitPackages = p.Hidden_api.Split_packages
786*333d2b36SAndroid Build Coastguard Worker}
787*333d2b36SAndroid Build Coastguard Worker
788*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIPropertyInfo) gatherPropertyInfo(ctx android.ModuleContext, contents []android.Module) {
789*333d2b36SAndroid Build Coastguard Worker	for _, module := range contents {
790*333d2b36SAndroid Build Coastguard Worker		if info, ok := android.OtherModuleProvider(ctx, module, hiddenAPIPropertyInfoProvider); ok {
791*333d2b36SAndroid Build Coastguard Worker			i.FlagFilesByCategory.append(info.FlagFilesByCategory)
792*333d2b36SAndroid Build Coastguard Worker			i.PackagePrefixes = append(i.PackagePrefixes, info.PackagePrefixes...)
793*333d2b36SAndroid Build Coastguard Worker			i.SinglePackages = append(i.SinglePackages, info.SinglePackages...)
794*333d2b36SAndroid Build Coastguard Worker			i.SplitPackages = append(i.SplitPackages, info.SplitPackages...)
795*333d2b36SAndroid Build Coastguard Worker		}
796*333d2b36SAndroid Build Coastguard Worker	}
797*333d2b36SAndroid Build Coastguard Worker
798*333d2b36SAndroid Build Coastguard Worker	// Dedup and sort the information to ensure consistent builds.
799*333d2b36SAndroid Build Coastguard Worker	i.FlagFilesByCategory.sort()
800*333d2b36SAndroid Build Coastguard Worker	i.PackagePrefixes = android.SortedUniqueStrings(i.PackagePrefixes)
801*333d2b36SAndroid Build Coastguard Worker	i.SinglePackages = android.SortedUniqueStrings(i.SinglePackages)
802*333d2b36SAndroid Build Coastguard Worker	i.SplitPackages = android.SortedUniqueStrings(i.SplitPackages)
803*333d2b36SAndroid Build Coastguard Worker}
804*333d2b36SAndroid Build Coastguard Worker
805*333d2b36SAndroid Build Coastguard Worker// HiddenAPIFlagInput encapsulates information obtained from a module and its dependencies that are
806*333d2b36SAndroid Build Coastguard Worker// needed for hidden API flag generation.
807*333d2b36SAndroid Build Coastguard Workertype HiddenAPIFlagInput struct {
808*333d2b36SAndroid Build Coastguard Worker	HiddenAPIPropertyInfo
809*333d2b36SAndroid Build Coastguard Worker
810*333d2b36SAndroid Build Coastguard Worker	// StubDexJarsByScope contains the stub dex jars for different *HiddenAPIScope and which determine
811*333d2b36SAndroid Build Coastguard Worker	// the initial flags for each dex member.
812*333d2b36SAndroid Build Coastguard Worker	StubDexJarsByScope StubDexJarsByModule
813*333d2b36SAndroid Build Coastguard Worker
814*333d2b36SAndroid Build Coastguard Worker	// DependencyStubDexJarsByScope contains the stub dex jars provided by the fragments on which this
815*333d2b36SAndroid Build Coastguard Worker	// depends. It is the result of merging HiddenAPIInfo.TransitiveStubDexJarsByScope from each
816*333d2b36SAndroid Build Coastguard Worker	// fragment on which this depends.
817*333d2b36SAndroid Build Coastguard Worker	DependencyStubDexJarsByScope StubDexJarsByModule
818*333d2b36SAndroid Build Coastguard Worker
819*333d2b36SAndroid Build Coastguard Worker	// AdditionalStubDexJarsByScope contains stub dex jars provided by other modules in addition to
820*333d2b36SAndroid Build Coastguard Worker	// the ones that are obtained from fragments on which this depends.
821*333d2b36SAndroid Build Coastguard Worker	//
822*333d2b36SAndroid Build Coastguard Worker	// These are kept separate from stub dex jars in HiddenAPIFlagInput.DependencyStubDexJarsByScope
823*333d2b36SAndroid Build Coastguard Worker	// as there are not propagated transitively to other fragments that depend on this.
824*333d2b36SAndroid Build Coastguard Worker	AdditionalStubDexJarsByScope StubDexJarsByModule
825*333d2b36SAndroid Build Coastguard Worker
826*333d2b36SAndroid Build Coastguard Worker	// RemovedTxtFiles is the list of removed.txt files provided by java_sdk_library modules that are
827*333d2b36SAndroid Build Coastguard Worker	// specified in the bootclasspath_fragment's stub_libs and contents properties.
828*333d2b36SAndroid Build Coastguard Worker	RemovedTxtFiles android.Paths
829*333d2b36SAndroid Build Coastguard Worker}
830*333d2b36SAndroid Build Coastguard Worker
831*333d2b36SAndroid Build Coastguard Worker// newHiddenAPIFlagInput creates a new initialized HiddenAPIFlagInput struct.
832*333d2b36SAndroid Build Coastguard Workerfunc newHiddenAPIFlagInput() HiddenAPIFlagInput {
833*333d2b36SAndroid Build Coastguard Worker	input := HiddenAPIFlagInput{
834*333d2b36SAndroid Build Coastguard Worker		HiddenAPIPropertyInfo:        newHiddenAPIPropertyInfo(),
835*333d2b36SAndroid Build Coastguard Worker		StubDexJarsByScope:           StubDexJarsByModule{},
836*333d2b36SAndroid Build Coastguard Worker		DependencyStubDexJarsByScope: StubDexJarsByModule{},
837*333d2b36SAndroid Build Coastguard Worker		AdditionalStubDexJarsByScope: StubDexJarsByModule{},
838*333d2b36SAndroid Build Coastguard Worker	}
839*333d2b36SAndroid Build Coastguard Worker
840*333d2b36SAndroid Build Coastguard Worker	return input
841*333d2b36SAndroid Build Coastguard Worker}
842*333d2b36SAndroid Build Coastguard Worker
843*333d2b36SAndroid Build Coastguard Worker// gatherStubLibInfo gathers information from the stub libs needed by hidden API processing from the
844*333d2b36SAndroid Build Coastguard Worker// dependencies added in hiddenAPIAddStubLibDependencies.
845*333d2b36SAndroid Build Coastguard Worker//
846*333d2b36SAndroid Build Coastguard Worker// That includes paths to the stub dex jars as well as paths to the *removed.txt files.
847*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, contents []android.Module) {
848*333d2b36SAndroid Build Coastguard Worker	addFromModule := func(ctx android.ModuleContext, module android.Module, apiScope *HiddenAPIScope) {
849*333d2b36SAndroid Build Coastguard Worker		sdkKind := apiScope.sdkKind
850*333d2b36SAndroid Build Coastguard Worker		dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module, sdkKind)
851*333d2b36SAndroid Build Coastguard Worker		if dexJar != nil {
852*333d2b36SAndroid Build Coastguard Worker			i.StubDexJarsByScope.addStubDexJar(ctx, module, apiScope, dexJar)
853*333d2b36SAndroid Build Coastguard Worker		}
854*333d2b36SAndroid Build Coastguard Worker
855*333d2b36SAndroid Build Coastguard Worker		if sdkLibrary, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
856*333d2b36SAndroid Build Coastguard Worker			removedTxtFile := sdkLibrary.RemovedTxtFiles[sdkKind]
857*333d2b36SAndroid Build Coastguard Worker			i.RemovedTxtFiles = append(i.RemovedTxtFiles, removedTxtFile.AsPaths()...)
858*333d2b36SAndroid Build Coastguard Worker		}
859*333d2b36SAndroid Build Coastguard Worker	}
860*333d2b36SAndroid Build Coastguard Worker
861*333d2b36SAndroid Build Coastguard Worker	// If the contents includes any java_sdk_library modules then add them to the stubs.
862*333d2b36SAndroid Build Coastguard Worker	for _, module := range contents {
863*333d2b36SAndroid Build Coastguard Worker		if _, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
864*333d2b36SAndroid Build Coastguard Worker			// Add information for every possible API scope needed by hidden API.
865*333d2b36SAndroid Build Coastguard Worker			for _, apiScope := range hiddenAPISdkLibrarySupportedScopes {
866*333d2b36SAndroid Build Coastguard Worker				addFromModule(ctx, module, apiScope)
867*333d2b36SAndroid Build Coastguard Worker			}
868*333d2b36SAndroid Build Coastguard Worker		}
869*333d2b36SAndroid Build Coastguard Worker	}
870*333d2b36SAndroid Build Coastguard Worker
871*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDeps(func(module android.Module) {
872*333d2b36SAndroid Build Coastguard Worker		tag := ctx.OtherModuleDependencyTag(module)
873*333d2b36SAndroid Build Coastguard Worker		if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok {
874*333d2b36SAndroid Build Coastguard Worker			apiScope := hiddenAPIStubsTag.apiScope
875*333d2b36SAndroid Build Coastguard Worker			if hiddenAPIStubsTag.fromAdditionalDependency {
876*333d2b36SAndroid Build Coastguard Worker				dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module, apiScope.sdkKind)
877*333d2b36SAndroid Build Coastguard Worker				if dexJar != nil {
878*333d2b36SAndroid Build Coastguard Worker					i.AdditionalStubDexJarsByScope.addStubDexJar(ctx, module, apiScope, dexJar)
879*333d2b36SAndroid Build Coastguard Worker				}
880*333d2b36SAndroid Build Coastguard Worker			} else {
881*333d2b36SAndroid Build Coastguard Worker				addFromModule(ctx, module, apiScope)
882*333d2b36SAndroid Build Coastguard Worker			}
883*333d2b36SAndroid Build Coastguard Worker		}
884*333d2b36SAndroid Build Coastguard Worker	})
885*333d2b36SAndroid Build Coastguard Worker
886*333d2b36SAndroid Build Coastguard Worker	// Normalize the paths, i.e. remove duplicates and sort.
887*333d2b36SAndroid Build Coastguard Worker	i.RemovedTxtFiles = android.SortedUniquePaths(i.RemovedTxtFiles)
888*333d2b36SAndroid Build Coastguard Worker}
889*333d2b36SAndroid Build Coastguard Worker
890*333d2b36SAndroid Build Coastguard Workerfunc (i *HiddenAPIFlagInput) transitiveStubDexJarsByScope() StubDexJarsByModule {
891*333d2b36SAndroid Build Coastguard Worker	transitive := i.DependencyStubDexJarsByScope
892*333d2b36SAndroid Build Coastguard Worker	transitive.addStubDexJarsByModule(i.StubDexJarsByScope)
893*333d2b36SAndroid Build Coastguard Worker	return transitive
894*333d2b36SAndroid Build Coastguard Worker}
895*333d2b36SAndroid Build Coastguard Worker
896*333d2b36SAndroid Build Coastguard Worker// HiddenAPIFlagOutput contains paths to output files from the hidden API flag generation for a
897*333d2b36SAndroid Build Coastguard Worker// bootclasspath_fragment module.
898*333d2b36SAndroid Build Coastguard Workertype HiddenAPIFlagOutput struct {
899*333d2b36SAndroid Build Coastguard Worker	// The path to the generated annotation-flags.csv file.
900*333d2b36SAndroid Build Coastguard Worker	AnnotationFlagsPath android.Path
901*333d2b36SAndroid Build Coastguard Worker
902*333d2b36SAndroid Build Coastguard Worker	// The path to the generated metadata.csv file.
903*333d2b36SAndroid Build Coastguard Worker	MetadataPath android.Path
904*333d2b36SAndroid Build Coastguard Worker
905*333d2b36SAndroid Build Coastguard Worker	// The path to the generated index.csv file.
906*333d2b36SAndroid Build Coastguard Worker	IndexPath android.Path
907*333d2b36SAndroid Build Coastguard Worker
908*333d2b36SAndroid Build Coastguard Worker	// The path to the generated stub-flags.csv file.
909*333d2b36SAndroid Build Coastguard Worker	StubFlagsPath android.Path
910*333d2b36SAndroid Build Coastguard Worker
911*333d2b36SAndroid Build Coastguard Worker	// The path to the generated all-flags.csv file.
912*333d2b36SAndroid Build Coastguard Worker	AllFlagsPath android.Path
913*333d2b36SAndroid Build Coastguard Worker
914*333d2b36SAndroid Build Coastguard Worker	// The path to the generated signature-patterns.txt file which defines the subset of the
915*333d2b36SAndroid Build Coastguard Worker	// monolithic hidden API files provided in this.
916*333d2b36SAndroid Build Coastguard Worker	SignaturePatternsPath android.Path
917*333d2b36SAndroid Build Coastguard Worker
918*333d2b36SAndroid Build Coastguard Worker	// The path to the generated filtered-stub-flags.csv file.
919*333d2b36SAndroid Build Coastguard Worker	FilteredStubFlagsPath android.Path
920*333d2b36SAndroid Build Coastguard Worker
921*333d2b36SAndroid Build Coastguard Worker	// The path to the generated filtered-flags.csv file.
922*333d2b36SAndroid Build Coastguard Worker	FilteredFlagsPath android.Path
923*333d2b36SAndroid Build Coastguard Worker}
924*333d2b36SAndroid Build Coastguard Worker
925*333d2b36SAndroid Build Coastguard Worker// bootDexJarByModule is a map from base module name (without prebuilt_ prefix) to the boot dex
926*333d2b36SAndroid Build Coastguard Worker// path.
927*333d2b36SAndroid Build Coastguard Workertype bootDexJarByModule map[string]android.Path
928*333d2b36SAndroid Build Coastguard Worker
929*333d2b36SAndroid Build Coastguard Worker// addPath adds the path for a module to the map.
930*333d2b36SAndroid Build Coastguard Workerfunc (b bootDexJarByModule) addPath(module android.Module, path android.Path) {
931*333d2b36SAndroid Build Coastguard Worker	b[android.RemoveOptionalPrebuiltPrefix(module.Name())] = path
932*333d2b36SAndroid Build Coastguard Worker}
933*333d2b36SAndroid Build Coastguard Worker
934*333d2b36SAndroid Build Coastguard Worker// bootDexJars returns the boot dex jar paths sorted by their keys.
935*333d2b36SAndroid Build Coastguard Workerfunc (b bootDexJarByModule) bootDexJars() android.Paths {
936*333d2b36SAndroid Build Coastguard Worker	paths := android.Paths{}
937*333d2b36SAndroid Build Coastguard Worker	for _, k := range android.SortedKeys(b) {
938*333d2b36SAndroid Build Coastguard Worker		paths = append(paths, b[k])
939*333d2b36SAndroid Build Coastguard Worker	}
940*333d2b36SAndroid Build Coastguard Worker	return paths
941*333d2b36SAndroid Build Coastguard Worker}
942*333d2b36SAndroid Build Coastguard Worker
943*333d2b36SAndroid Build Coastguard Worker// bootDexJarsWithoutCoverage returns the boot dex jar paths sorted by their keys without coverage
944*333d2b36SAndroid Build Coastguard Worker// libraries if present.
945*333d2b36SAndroid Build Coastguard Workerfunc (b bootDexJarByModule) bootDexJarsWithoutCoverage() android.Paths {
946*333d2b36SAndroid Build Coastguard Worker	paths := android.Paths{}
947*333d2b36SAndroid Build Coastguard Worker	for _, k := range android.SortedKeys(b) {
948*333d2b36SAndroid Build Coastguard Worker		if k == "jacocoagent" {
949*333d2b36SAndroid Build Coastguard Worker			continue
950*333d2b36SAndroid Build Coastguard Worker		}
951*333d2b36SAndroid Build Coastguard Worker		paths = append(paths, b[k])
952*333d2b36SAndroid Build Coastguard Worker	}
953*333d2b36SAndroid Build Coastguard Worker	return paths
954*333d2b36SAndroid Build Coastguard Worker}
955*333d2b36SAndroid Build Coastguard Worker
956*333d2b36SAndroid Build Coastguard Worker// HiddenAPIOutput encapsulates the output from the hidden API processing.
957*333d2b36SAndroid Build Coastguard Workertype HiddenAPIOutput struct {
958*333d2b36SAndroid Build Coastguard Worker	HiddenAPIFlagOutput
959*333d2b36SAndroid Build Coastguard Worker
960*333d2b36SAndroid Build Coastguard Worker	// The map from base module name to the path to the encoded boot dex file.
961*333d2b36SAndroid Build Coastguard Worker	// This field is not available in prebuilt apexes
962*333d2b36SAndroid Build Coastguard Worker	EncodedBootDexFilesByModule bootDexJarByModule
963*333d2b36SAndroid Build Coastguard Worker}
964*333d2b36SAndroid Build Coastguard Worker
965*333d2b36SAndroid Build Coastguard Worker// pathForValidation creates a path of the same type as the supplied type but with a name of
966*333d2b36SAndroid Build Coastguard Worker// <path>.valid.
967*333d2b36SAndroid Build Coastguard Worker//
968*333d2b36SAndroid Build Coastguard Worker// e.g. If path is an OutputPath for out/soong/hiddenapi/hiddenapi-flags.csv then this will return
969*333d2b36SAndroid Build Coastguard Worker// an OutputPath for out/soong/hiddenapi/hiddenapi-flags.csv.valid
970*333d2b36SAndroid Build Coastguard Workerfunc pathForValidation(ctx android.PathContext, path android.WritablePath) android.WritablePath {
971*333d2b36SAndroid Build Coastguard Worker	extWithoutLeadingDot := strings.TrimPrefix(path.Ext(), ".")
972*333d2b36SAndroid Build Coastguard Worker	return path.ReplaceExtension(ctx, extWithoutLeadingDot+".valid")
973*333d2b36SAndroid Build Coastguard Worker}
974*333d2b36SAndroid Build Coastguard Worker
975*333d2b36SAndroid Build Coastguard Worker// buildRuleToGenerateHiddenApiFlags creates a rule to create the monolithic hidden API flags from
976*333d2b36SAndroid Build Coastguard Worker// the flags from all the modules, the stub flags, augmented with some additional configuration
977*333d2b36SAndroid Build Coastguard Worker// files.
978*333d2b36SAndroid Build Coastguard Worker//
979*333d2b36SAndroid Build Coastguard Worker// baseFlagsPath is the path to the flags file containing all the information from the stubs plus
980*333d2b36SAndroid Build Coastguard Worker// an entry for every single member in the dex implementation jars of the individual modules. Every
981*333d2b36SAndroid Build Coastguard Worker// signature in any of the other files MUST be included in this file.
982*333d2b36SAndroid Build Coastguard Worker//
983*333d2b36SAndroid Build Coastguard Worker// annotationFlags is the path to the annotation flags file generated from annotation information
984*333d2b36SAndroid Build Coastguard Worker// in each module.
985*333d2b36SAndroid Build Coastguard Worker//
986*333d2b36SAndroid Build Coastguard Worker// hiddenAPIInfo is a struct containing paths to files that augment the information provided by
987*333d2b36SAndroid Build Coastguard Worker// the annotationFlags.
988*333d2b36SAndroid Build Coastguard Workerfunc buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc string,
989*333d2b36SAndroid Build Coastguard Worker	outputPath android.WritablePath, baseFlagsPath android.Path, annotationFlagPaths android.Paths,
990*333d2b36SAndroid Build Coastguard Worker	flagFilesByCategory FlagFilesByCategory, flagSubsets SignatureCsvSubsets, generatedRemovedDexSignatures android.OptionalPath) {
991*333d2b36SAndroid Build Coastguard Worker
992*333d2b36SAndroid Build Coastguard Worker	// Create the rule that will generate the flag files.
993*333d2b36SAndroid Build Coastguard Worker	tempPath := tempPathForRestat(ctx, outputPath)
994*333d2b36SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
995*333d2b36SAndroid Build Coastguard Worker	command := rule.Command().
996*333d2b36SAndroid Build Coastguard Worker		BuiltTool("generate_hiddenapi_lists").
997*333d2b36SAndroid Build Coastguard Worker		FlagWithInput("--csv ", baseFlagsPath).
998*333d2b36SAndroid Build Coastguard Worker		Inputs(annotationFlagPaths).
999*333d2b36SAndroid Build Coastguard Worker		FlagWithOutput("--output ", tempPath)
1000*333d2b36SAndroid Build Coastguard Worker
1001*333d2b36SAndroid Build Coastguard Worker	// Add the options for the different categories of flag files.
1002*333d2b36SAndroid Build Coastguard Worker	for _, category := range HiddenAPIFlagFileCategories {
1003*333d2b36SAndroid Build Coastguard Worker		paths := flagFilesByCategory[category]
1004*333d2b36SAndroid Build Coastguard Worker		for _, path := range paths {
1005*333d2b36SAndroid Build Coastguard Worker			category.commandMutator(command, path)
1006*333d2b36SAndroid Build Coastguard Worker		}
1007*333d2b36SAndroid Build Coastguard Worker	}
1008*333d2b36SAndroid Build Coastguard Worker
1009*333d2b36SAndroid Build Coastguard Worker	// If available then pass the automatically generated file containing dex signatures of removed
1010*333d2b36SAndroid Build Coastguard Worker	// API members to the rule so they can be marked as removed.
1011*333d2b36SAndroid Build Coastguard Worker	if generatedRemovedDexSignatures.Valid() {
1012*333d2b36SAndroid Build Coastguard Worker		hiddenAPIFlagFileCategoryRemoved.commandMutator(command, generatedRemovedDexSignatures.Path())
1013*333d2b36SAndroid Build Coastguard Worker	}
1014*333d2b36SAndroid Build Coastguard Worker
1015*333d2b36SAndroid Build Coastguard Worker	commitChangeForRestat(rule, tempPath, outputPath)
1016*333d2b36SAndroid Build Coastguard Worker
1017*333d2b36SAndroid Build Coastguard Worker	// If there are flag files that have been generated by fragments on which this depends then use
1018*333d2b36SAndroid Build Coastguard Worker	// them to validate the flag file generated by the rules created by this method.
1019*333d2b36SAndroid Build Coastguard Worker	if !ctx.Config().DisableVerifyOverlaps() && len(flagSubsets) > 0 {
1020*333d2b36SAndroid Build Coastguard Worker		validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, flagSubsets,
1021*333d2b36SAndroid Build Coastguard Worker			HIDDENAPI_FLAGS_CSV_IMPL_FLAGS)
1022*333d2b36SAndroid Build Coastguard Worker
1023*333d2b36SAndroid Build Coastguard Worker		// Add the file that indicates that the file generated by this is valid.
1024*333d2b36SAndroid Build Coastguard Worker		//
1025*333d2b36SAndroid Build Coastguard Worker		// This will cause the validation rule above to be run any time that the output of this rule
1026*333d2b36SAndroid Build Coastguard Worker		// changes but the validation will run in parallel with other rules that depend on this file.
1027*333d2b36SAndroid Build Coastguard Worker		command.Validation(validFile)
1028*333d2b36SAndroid Build Coastguard Worker	}
1029*333d2b36SAndroid Build Coastguard Worker
1030*333d2b36SAndroid Build Coastguard Worker	rule.Build(name, desc)
1031*333d2b36SAndroid Build Coastguard Worker}
1032*333d2b36SAndroid Build Coastguard Worker
1033*333d2b36SAndroid Build Coastguard Worker// SignatureCsvSubset describes a subset of a monolithic flags file, i.e. either
1034*333d2b36SAndroid Build Coastguard Worker// out/soong/hiddenapi/hiddenapi-stub-flags.txt or out/soong/hiddenapi/hiddenapi-flags.csv
1035*333d2b36SAndroid Build Coastguard Workertype SignatureCsvSubset struct {
1036*333d2b36SAndroid Build Coastguard Worker	// The path to the CSV file containing hidden API flags.
1037*333d2b36SAndroid Build Coastguard Worker	//
1038*333d2b36SAndroid Build Coastguard Worker	// It has the dex member signature as the first column, with flags, one per column, in the
1039*333d2b36SAndroid Build Coastguard Worker	// subsequent columns.
1040*333d2b36SAndroid Build Coastguard Worker	CsvFile android.Path
1041*333d2b36SAndroid Build Coastguard Worker
1042*333d2b36SAndroid Build Coastguard Worker	// The path to the CSV file containing the signature patterns.
1043*333d2b36SAndroid Build Coastguard Worker	//
1044*333d2b36SAndroid Build Coastguard Worker	// It is a single column CSV file with the column containing a signature pattern.
1045*333d2b36SAndroid Build Coastguard Worker	SignaturePatternsFile android.Path
1046*333d2b36SAndroid Build Coastguard Worker}
1047*333d2b36SAndroid Build Coastguard Worker
1048*333d2b36SAndroid Build Coastguard Workertype SignatureCsvSubsets []SignatureCsvSubset
1049*333d2b36SAndroid Build Coastguard Worker
1050*333d2b36SAndroid Build Coastguard Workerfunc (s SignatureCsvSubsets) RelativeToTop() []string {
1051*333d2b36SAndroid Build Coastguard Worker	result := []string{}
1052*333d2b36SAndroid Build Coastguard Worker	for _, subset := range s {
1053*333d2b36SAndroid Build Coastguard Worker		result = append(result, fmt.Sprintf("%s:%s", subset.CsvFile.RelativeToTop(), subset.SignaturePatternsFile.RelativeToTop()))
1054*333d2b36SAndroid Build Coastguard Worker	}
1055*333d2b36SAndroid Build Coastguard Worker	return result
1056*333d2b36SAndroid Build Coastguard Worker}
1057*333d2b36SAndroid Build Coastguard Worker
1058*333d2b36SAndroid Build Coastguard Worker// buildRuleSignaturePatternsFile creates a rule to generate a file containing the set of signature
1059*333d2b36SAndroid Build Coastguard Worker// patterns that will select a subset of the monolithic flags.
1060*333d2b36SAndroid Build Coastguard Workerfunc buildRuleSignaturePatternsFile(
1061*333d2b36SAndroid Build Coastguard Worker	ctx android.ModuleContext, flagsPath android.Path,
1062*333d2b36SAndroid Build Coastguard Worker	splitPackages []string, packagePrefixes []string, singlePackages []string,
1063*333d2b36SAndroid Build Coastguard Worker	suffix string) android.Path {
1064*333d2b36SAndroid Build Coastguard Worker	hiddenApiSubDir := "modular-hiddenapi" + suffix
1065*333d2b36SAndroid Build Coastguard Worker
1066*333d2b36SAndroid Build Coastguard Worker	patternsFile := android.PathForModuleOut(ctx, hiddenApiSubDir, "signature-patterns.csv")
1067*333d2b36SAndroid Build Coastguard Worker	// Create a rule to validate the output from the following rule.
1068*333d2b36SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
1069*333d2b36SAndroid Build Coastguard Worker
1070*333d2b36SAndroid Build Coastguard Worker	// Quote any * in the packages to avoid them being expanded by the shell.
1071*333d2b36SAndroid Build Coastguard Worker	quotedSplitPackages := []string{}
1072*333d2b36SAndroid Build Coastguard Worker	for _, pkg := range splitPackages {
1073*333d2b36SAndroid Build Coastguard Worker		quotedSplitPackages = append(quotedSplitPackages, strings.ReplaceAll(pkg, "*", "\\*"))
1074*333d2b36SAndroid Build Coastguard Worker	}
1075*333d2b36SAndroid Build Coastguard Worker
1076*333d2b36SAndroid Build Coastguard Worker	rule.Command().
1077*333d2b36SAndroid Build Coastguard Worker		BuiltTool("signature_patterns").
1078*333d2b36SAndroid Build Coastguard Worker		FlagWithInput("--flags ", flagsPath).
1079*333d2b36SAndroid Build Coastguard Worker		FlagForEachArg("--split-package ", quotedSplitPackages).
1080*333d2b36SAndroid Build Coastguard Worker		FlagForEachArg("--package-prefix ", packagePrefixes).
1081*333d2b36SAndroid Build Coastguard Worker		FlagForEachArg("--single-package ", singlePackages).
1082*333d2b36SAndroid Build Coastguard Worker		FlagWithOutput("--output ", patternsFile)
1083*333d2b36SAndroid Build Coastguard Worker	rule.Build("hiddenAPISignaturePatterns"+suffix, "hidden API signature patterns"+suffix)
1084*333d2b36SAndroid Build Coastguard Worker
1085*333d2b36SAndroid Build Coastguard Worker	return patternsFile
1086*333d2b36SAndroid Build Coastguard Worker}
1087*333d2b36SAndroid Build Coastguard Worker
1088*333d2b36SAndroid Build Coastguard Worker// buildRuleRemoveSignaturesWithImplementationFlags creates a rule that will remove signatures from
1089*333d2b36SAndroid Build Coastguard Worker// the input flags file which have only the implementation flags, i.e. are not part of an API.
1090*333d2b36SAndroid Build Coastguard Worker//
1091*333d2b36SAndroid Build Coastguard Worker// The implementationFlags specifies the set of default flags that identifies the signature of a
1092*333d2b36SAndroid Build Coastguard Worker// private, implementation only, member. Signatures that match those flags are removed from the
1093*333d2b36SAndroid Build Coastguard Worker// flags as they are implementation only.
1094*333d2b36SAndroid Build Coastguard Worker//
1095*333d2b36SAndroid Build Coastguard Worker// This is used to remove implementation only signatures from the signature files that are persisted
1096*333d2b36SAndroid Build Coastguard Worker// in the sdk snapshot as the sdk snapshots should not include implementation details. The
1097*333d2b36SAndroid Build Coastguard Worker// signatures generated by this method will be compared by the buildRuleValidateOverlappingCsvFiles
1098*333d2b36SAndroid Build Coastguard Worker// method which treats any missing signatures as if they were implementation only signatures.
1099*333d2b36SAndroid Build Coastguard Workerfunc buildRuleRemoveSignaturesWithImplementationFlags(ctx android.BuilderContext,
1100*333d2b36SAndroid Build Coastguard Worker	name string, desc string, inputPath android.Path, filteredPath android.WritablePath,
1101*333d2b36SAndroid Build Coastguard Worker	implementationFlags []string) {
1102*333d2b36SAndroid Build Coastguard Worker
1103*333d2b36SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
1104*333d2b36SAndroid Build Coastguard Worker	implementationFlagPattern := ""
1105*333d2b36SAndroid Build Coastguard Worker	for _, implementationFlag := range implementationFlags {
1106*333d2b36SAndroid Build Coastguard Worker		implementationFlagPattern = implementationFlagPattern + "," + implementationFlag
1107*333d2b36SAndroid Build Coastguard Worker	}
1108*333d2b36SAndroid Build Coastguard Worker	rule.Command().
1109*333d2b36SAndroid Build Coastguard Worker		Text(`grep -vE "^[^,]+` + implementationFlagPattern + `$"`).Input(inputPath).
1110*333d2b36SAndroid Build Coastguard Worker		Text(">").Output(filteredPath).
1111*333d2b36SAndroid Build Coastguard Worker		// Grep's exit code depends on whether it finds anything. It is 0 (build success) when it finds
1112*333d2b36SAndroid Build Coastguard Worker		// something and 1 (build failure) when it does not and 2 (when it encounters an error).
1113*333d2b36SAndroid Build Coastguard Worker		// However, while it is unlikely it is not an error if this does not find any matches. The
1114*333d2b36SAndroid Build Coastguard Worker		// following will only run if the grep does not find something and in that case it will treat
1115*333d2b36SAndroid Build Coastguard Worker		// an exit code of 1 as success and anything else as failure.
1116*333d2b36SAndroid Build Coastguard Worker		Text("|| test $? -eq 1")
1117*333d2b36SAndroid Build Coastguard Worker	rule.Build(name, desc)
1118*333d2b36SAndroid Build Coastguard Worker}
1119*333d2b36SAndroid Build Coastguard Worker
1120*333d2b36SAndroid Build Coastguard Worker// buildRuleValidateOverlappingCsvFiles checks that the modular CSV files, i.e. the files generated
1121*333d2b36SAndroid Build Coastguard Worker// by the individual bootclasspath_fragment modules are subsets of the monolithic CSV file.
1122*333d2b36SAndroid Build Coastguard Worker//
1123*333d2b36SAndroid Build Coastguard Worker// The implementationFlags specifies the set of default flags that identifies the signature of a
1124*333d2b36SAndroid Build Coastguard Worker// private, implementation only, member. A signature which is present in a monolithic flags subset
1125*333d2b36SAndroid Build Coastguard Worker// defined by SignatureCsvSubset but which is not present in the flags file from the corresponding
1126*333d2b36SAndroid Build Coastguard Worker// module is assumed to be an implementation only member and so must have these flags.
1127*333d2b36SAndroid Build Coastguard Workerfunc buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name string, desc string,
1128*333d2b36SAndroid Build Coastguard Worker	monolithicFilePath android.WritablePath, csvSubsets SignatureCsvSubsets,
1129*333d2b36SAndroid Build Coastguard Worker	implementationFlags []string) android.WritablePath {
1130*333d2b36SAndroid Build Coastguard Worker	// The file which is used to record that the flags file is valid.
1131*333d2b36SAndroid Build Coastguard Worker	validFile := pathForValidation(ctx, monolithicFilePath)
1132*333d2b36SAndroid Build Coastguard Worker
1133*333d2b36SAndroid Build Coastguard Worker	// Create a rule to validate the output from the following rule.
1134*333d2b36SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
1135*333d2b36SAndroid Build Coastguard Worker	command := rule.Command().
1136*333d2b36SAndroid Build Coastguard Worker		BuiltTool("verify_overlaps").
1137*333d2b36SAndroid Build Coastguard Worker		FlagWithInput("--monolithic-flags ", monolithicFilePath)
1138*333d2b36SAndroid Build Coastguard Worker
1139*333d2b36SAndroid Build Coastguard Worker	for _, subset := range csvSubsets {
1140*333d2b36SAndroid Build Coastguard Worker		command.
1141*333d2b36SAndroid Build Coastguard Worker			Flag("--module-flags ").
1142*333d2b36SAndroid Build Coastguard Worker			Textf("%s:%s", subset.CsvFile, subset.SignaturePatternsFile).
1143*333d2b36SAndroid Build Coastguard Worker			Implicit(subset.CsvFile).Implicit(subset.SignaturePatternsFile)
1144*333d2b36SAndroid Build Coastguard Worker	}
1145*333d2b36SAndroid Build Coastguard Worker
1146*333d2b36SAndroid Build Coastguard Worker	for _, implementationFlag := range implementationFlags {
1147*333d2b36SAndroid Build Coastguard Worker		command.FlagWithArg("--implementation-flag ", implementationFlag)
1148*333d2b36SAndroid Build Coastguard Worker	}
1149*333d2b36SAndroid Build Coastguard Worker
1150*333d2b36SAndroid Build Coastguard Worker	// If validation passes then update the file that records that.
1151*333d2b36SAndroid Build Coastguard Worker	command.Text("&& touch").Output(validFile)
1152*333d2b36SAndroid Build Coastguard Worker	rule.Build(name+"Validation", desc+" validation")
1153*333d2b36SAndroid Build Coastguard Worker
1154*333d2b36SAndroid Build Coastguard Worker	return validFile
1155*333d2b36SAndroid Build Coastguard Worker}
1156*333d2b36SAndroid Build Coastguard Worker
1157*333d2b36SAndroid Build Coastguard Worker// hiddenAPIFlagRulesForBootclasspathFragment will generate all the flags for a fragment of the
1158*333d2b36SAndroid Build Coastguard Worker// bootclasspath.
1159*333d2b36SAndroid Build Coastguard Worker//
1160*333d2b36SAndroid Build Coastguard Worker// It takes:
1161*333d2b36SAndroid Build Coastguard Worker// * Map from android.SdkKind to stub dex jar paths defining the API for that sdk kind.
1162*333d2b36SAndroid Build Coastguard Worker// * The list of modules that are the contents of the fragment.
1163*333d2b36SAndroid Build Coastguard Worker// * The additional manually curated flag files to use.
1164*333d2b36SAndroid Build Coastguard Worker//
1165*333d2b36SAndroid Build Coastguard Worker// It generates:
1166*333d2b36SAndroid Build Coastguard Worker// * stub-flags.csv
1167*333d2b36SAndroid Build Coastguard Worker// * annotation-flags.csv
1168*333d2b36SAndroid Build Coastguard Worker// * metadata.csv
1169*333d2b36SAndroid Build Coastguard Worker// * index.csv
1170*333d2b36SAndroid Build Coastguard Worker// * all-flags.csv
1171*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIFlagRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, contents []android.Module, input HiddenAPIFlagInput, suffix string) HiddenAPIFlagOutput {
1172*333d2b36SAndroid Build Coastguard Worker	hiddenApiSubDir := "modular-hiddenapi" + suffix
1173*333d2b36SAndroid Build Coastguard Worker
1174*333d2b36SAndroid Build Coastguard Worker	// Generate the stub-flags.csv.
1175*333d2b36SAndroid Build Coastguard Worker	stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv")
1176*333d2b36SAndroid Build Coastguard Worker	buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "modularHiddenAPIStubFlagsFile"+suffix, "modular hiddenapi stub flags", stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input, nil)
1177*333d2b36SAndroid Build Coastguard Worker
1178*333d2b36SAndroid Build Coastguard Worker	// Extract the classes jars from the contents.
1179*333d2b36SAndroid Build Coastguard Worker	classesJars := extractClassesJarsFromModules(contents)
1180*333d2b36SAndroid Build Coastguard Worker
1181*333d2b36SAndroid Build Coastguard Worker	// Generate the set of flags from the annotations in the source code.
1182*333d2b36SAndroid Build Coastguard Worker	annotationFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "annotation-flags.csv")
1183*333d2b36SAndroid Build Coastguard Worker	buildRuleToGenerateAnnotationFlags(ctx, "modular hiddenapi annotation flags"+suffix, classesJars, stubFlagsCSV, annotationFlagsCSV)
1184*333d2b36SAndroid Build Coastguard Worker
1185*333d2b36SAndroid Build Coastguard Worker	// Generate the metadata from the annotations in the source code.
1186*333d2b36SAndroid Build Coastguard Worker	metadataCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "metadata.csv")
1187*333d2b36SAndroid Build Coastguard Worker	buildRuleToGenerateMetadata(ctx, "modular hiddenapi metadata"+suffix, classesJars, stubFlagsCSV, metadataCSV)
1188*333d2b36SAndroid Build Coastguard Worker
1189*333d2b36SAndroid Build Coastguard Worker	// Generate the index file from the CSV files in the classes jars.
1190*333d2b36SAndroid Build Coastguard Worker	indexCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "index.csv")
1191*333d2b36SAndroid Build Coastguard Worker	buildRuleToGenerateIndex(ctx, "modular hiddenapi index"+suffix, classesJars, indexCSV)
1192*333d2b36SAndroid Build Coastguard Worker
1193*333d2b36SAndroid Build Coastguard Worker	// Removed APIs need to be marked and in order to do that the hiddenAPIInfo needs to specify files
1194*333d2b36SAndroid Build Coastguard Worker	// containing dex signatures of all the removed APIs. In the monolithic files that is done by
1195*333d2b36SAndroid Build Coastguard Worker	// manually combining all the removed.txt files for each API and then converting them to dex
1196*333d2b36SAndroid Build Coastguard Worker	// signatures, see the combined-removed-dex module. This does that automatically by using the
1197*333d2b36SAndroid Build Coastguard Worker	// *removed.txt files retrieved from the java_sdk_library modules that are specified in the
1198*333d2b36SAndroid Build Coastguard Worker	// stub_libs and contents properties of a bootclasspath_fragment.
1199*333d2b36SAndroid Build Coastguard Worker	removedDexSignatures := buildRuleToGenerateRemovedDexSignatures(ctx, suffix, input.RemovedTxtFiles)
1200*333d2b36SAndroid Build Coastguard Worker
1201*333d2b36SAndroid Build Coastguard Worker	// Generate the all-flags.csv which are the flags that will, in future, be encoded into the dex
1202*333d2b36SAndroid Build Coastguard Worker	// files.
1203*333d2b36SAndroid Build Coastguard Worker	allFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "all-flags.csv")
1204*333d2b36SAndroid Build Coastguard Worker	buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags"+suffix, "modular hiddenapi all flags"+suffix, allFlagsCSV, stubFlagsCSV, android.Paths{annotationFlagsCSV}, input.FlagFilesByCategory, nil, removedDexSignatures)
1205*333d2b36SAndroid Build Coastguard Worker
1206*333d2b36SAndroid Build Coastguard Worker	// Generate the filtered-stub-flags.csv file which contains the filtered stub flags that will be
1207*333d2b36SAndroid Build Coastguard Worker	// compared against the monolithic stub flags.
1208*333d2b36SAndroid Build Coastguard Worker	filteredStubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-stub-flags.csv")
1209*333d2b36SAndroid Build Coastguard Worker	buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredStubFlags"+suffix,
1210*333d2b36SAndroid Build Coastguard Worker		"modular hiddenapi filtered stub flags"+suffix, stubFlagsCSV, filteredStubFlagsCSV,
1211*333d2b36SAndroid Build Coastguard Worker		HIDDENAPI_STUB_FLAGS_IMPL_FLAGS)
1212*333d2b36SAndroid Build Coastguard Worker
1213*333d2b36SAndroid Build Coastguard Worker	// Generate the filtered-flags.csv file which contains the filtered flags that will be compared
1214*333d2b36SAndroid Build Coastguard Worker	// against the monolithic flags.
1215*333d2b36SAndroid Build Coastguard Worker	filteredFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-flags.csv")
1216*333d2b36SAndroid Build Coastguard Worker	buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredFlags"+suffix,
1217*333d2b36SAndroid Build Coastguard Worker		"modular hiddenapi filtered flags"+suffix, allFlagsCSV, filteredFlagsCSV,
1218*333d2b36SAndroid Build Coastguard Worker		HIDDENAPI_FLAGS_CSV_IMPL_FLAGS)
1219*333d2b36SAndroid Build Coastguard Worker
1220*333d2b36SAndroid Build Coastguard Worker	// Store the paths in the info for use by other modules and sdk snapshot generation.
1221*333d2b36SAndroid Build Coastguard Worker	return HiddenAPIFlagOutput{
1222*333d2b36SAndroid Build Coastguard Worker		AnnotationFlagsPath:   annotationFlagsCSV,
1223*333d2b36SAndroid Build Coastguard Worker		MetadataPath:          metadataCSV,
1224*333d2b36SAndroid Build Coastguard Worker		IndexPath:             indexCSV,
1225*333d2b36SAndroid Build Coastguard Worker		StubFlagsPath:         stubFlagsCSV,
1226*333d2b36SAndroid Build Coastguard Worker		AllFlagsPath:          allFlagsCSV,
1227*333d2b36SAndroid Build Coastguard Worker		FilteredStubFlagsPath: filteredStubFlagsCSV,
1228*333d2b36SAndroid Build Coastguard Worker		FilteredFlagsPath:     filteredFlagsCSV,
1229*333d2b36SAndroid Build Coastguard Worker	}
1230*333d2b36SAndroid Build Coastguard Worker}
1231*333d2b36SAndroid Build Coastguard Worker
1232*333d2b36SAndroid Build Coastguard Worker// hiddenAPIEncodeRulesForBootclasspathFragment generates rules to encode hidden API flags into the
1233*333d2b36SAndroid Build Coastguard Worker// dex jars in bootDexInfoByModule.
1234*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIEncodeRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, allFlagsCSV android.Path) bootDexJarByModule {
1235*333d2b36SAndroid Build Coastguard Worker	// Encode the flags into the boot dex files.
1236*333d2b36SAndroid Build Coastguard Worker	encodedBootDexJarsByModule := bootDexJarByModule{}
1237*333d2b36SAndroid Build Coastguard Worker	outputDir := android.PathForModuleOut(ctx, "hiddenapi-modular/encoded").OutputPath
1238*333d2b36SAndroid Build Coastguard Worker	for _, name := range android.SortedKeys(bootDexInfoByModule) {
1239*333d2b36SAndroid Build Coastguard Worker		bootDexInfo := bootDexInfoByModule[name]
1240*333d2b36SAndroid Build Coastguard Worker		unencodedDex := bootDexInfo.path
1241*333d2b36SAndroid Build Coastguard Worker		encodedDex := hiddenAPIEncodeDex(ctx, unencodedDex, allFlagsCSV, bootDexInfo.uncompressDex, bootDexInfo.minSdkVersion, outputDir)
1242*333d2b36SAndroid Build Coastguard Worker		encodedBootDexJarsByModule[name] = encodedDex
1243*333d2b36SAndroid Build Coastguard Worker	}
1244*333d2b36SAndroid Build Coastguard Worker	return encodedBootDexJarsByModule
1245*333d2b36SAndroid Build Coastguard Worker}
1246*333d2b36SAndroid Build Coastguard Worker
1247*333d2b36SAndroid Build Coastguard Workerfunc buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, suffix string, removedTxtFiles android.Paths) android.OptionalPath {
1248*333d2b36SAndroid Build Coastguard Worker	if len(removedTxtFiles) == 0 {
1249*333d2b36SAndroid Build Coastguard Worker		return android.OptionalPath{}
1250*333d2b36SAndroid Build Coastguard Worker	}
1251*333d2b36SAndroid Build Coastguard Worker
1252*333d2b36SAndroid Build Coastguard Worker	output := android.PathForModuleOut(ctx, "module-hiddenapi"+suffix, "removed-dex-signatures.txt")
1253*333d2b36SAndroid Build Coastguard Worker
1254*333d2b36SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
1255*333d2b36SAndroid Build Coastguard Worker	rule.Command().
1256*333d2b36SAndroid Build Coastguard Worker		BuiltTool("metalava").
1257*333d2b36SAndroid Build Coastguard Worker		Text("signature-to-dex").
1258*333d2b36SAndroid Build Coastguard Worker		Inputs(removedTxtFiles).
1259*333d2b36SAndroid Build Coastguard Worker		FlagWithOutput("--out ", output)
1260*333d2b36SAndroid Build Coastguard Worker	rule.Build("modular-hiddenapi-removed-dex-signatures"+suffix, "modular hiddenapi removed dex signatures"+suffix)
1261*333d2b36SAndroid Build Coastguard Worker	return android.OptionalPathForPath(output)
1262*333d2b36SAndroid Build Coastguard Worker}
1263*333d2b36SAndroid Build Coastguard Worker
1264*333d2b36SAndroid Build Coastguard Worker// extractBootDexJarsFromModules extracts the boot dex jars from the supplied modules.
1265*333d2b36SAndroid Build Coastguard Worker// This information can come from two mechanisms
1266*333d2b36SAndroid Build Coastguard Worker// 1. New: Direct deps to _selected_ apexes. The apexes contain a ApexExportsInfo
1267*333d2b36SAndroid Build Coastguard Worker// 2. Legacy: An edge to java_sdk_library(_import) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes
1268*333d2b36SAndroid Build Coastguard Worker// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2)
1269*333d2b36SAndroid Build Coastguard Workerfunc extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule {
1270*333d2b36SAndroid Build Coastguard Worker	bootDexJars := bootDexJarByModule{}
1271*333d2b36SAndroid Build Coastguard Worker
1272*333d2b36SAndroid Build Coastguard Worker	apexNameToApexExportsInfoMap := getApexNameToApexExportsInfoMap(ctx)
1273*333d2b36SAndroid Build Coastguard Worker	// For ART and mainline module jars, query apexNameToApexExportsInfoMap to get the dex file
1274*333d2b36SAndroid Build Coastguard Worker	apexJars := dexpreopt.GetGlobalConfig(ctx).ArtApexJars.AppendList(&dexpreopt.GetGlobalConfig(ctx).ApexBootJars)
1275*333d2b36SAndroid Build Coastguard Worker	for i := 0; i < apexJars.Len(); i++ {
1276*333d2b36SAndroid Build Coastguard Worker		if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, apexJars.Apex(i), apexJars.Jar(i)); found {
1277*333d2b36SAndroid Build Coastguard Worker			bootDexJars[apexJars.Jar(i)] = dex
1278*333d2b36SAndroid Build Coastguard Worker		}
1279*333d2b36SAndroid Build Coastguard Worker	}
1280*333d2b36SAndroid Build Coastguard Worker
1281*333d2b36SAndroid Build Coastguard Worker	// TODO - b/308174306: Drop the legacy mechanism
1282*333d2b36SAndroid Build Coastguard Worker	for _, module := range contents {
1283*333d2b36SAndroid Build Coastguard Worker		if _, exists := bootDexJars[android.RemoveOptionalPrebuiltPrefix(module.Name())]; exists {
1284*333d2b36SAndroid Build Coastguard Worker			continue
1285*333d2b36SAndroid Build Coastguard Worker		}
1286*333d2b36SAndroid Build Coastguard Worker		hiddenAPIModule := hiddenAPIModuleFromModule(ctx, module)
1287*333d2b36SAndroid Build Coastguard Worker		if hiddenAPIModule == nil {
1288*333d2b36SAndroid Build Coastguard Worker			continue
1289*333d2b36SAndroid Build Coastguard Worker		}
1290*333d2b36SAndroid Build Coastguard Worker		bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, hiddenAPIModule)
1291*333d2b36SAndroid Build Coastguard Worker		bootDexJars.addPath(module, bootDexJar)
1292*333d2b36SAndroid Build Coastguard Worker	}
1293*333d2b36SAndroid Build Coastguard Worker	return bootDexJars
1294*333d2b36SAndroid Build Coastguard Worker}
1295*333d2b36SAndroid Build Coastguard Worker
1296*333d2b36SAndroid Build Coastguard Workerfunc hiddenAPIModuleFromModule(ctx android.BaseModuleContext, module android.Module) hiddenAPIModule {
1297*333d2b36SAndroid Build Coastguard Worker	if hiddenAPIModule, ok := module.(hiddenAPIModule); ok {
1298*333d2b36SAndroid Build Coastguard Worker		return hiddenAPIModule
1299*333d2b36SAndroid Build Coastguard Worker	} else if _, ok := module.(*DexImport); ok {
1300*333d2b36SAndroid Build Coastguard Worker		// Ignore this for the purposes of hidden API processing
1301*333d2b36SAndroid Build Coastguard Worker	} else {
1302*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("module %s does not implement hiddenAPIModule", module)
1303*333d2b36SAndroid Build Coastguard Worker	}
1304*333d2b36SAndroid Build Coastguard Worker
1305*333d2b36SAndroid Build Coastguard Worker	return nil
1306*333d2b36SAndroid Build Coastguard Worker}
1307*333d2b36SAndroid Build Coastguard Worker
1308*333d2b36SAndroid Build Coastguard Worker// bootDexInfo encapsulates both the path and uncompressDex status retrieved from a hiddenAPIModule.
1309*333d2b36SAndroid Build Coastguard Workertype bootDexInfo struct {
1310*333d2b36SAndroid Build Coastguard Worker	// The path to the dex jar that has not had hidden API flags encoded into it.
1311*333d2b36SAndroid Build Coastguard Worker	path android.Path
1312*333d2b36SAndroid Build Coastguard Worker
1313*333d2b36SAndroid Build Coastguard Worker	// Indicates whether the dex jar needs uncompressing before encoding.
1314*333d2b36SAndroid Build Coastguard Worker	uncompressDex bool
1315*333d2b36SAndroid Build Coastguard Worker
1316*333d2b36SAndroid Build Coastguard Worker	// The minimum sdk version that the dex jar will be used on.
1317*333d2b36SAndroid Build Coastguard Worker	minSdkVersion android.ApiLevel
1318*333d2b36SAndroid Build Coastguard Worker}
1319*333d2b36SAndroid Build Coastguard Worker
1320*333d2b36SAndroid Build Coastguard Worker// bootDexInfoByModule is a map from module name (as returned by module.Name()) to the boot dex
1321*333d2b36SAndroid Build Coastguard Worker// path (as returned by hiddenAPIModule.bootDexJar()) and the uncompressDex flag.
1322*333d2b36SAndroid Build Coastguard Workertype bootDexInfoByModule map[string]bootDexInfo
1323*333d2b36SAndroid Build Coastguard Worker
1324*333d2b36SAndroid Build Coastguard Worker// bootDexJars returns the boot dex jar paths sorted by their keys.
1325*333d2b36SAndroid Build Coastguard Workerfunc (b bootDexInfoByModule) bootDexJars() android.Paths {
1326*333d2b36SAndroid Build Coastguard Worker	paths := android.Paths{}
1327*333d2b36SAndroid Build Coastguard Worker	for _, m := range android.SortedKeys(b) {
1328*333d2b36SAndroid Build Coastguard Worker		paths = append(paths, b[m].path)
1329*333d2b36SAndroid Build Coastguard Worker	}
1330*333d2b36SAndroid Build Coastguard Worker	return paths
1331*333d2b36SAndroid Build Coastguard Worker}
1332*333d2b36SAndroid Build Coastguard Worker
1333*333d2b36SAndroid Build Coastguard Worker// extractBootDexInfoFromModules extracts the boot dex jar and uncompress dex state from
1334*333d2b36SAndroid Build Coastguard Worker// each of the supplied modules which must implement hiddenAPIModule.
1335*333d2b36SAndroid Build Coastguard Workerfunc extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android.Module) bootDexInfoByModule {
1336*333d2b36SAndroid Build Coastguard Worker	bootDexJarsByModule := bootDexInfoByModule{}
1337*333d2b36SAndroid Build Coastguard Worker	for _, module := range contents {
1338*333d2b36SAndroid Build Coastguard Worker		hiddenAPIModule := module.(hiddenAPIModule)
1339*333d2b36SAndroid Build Coastguard Worker		bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, hiddenAPIModule)
1340*333d2b36SAndroid Build Coastguard Worker		bootDexJarsByModule[module.Name()] = bootDexInfo{
1341*333d2b36SAndroid Build Coastguard Worker			path:          bootDexJar,
1342*333d2b36SAndroid Build Coastguard Worker			uncompressDex: *hiddenAPIModule.uncompressDex(),
1343*333d2b36SAndroid Build Coastguard Worker			minSdkVersion: hiddenAPIModule.MinSdkVersion(ctx),
1344*333d2b36SAndroid Build Coastguard Worker		}
1345*333d2b36SAndroid Build Coastguard Worker	}
1346*333d2b36SAndroid Build Coastguard Worker
1347*333d2b36SAndroid Build Coastguard Worker	return bootDexJarsByModule
1348*333d2b36SAndroid Build Coastguard Worker}
1349*333d2b36SAndroid Build Coastguard Worker
1350*333d2b36SAndroid Build Coastguard Worker// retrieveBootDexJarFromHiddenAPIModule retrieves the boot dex jar from the hiddenAPIModule.
1351*333d2b36SAndroid Build Coastguard Worker//
1352*333d2b36SAndroid Build Coastguard Worker// If the module does not provide a boot dex jar, i.e. the returned boot dex jar is unset or
1353*333d2b36SAndroid Build Coastguard Worker// invalid, then create a fake path and either report an error immediately or defer reporting of the
1354*333d2b36SAndroid Build Coastguard Worker// error until the path is actually used.
1355*333d2b36SAndroid Build Coastguard Workerfunc retrieveBootDexJarFromHiddenAPIModule(ctx android.ModuleContext, module hiddenAPIModule) android.Path {
1356*333d2b36SAndroid Build Coastguard Worker	bootDexJar := module.bootDexJar(ctx)
1357*333d2b36SAndroid Build Coastguard Worker	if !bootDexJar.Valid() {
1358*333d2b36SAndroid Build Coastguard Worker		fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/boot-dex/%s.jar", module.Name()))
1359*333d2b36SAndroid Build Coastguard Worker		handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason())
1360*333d2b36SAndroid Build Coastguard Worker		return fake
1361*333d2b36SAndroid Build Coastguard Worker	}
1362*333d2b36SAndroid Build Coastguard Worker	return bootDexJar.Path()
1363*333d2b36SAndroid Build Coastguard Worker}
1364*333d2b36SAndroid Build Coastguard Worker
1365*333d2b36SAndroid Build Coastguard Worker// extractClassesJarsFromModules extracts the class jars from the supplied modules.
1366*333d2b36SAndroid Build Coastguard Workerfunc extractClassesJarsFromModules(contents []android.Module) android.Paths {
1367*333d2b36SAndroid Build Coastguard Worker	classesJars := android.Paths{}
1368*333d2b36SAndroid Build Coastguard Worker	for _, module := range contents {
1369*333d2b36SAndroid Build Coastguard Worker		classesJars = append(classesJars, retrieveClassesJarsFromModule(module)...)
1370*333d2b36SAndroid Build Coastguard Worker	}
1371*333d2b36SAndroid Build Coastguard Worker	return classesJars
1372*333d2b36SAndroid Build Coastguard Worker}
1373*333d2b36SAndroid Build Coastguard Worker
1374*333d2b36SAndroid Build Coastguard Worker// retrieveClassesJarsFromModule retrieves the classes jars from the supplied module.
1375*333d2b36SAndroid Build Coastguard Workerfunc retrieveClassesJarsFromModule(module android.Module) android.Paths {
1376*333d2b36SAndroid Build Coastguard Worker	if hiddenAPIModule, ok := module.(hiddenAPIModule); ok {
1377*333d2b36SAndroid Build Coastguard Worker		return hiddenAPIModule.classesJars()
1378*333d2b36SAndroid Build Coastguard Worker	}
1379*333d2b36SAndroid Build Coastguard Worker
1380*333d2b36SAndroid Build Coastguard Worker	return nil
1381*333d2b36SAndroid Build Coastguard Worker}
1382*333d2b36SAndroid Build Coastguard Worker
1383*333d2b36SAndroid Build Coastguard Worker// deferReportingMissingBootDexJar returns true if a missing boot dex jar should not be reported by
1384*333d2b36SAndroid Build Coastguard Worker// Soong but should instead only be reported in ninja if the file is actually built.
1385*333d2b36SAndroid Build Coastguard Workerfunc deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.Module) bool {
1386*333d2b36SAndroid Build Coastguard Worker	// Any missing dependency should be allowed.
1387*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().AllowMissingDependencies() {
1388*333d2b36SAndroid Build Coastguard Worker		return true
1389*333d2b36SAndroid Build Coastguard Worker	}
1390*333d2b36SAndroid Build Coastguard Worker
1391*333d2b36SAndroid Build Coastguard Worker	// This is called for both platform_bootclasspath and bootclasspath_fragment modules.
1392*333d2b36SAndroid Build Coastguard Worker	//
1393*333d2b36SAndroid Build Coastguard Worker	// A bootclasspath_fragment module should only use the APEX variant of source or prebuilt modules.
1394*333d2b36SAndroid Build Coastguard Worker	// Ideally, a bootclasspath_fragment module should never have a platform variant created for it
1395*333d2b36SAndroid Build Coastguard Worker	// but unfortunately, due to b/187910671 it does.
1396*333d2b36SAndroid Build Coastguard Worker	//
1397*333d2b36SAndroid Build Coastguard Worker	// That causes issues when obtaining a boot dex jar for a prebuilt module as a prebuilt module
1398*333d2b36SAndroid Build Coastguard Worker	// used by a bootclasspath_fragment can only provide a boot dex jar when it is part of APEX, i.e.
1399*333d2b36SAndroid Build Coastguard Worker	// has an APEX variant not a platform variant.
1400*333d2b36SAndroid Build Coastguard Worker	//
1401*333d2b36SAndroid Build Coastguard Worker	// There are some other situations when a prebuilt module used by a bootclasspath_fragment cannot
1402*333d2b36SAndroid Build Coastguard Worker	// provide a boot dex jar:
1403*333d2b36SAndroid Build Coastguard Worker	// 1. If the bootclasspath_fragment is not exported by the prebuilt_apex/apex_set module then it
1404*333d2b36SAndroid Build Coastguard Worker	//    does not have an APEX variant and only has a platform variant and neither do its content
1405*333d2b36SAndroid Build Coastguard Worker	//    modules.
1406*333d2b36SAndroid Build Coastguard Worker	// 2. Some build configurations, e.g. setting TARGET_BUILD_USE_PREBUILT_SDKS causes all
1407*333d2b36SAndroid Build Coastguard Worker	//    java_sdk_library_import modules to be treated as preferred and as many of them are not part
1408*333d2b36SAndroid Build Coastguard Worker	//    of an apex they cannot provide a boot dex jar.
1409*333d2b36SAndroid Build Coastguard Worker	//
1410*333d2b36SAndroid Build Coastguard Worker	// The first case causes problems when the affected prebuilt modules are preferred but that is an
1411*333d2b36SAndroid Build Coastguard Worker	// invalid configuration and it is ok for it to fail as the work to enable that is not yet
1412*333d2b36SAndroid Build Coastguard Worker	// complete. The second case is used for building targets that do not use boot dex jars and so
1413*333d2b36SAndroid Build Coastguard Worker	// deferring error reporting to ninja is fine as the affected ninja targets should never be built.
1414*333d2b36SAndroid Build Coastguard Worker	// That is handled above.
1415*333d2b36SAndroid Build Coastguard Worker	//
1416*333d2b36SAndroid Build Coastguard Worker	// A platform_bootclasspath module can use libraries from both platform and APEX variants. Unlike
1417*333d2b36SAndroid Build Coastguard Worker	// the bootclasspath_fragment it supports dex_import modules which provides the dex file. So, it
1418*333d2b36SAndroid Build Coastguard Worker	// can obtain a boot dex jar from a prebuilt that is not part of an APEX. However, it is assumed
1419*333d2b36SAndroid Build Coastguard Worker	// that if the library can be part of an APEX then it is the APEX variant that is used.
1420*333d2b36SAndroid Build Coastguard Worker	//
1421*333d2b36SAndroid Build Coastguard Worker	// This check handles the slightly different requirements of the bootclasspath_fragment and
1422*333d2b36SAndroid Build Coastguard Worker	// platform_bootclasspath modules by only deferring error reporting for the platform variant of
1423*333d2b36SAndroid Build Coastguard Worker	// a prebuilt modules that has other variants which are part of an APEX.
1424*333d2b36SAndroid Build Coastguard Worker	//
1425*333d2b36SAndroid Build Coastguard Worker	// TODO(b/187910671): Remove this once platform variants are no longer created unnecessarily.
1426*333d2b36SAndroid Build Coastguard Worker	if android.IsModulePrebuilt(module) {
1427*333d2b36SAndroid Build Coastguard Worker		// An inactive source module can still contribute to the APEX but an inactive prebuilt module
1428*333d2b36SAndroid Build Coastguard Worker		// should not contribute to anything. So, rather than have a missing dex jar cause a Soong
1429*333d2b36SAndroid Build Coastguard Worker		// failure defer the error reporting to Ninja. Unless the prebuilt build target is explicitly
1430*333d2b36SAndroid Build Coastguard Worker		// built Ninja should never use the dex jar file.
1431*333d2b36SAndroid Build Coastguard Worker		if !isActiveModule(ctx, module) {
1432*333d2b36SAndroid Build Coastguard Worker			return true
1433*333d2b36SAndroid Build Coastguard Worker		}
1434*333d2b36SAndroid Build Coastguard Worker
1435*333d2b36SAndroid Build Coastguard Worker		if am, ok := module.(android.ApexModule); ok && am.InAnyApex() {
1436*333d2b36SAndroid Build Coastguard Worker			apexInfo, _ := android.OtherModuleProvider(ctx, module, android.ApexInfoProvider)
1437*333d2b36SAndroid Build Coastguard Worker			if apexInfo.IsForPlatform() {
1438*333d2b36SAndroid Build Coastguard Worker				return true
1439*333d2b36SAndroid Build Coastguard Worker			}
1440*333d2b36SAndroid Build Coastguard Worker		}
1441*333d2b36SAndroid Build Coastguard Worker	}
1442*333d2b36SAndroid Build Coastguard Worker
1443*333d2b36SAndroid Build Coastguard Worker	return false
1444*333d2b36SAndroid Build Coastguard Worker}
1445*333d2b36SAndroid Build Coastguard Worker
1446*333d2b36SAndroid Build Coastguard Worker// handleMissingDexBootFile will either log a warning or create an error rule to create the fake
1447*333d2b36SAndroid Build Coastguard Worker// file depending on the value returned from deferReportingMissingBootDexJar.
1448*333d2b36SAndroid Build Coastguard Workerfunc handleMissingDexBootFile(ctx android.ModuleContext, module android.Module, fake android.WritablePath, reason string) {
1449*333d2b36SAndroid Build Coastguard Worker	if deferReportingMissingBootDexJar(ctx, module) {
1450*333d2b36SAndroid Build Coastguard Worker		// Create an error rule that pretends to create the output file but will actually fail if it
1451*333d2b36SAndroid Build Coastguard Worker		// is run.
1452*333d2b36SAndroid Build Coastguard Worker		ctx.Build(pctx, android.BuildParams{
1453*333d2b36SAndroid Build Coastguard Worker			Rule:   android.ErrorRule,
1454*333d2b36SAndroid Build Coastguard Worker			Output: fake,
1455*333d2b36SAndroid Build Coastguard Worker			Args: map[string]string{
1456*333d2b36SAndroid Build Coastguard Worker				"error": fmt.Sprintf("missing boot dex jar dependency for %s: %s", module, reason),
1457*333d2b36SAndroid Build Coastguard Worker			},
1458*333d2b36SAndroid Build Coastguard Worker		})
1459*333d2b36SAndroid Build Coastguard Worker	} else {
1460*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("module %s does not provide a dex jar: %s", module, reason)
1461*333d2b36SAndroid Build Coastguard Worker	}
1462*333d2b36SAndroid Build Coastguard Worker}
1463*333d2b36SAndroid Build Coastguard Worker
1464*333d2b36SAndroid Build Coastguard Worker// retrieveEncodedBootDexJarFromModule returns a path to the boot dex jar from the supplied module's
1465*333d2b36SAndroid Build Coastguard Worker// DexJarBuildPath() method.
1466*333d2b36SAndroid Build Coastguard Worker//
1467*333d2b36SAndroid Build Coastguard Worker// The returned path will usually be to a dex jar file that has been encoded with hidden API flags.
1468*333d2b36SAndroid Build Coastguard Worker// However, under certain conditions, e.g. errors, or special build configurations it will return
1469*333d2b36SAndroid Build Coastguard Worker// a path to a fake file.
1470*333d2b36SAndroid Build Coastguard Workerfunc retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module android.Module) android.Path {
1471*333d2b36SAndroid Build Coastguard Worker	bootDexJar := module.(interface {
1472*333d2b36SAndroid Build Coastguard Worker		DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath
1473*333d2b36SAndroid Build Coastguard Worker	}).DexJarBuildPath(ctx)
1474*333d2b36SAndroid Build Coastguard Worker	if !bootDexJar.Valid() {
1475*333d2b36SAndroid Build Coastguard Worker		fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/encoded-dex/%s.jar", module.Name()))
1476*333d2b36SAndroid Build Coastguard Worker		handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason())
1477*333d2b36SAndroid Build Coastguard Worker		return fake
1478*333d2b36SAndroid Build Coastguard Worker	}
1479*333d2b36SAndroid Build Coastguard Worker	return bootDexJar.Path()
1480*333d2b36SAndroid Build Coastguard Worker}
1481