Use the correct bootjars for hiddneapi when multiple prebuilts exist
hiddenapi processing require boot jars from apexes to determine the full
set of methods available at runtime.
When building with prebuilts, this comes via
java_import/java_sdk_library_import, which acts as a hook for
prebuilt_apex/apex_set. If we have multiple apexes in the tree, this
hook becomes 1:many. This CL prepares platform_bootclasspath to select the right
deapexerd .jar files when mutliple prebuilts exist.
Implementation details
- Create a dependency edge from platform_bootclasspath to
all_apex_contributions (DepsMutator)
- For every boot jar, query all_apex_contributions to get the path to
dexjar file (GenerateAndroidBuildActions)
Some other important details
- This CL does not drop the old mechanism to get the dex file (i.e. by
creating a dep on java_library). Once all mainline
modules have been flagged using apex_contributions, the old mechanism
will be dropped
- This CL has a functional change when building with source apexes. At
ToT, the unecoded hiddenapi dex jar is used for package check and
generating the monolithic stub file. After this change, the hiddenapi
encoded file will be used for these operations.
This should be fine since the
package and dex signature do not change across the encoded and
unencoded dex file. In fact, we already have a split today. When
building with prebuilts, we use the encoded dex file. When building
with source, we use the unecoded dex file.
Test: Added a unit test
Test: Manual testing in internal described below
- lunch cf_x86_64_phone-next-userdebug
- flagged com.google.android.adservices using apex_contributions
- aninja -t commands out/soong/hiddenapi/hiddenapi-stubs-flags.txt # no
diff before and after
Bug: 308790777
Change-Id: I72c70f0ae1b587679203ea254c9c12a48e7aa782
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 73609bf..82cece3 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -699,28 +699,40 @@
// extractEncodedDexJarsFromModulesOrBootclasspathFragments gets the hidden API encoded dex jars for
// the given modules.
func extractEncodedDexJarsFromModulesOrBootclasspathFragments(ctx android.ModuleContext, apexJarModulePairs []apexJarModulePair) bootDexJarByModule {
- apexNameToBcpInfoMap := getApexNameToBcpInfoMap(ctx)
+ apexNameToApexExportInfoMap := getApexNameToApexExportsInfoMap(ctx)
encodedDexJarsByModuleName := bootDexJarByModule{}
for _, pair := range apexJarModulePairs {
- dexJarPath := getDexJarForApex(ctx, pair, apexNameToBcpInfoMap)
+ dexJarPath := getDexJarForApex(ctx, pair, apexNameToApexExportInfoMap)
encodedDexJarsByModuleName.addPath(pair.jarModule, dexJarPath)
}
return encodedDexJarsByModuleName
}
+type apexNameToApexExportsInfoMap map[string]android.ApexExportsInfo
+
+// javaLibraryPathOnHost returns the path to the java library which is exported by the apex for hiddenapi and dexpreopt and a boolean indicating whether the java library exists
+// For prebuilt apexes, this is created by deapexing the prebuilt apex
+func (m *apexNameToApexExportsInfoMap) javaLibraryDexPathOnHost(ctx android.ModuleContext, apex string, javalib string) (android.Path, bool) {
+ if info, exists := (*m)[apex]; exists {
+ if dex, exists := info.LibraryNameToDexJarPathOnHost[javalib]; exists {
+ return dex, true
+ } else {
+ ctx.ModuleErrorf("Apex %s does not provide a dex boot jar for library %s\n", apex, javalib)
+ }
+ }
+ // An apex entry could not be found. Return false.
+ // TODO: b/308174306 - When all the mainline modules have been flagged, make this a hard error
+ return nil, false
+}
+
// Returns the java libraries exported by the apex for hiddenapi and dexpreopt
// This information can come from two mechanisms
// 1. New: Direct deps to _selected_ apexes. The apexes return a ApexExportsInfo
// 2. Legacy: An edge to java_library or java_import (java_sdk_library) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes
// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2)
-func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNameToBcpInfoMap map[string]android.ApexExportsInfo) android.Path {
- if info, exists := apexNameToBcpInfoMap[pair.apex]; exists {
- libraryName := android.RemoveOptionalPrebuiltPrefix(pair.jarModule.Name())
- if dex, exists := info.LibraryNameToDexJarPathOnHost[libraryName]; exists {
- return dex
- } else {
- ctx.ModuleErrorf("Apex %s does not provide a dex boot jar for library %s\n", pair.apex, libraryName)
- }
+func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNameToApexExportsInfoMap apexNameToApexExportsInfoMap) android.Path {
+ if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, pair.apex, android.RemoveOptionalPrebuiltPrefix(pair.jarModule.Name())); found {
+ return dex
}
// TODO: b/308174306 - Remove the legacy mechanism
if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(pair.jarModule) {
@@ -900,14 +912,14 @@
return fragment.(commonBootclasspathFragment).getProfilePath()
}
-func getApexNameToBcpInfoMap(ctx android.ModuleContext) map[string]android.ApexExportsInfo {
- apexNameToBcpInfoMap := map[string]android.ApexExportsInfo{}
+func getApexNameToApexExportsInfoMap(ctx android.ModuleContext) apexNameToApexExportsInfoMap {
+ apexNameToApexExportsInfoMap := apexNameToApexExportsInfoMap{}
ctx.VisitDirectDepsWithTag(dexpreoptBootJarDepTag, func(am android.Module) {
if info, exists := android.OtherModuleProvider(ctx, am, android.ApexExportsInfoProvider); exists {
- apexNameToBcpInfoMap[info.ApexName] = info
+ apexNameToApexExportsInfoMap[info.ApexName] = info
}
})
- return apexNameToBcpInfoMap
+ return apexNameToApexExportsInfoMap
}
// Generate boot image build rules for a specific target.
@@ -952,7 +964,7 @@
invocationPath := outputPath.ReplaceExtension(ctx, "invocation")
- apexNameToBcpInfoMap := getApexNameToBcpInfoMap(ctx)
+ apexNameToApexExportsInfoMap := getApexNameToApexExportsInfoMap(ctx)
cmd.Tool(globalSoong.Dex2oat).
Flag("--avoid-storing-invocation").
@@ -966,7 +978,7 @@
}
for _, apex := range image.profileImports {
- importedProfile := getProfilePathForApex(ctx, apex, apexNameToBcpInfoMap)
+ importedProfile := getProfilePathForApex(ctx, apex, apexNameToApexExportsInfoMap)
if importedProfile == nil {
ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but '%[2]s' "+
"doesn't provide a profile",