Propagate the dex jar path as an OptionalPath which is either valid or
invalid with a message. This will allow propagating any error from the deapexer module for prebuilt APEXes to the location where the dex jars get used. It's only at those points that we can raise errors about not being able to extract files from the deapexer modules if they are invalid, and this way we avoid encoding knowledge there about why they may be invalid. To keep the refactoring limited it intentionally does not change any of the existing logic for when dexJarFiles are set or not (non-nil vs nil prior to this change), although there may be opportunity to use this for more conditions when dex jars aren't available. The refactoring is also not extended to dexpreopt.ClassLoaderContextMap. Test: m nothing Bug: 192006406 Change-Id: I68986dccd9a9b3fee4d24caa1947ea17a36caedc
This commit is contained in:
@@ -1545,7 +1545,7 @@ func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.Platform
|
||||
type javaModule interface {
|
||||
android.Module
|
||||
BaseModuleName() string
|
||||
DexJarBuildPath() android.Path
|
||||
DexJarBuildPath() java.OptionalDexJarPath
|
||||
JacocoReportClassesFile() android.Path
|
||||
LintDepSets() java.LintDepSets
|
||||
Stem() string
|
||||
@@ -1559,7 +1559,7 @@ var _ javaModule = (*java.SdkLibraryImport)(nil)
|
||||
|
||||
// apexFileForJavaModule creates an apexFile for a java module's dex implementation jar.
|
||||
func apexFileForJavaModule(ctx android.BaseModuleContext, module javaModule) apexFile {
|
||||
return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath())
|
||||
return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath().PathOrNil())
|
||||
}
|
||||
|
||||
// apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file.
|
||||
|
@@ -4799,9 +4799,10 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) {
|
||||
transform := android.NullFixturePreparer
|
||||
|
||||
checkDexJarBuildPath := func(t *testing.T, ctx *android.TestContext, name string) {
|
||||
t.Helper()
|
||||
// Make sure the import has been given the correct path to the dex jar.
|
||||
p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
|
||||
dexJarBuildPath := p.DexJarBuildPath()
|
||||
dexJarBuildPath := p.DexJarBuildPath().PathOrNil()
|
||||
stem := android.RemoveOptionalPrebuiltPrefix(name)
|
||||
android.AssertStringEquals(t, "DexJarBuildPath should be apex-related path.",
|
||||
".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar",
|
||||
@@ -4809,6 +4810,7 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) {
|
||||
}
|
||||
|
||||
checkDexJarInstallPath := func(t *testing.T, ctx *android.TestContext, name string) {
|
||||
t.Helper()
|
||||
// Make sure the import has been given the correct path to the dex jar.
|
||||
p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
|
||||
dexJarBuildPath := p.DexJarInstallPath()
|
||||
@@ -4819,6 +4821,7 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) {
|
||||
}
|
||||
|
||||
ensureNoSourceVariant := func(t *testing.T, ctx *android.TestContext, name string) {
|
||||
t.Helper()
|
||||
// Make sure that an apex variant is not created for the source module.
|
||||
android.AssertArrayString(t, "Check if there is no source variant",
|
||||
[]string{"android_common"},
|
||||
|
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/java"
|
||||
|
||||
"github.com/google/blueprint/proptools"
|
||||
)
|
||||
|
||||
@@ -737,7 +738,7 @@ func TestBootclasspathFragmentContentsNoName(t *testing.T) {
|
||||
|
||||
func getDexJarPath(result *android.TestResult, name string) string {
|
||||
module := result.Module(name, "android_common")
|
||||
return module.(java.UsesLibraryDependency).DexJarBuildPath().RelativeToTop().String()
|
||||
return module.(java.UsesLibraryDependency).DexJarBuildPath().Path().RelativeToTop().String()
|
||||
}
|
||||
|
||||
// TestBootclasspathFragment_HiddenAPIList checks to make sure that the correct parameters are
|
||||
|
@@ -176,13 +176,15 @@ func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) {
|
||||
name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
|
||||
if java.IsBootclasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
|
||||
// If the exported java module provides a dex jar path then add it to the list of apexFiles.
|
||||
path := child.(interface{ DexJarBuildPath() android.Path }).DexJarBuildPath()
|
||||
if path != nil {
|
||||
path := child.(interface {
|
||||
DexJarBuildPath() java.OptionalDexJarPath
|
||||
}).DexJarBuildPath()
|
||||
if path.IsSet() {
|
||||
af := apexFile{
|
||||
module: child,
|
||||
moduleDir: ctx.OtherModuleDir(child),
|
||||
androidMkModuleName: name,
|
||||
builtFile: path,
|
||||
builtFile: path.Path(),
|
||||
class: javaSharedLib,
|
||||
}
|
||||
if module, ok := child.(java.DexpreopterInterface); ok {
|
||||
|
@@ -29,8 +29,8 @@ func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries {
|
||||
|
||||
if hostDexNeeded {
|
||||
var output android.Path
|
||||
if library.dexJarFile != nil {
|
||||
output = library.dexJarFile
|
||||
if library.dexJarFile.IsSet() {
|
||||
output = library.dexJarFile.Path()
|
||||
} else {
|
||||
output = library.implementationAndResourcesJar
|
||||
}
|
||||
@@ -44,8 +44,8 @@ func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries {
|
||||
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
||||
entries.SetBool("LOCAL_IS_HOST_MODULE", true)
|
||||
entries.SetPath("LOCAL_PREBUILT_MODULE_FILE", output)
|
||||
if library.dexJarFile != nil {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile)
|
||||
if library.dexJarFile.IsSet() {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile.Path())
|
||||
}
|
||||
entries.SetPath("LOCAL_SOONG_HEADER_JAR", library.headerJarFile)
|
||||
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", library.implementationAndResourcesJar)
|
||||
@@ -106,8 +106,8 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
|
||||
if library.installFile == nil {
|
||||
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", true)
|
||||
}
|
||||
if library.dexJarFile != nil {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile)
|
||||
if library.dexJarFile.IsSet() {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", library.dexJarFile.Path())
|
||||
}
|
||||
if len(library.dexpreopter.builtInstalled) > 0 {
|
||||
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", library.dexpreopter.builtInstalled)
|
||||
@@ -207,8 +207,8 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
|
||||
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
|
||||
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
||||
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !Bool(prebuilt.properties.Installable))
|
||||
if prebuilt.dexJarFile != nil {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile)
|
||||
if prebuilt.dexJarFile.IsSet() {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile.Path())
|
||||
}
|
||||
entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedClasspathFile)
|
||||
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedClasspathFile)
|
||||
@@ -227,12 +227,12 @@ func (prebuilt *DexImport) AndroidMkEntries() []android.AndroidMkEntries {
|
||||
}
|
||||
return []android.AndroidMkEntries{android.AndroidMkEntries{
|
||||
Class: "JAVA_LIBRARIES",
|
||||
OutputFile: android.OptionalPathForPath(prebuilt.dexJarFile),
|
||||
OutputFile: android.OptionalPathForPath(prebuilt.dexJarFile.Path()),
|
||||
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
|
||||
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
|
||||
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
||||
if prebuilt.dexJarFile != nil {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile)
|
||||
if prebuilt.dexJarFile.IsSet() {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile.Path())
|
||||
}
|
||||
if len(prebuilt.dexpreopter.builtInstalled) > 0 {
|
||||
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", prebuilt.dexpreopter.builtInstalled)
|
||||
@@ -279,8 +279,8 @@ func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries {
|
||||
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
||||
entries.SetPath("LOCAL_SOONG_HEADER_JAR", binary.headerJarFile)
|
||||
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", binary.implementationAndResourcesJar)
|
||||
if binary.dexJarFile != nil {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", binary.dexJarFile)
|
||||
if binary.dexJarFile.IsSet() {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", binary.dexJarFile.Path())
|
||||
}
|
||||
if len(binary.dexpreopter.builtInstalled) > 0 {
|
||||
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled)
|
||||
@@ -336,8 +336,8 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
|
||||
entries.SetString("LOCAL_MODULE", app.installApkName)
|
||||
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", app.appProperties.PreventInstall)
|
||||
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", app.exportPackage)
|
||||
if app.dexJarFile != nil {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", app.dexJarFile)
|
||||
if app.dexJarFile.IsSet() {
|
||||
entries.SetPath("LOCAL_SOONG_DEX_JAR", app.dexJarFile.Path())
|
||||
}
|
||||
if app.implementationAndResourcesJar != nil {
|
||||
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", app.implementationAndResourcesJar)
|
||||
|
@@ -476,7 +476,7 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
|
||||
a.Module.compile(ctx, a.aaptSrcJar)
|
||||
}
|
||||
|
||||
return a.dexJarFile
|
||||
return a.dexJarFile.PathOrNil()
|
||||
}
|
||||
|
||||
func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, ctx android.ModuleContext) android.WritablePath {
|
||||
@@ -1305,7 +1305,8 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext
|
||||
replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
|
||||
}
|
||||
clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, tag.implicit,
|
||||
lib.DexJarBuildPath(), lib.DexJarInstallPath(), lib.ClassLoaderContexts())
|
||||
lib.DexJarBuildPath().PathOrNil(), lib.DexJarInstallPath(),
|
||||
lib.ClassLoaderContexts())
|
||||
} else if ctx.Config().AllowMissingDependencies() {
|
||||
ctx.AddMissingDependencies([]string{dep})
|
||||
} else {
|
||||
|
92
java/base.go
92
java/base.go
@@ -276,6 +276,87 @@ func (e *embeddableInModuleAndImport) depIsInSameApex(ctx android.BaseModuleCont
|
||||
return false
|
||||
}
|
||||
|
||||
// OptionalDexJarPath can be either unset, hold a valid path to a dex jar file,
|
||||
// or an invalid path describing the reason it is invalid.
|
||||
//
|
||||
// It is unset if a dex jar isn't applicable, i.e. no build rule has been
|
||||
// requested to create one.
|
||||
//
|
||||
// If a dex jar has been requested to be built then it is set, and it may be
|
||||
// either a valid android.Path, or invalid with a reason message. The latter
|
||||
// happens if the source that should produce the dex file isn't able to.
|
||||
//
|
||||
// E.g. it is invalid with a reason message if there is a prebuilt APEX that
|
||||
// could produce the dex jar through a deapexer module, but the APEX isn't
|
||||
// installable so doing so wouldn't be safe.
|
||||
type OptionalDexJarPath struct {
|
||||
isSet bool
|
||||
path android.OptionalPath
|
||||
}
|
||||
|
||||
// IsSet returns true if a path has been set, either invalid or valid.
|
||||
func (o OptionalDexJarPath) IsSet() bool {
|
||||
return o.isSet
|
||||
}
|
||||
|
||||
// Valid returns true if there is a path that is valid.
|
||||
func (o OptionalDexJarPath) Valid() bool {
|
||||
return o.isSet && o.path.Valid()
|
||||
}
|
||||
|
||||
// Path returns the valid path, or panics if it's either not set or is invalid.
|
||||
func (o OptionalDexJarPath) Path() android.Path {
|
||||
if !o.isSet {
|
||||
panic("path isn't set")
|
||||
}
|
||||
return o.path.Path()
|
||||
}
|
||||
|
||||
// PathOrNil returns the path if it's set and valid, or else nil.
|
||||
func (o OptionalDexJarPath) PathOrNil() android.Path {
|
||||
if o.Valid() {
|
||||
return o.Path()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InvalidReason returns the reason for an invalid path, which is never "". It
|
||||
// returns "" for an unset or valid path.
|
||||
func (o OptionalDexJarPath) InvalidReason() string {
|
||||
if !o.isSet {
|
||||
return ""
|
||||
}
|
||||
return o.path.InvalidReason()
|
||||
}
|
||||
|
||||
func (o OptionalDexJarPath) String() string {
|
||||
if !o.isSet {
|
||||
return "<unset>"
|
||||
}
|
||||
return o.path.String()
|
||||
}
|
||||
|
||||
// makeUnsetDexJarPath returns an unset OptionalDexJarPath.
|
||||
func makeUnsetDexJarPath() OptionalDexJarPath {
|
||||
return OptionalDexJarPath{isSet: false}
|
||||
}
|
||||
|
||||
// makeDexJarPathFromOptionalPath returns an OptionalDexJarPath that is set with
|
||||
// the given OptionalPath, which may be valid or invalid.
|
||||
func makeDexJarPathFromOptionalPath(path android.OptionalPath) OptionalDexJarPath {
|
||||
return OptionalDexJarPath{isSet: true, path: path}
|
||||
}
|
||||
|
||||
// makeDexJarPathFromPath returns an OptionalDexJarPath that is set with the
|
||||
// valid given path. It returns an unset OptionalDexJarPath if the given path is
|
||||
// nil.
|
||||
func makeDexJarPathFromPath(path android.Path) OptionalDexJarPath {
|
||||
if path == nil {
|
||||
return makeUnsetDexJarPath()
|
||||
}
|
||||
return makeDexJarPathFromOptionalPath(android.OptionalPathForPath(path))
|
||||
}
|
||||
|
||||
// Module contains the properties and members used by all java module types
|
||||
type Module struct {
|
||||
android.ModuleBase
|
||||
@@ -310,7 +391,7 @@ type Module struct {
|
||||
implementationAndResourcesJar android.Path
|
||||
|
||||
// output file containing classes.dex and resources
|
||||
dexJarFile android.Path
|
||||
dexJarFile OptionalDexJarPath
|
||||
|
||||
// output file containing uninstrumented classes that will be instrumented by jacoco
|
||||
jacocoReportClassesFile android.Path
|
||||
@@ -1265,12 +1346,13 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
|
||||
}
|
||||
|
||||
// Initialize the hiddenapi structure.
|
||||
j.initHiddenAPI(ctx, dexOutputFile, j.implementationJarFile, j.dexProperties.Uncompress_dex)
|
||||
|
||||
j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), j.implementationJarFile, j.dexProperties.Uncompress_dex)
|
||||
|
||||
// Encode hidden API flags in dex file, if needed.
|
||||
dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
|
||||
|
||||
j.dexJarFile = dexOutputFile
|
||||
j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
|
||||
|
||||
// Dexpreopting
|
||||
j.dexpreopt(ctx, dexOutputFile)
|
||||
@@ -1280,7 +1362,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
|
||||
// There is no code to compile into a dex jar, make sure the resources are propagated
|
||||
// to the APK if this is an app.
|
||||
outputFile = implementationAndResourcesJar
|
||||
j.dexJarFile = j.resourceJar
|
||||
j.dexJarFile = makeDexJarPathFromPath(j.resourceJar)
|
||||
}
|
||||
|
||||
if ctx.Failed() {
|
||||
@@ -1470,7 +1552,7 @@ func (j *Module) ImplementationJars() android.Paths {
|
||||
return android.Paths{j.implementationJarFile}
|
||||
}
|
||||
|
||||
func (j *Module) DexJarBuildPath() android.Path {
|
||||
func (j *Module) DexJarBuildPath() OptionalDexJarPath {
|
||||
return j.dexJarFile
|
||||
}
|
||||
|
||||
|
@@ -30,14 +30,14 @@ type hiddenAPI struct {
|
||||
// that information encoded within it.
|
||||
active bool
|
||||
|
||||
// The path to the dex jar that is in the boot class path. If this is nil then the associated
|
||||
// The path to the dex jar that is in the boot class path. If this is unset then the associated
|
||||
// module is not a boot jar, but could be one of the <x>-hiddenapi modules that provide additional
|
||||
// annotations for the <x> boot dex jar but which do not actually provide a boot dex jar
|
||||
// themselves.
|
||||
//
|
||||
// This must be the path to the unencoded dex jar as the encoded dex jar indirectly depends on
|
||||
// this file so using the encoded dex jar here would result in a cycle in the ninja rules.
|
||||
bootDexJarPath android.Path
|
||||
bootDexJarPath OptionalDexJarPath
|
||||
|
||||
// The paths to the classes jars that contain classes and class members annotated with
|
||||
// the UnsupportedAppUsage annotation that need to be extracted as part of the hidden API
|
||||
@@ -49,7 +49,7 @@ type hiddenAPI struct {
|
||||
uncompressDexState *bool
|
||||
}
|
||||
|
||||
func (h *hiddenAPI) bootDexJar() android.Path {
|
||||
func (h *hiddenAPI) bootDexJar() OptionalDexJarPath {
|
||||
return h.bootDexJarPath
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ type hiddenAPIModule interface {
|
||||
}
|
||||
|
||||
type hiddenAPIIntf interface {
|
||||
bootDexJar() android.Path
|
||||
bootDexJar() OptionalDexJarPath
|
||||
classesJars() android.Paths
|
||||
uncompressDex() *bool
|
||||
}
|
||||
@@ -79,7 +79,7 @@ var _ hiddenAPIIntf = (*hiddenAPI)(nil)
|
||||
//
|
||||
// uncompressedDexState should be nil when the module is a prebuilt and so does not require hidden
|
||||
// API encoding.
|
||||
func (h *hiddenAPI) initHiddenAPI(ctx android.ModuleContext, dexJar, classesJar android.Path, uncompressedDexState *bool) {
|
||||
func (h *hiddenAPI) initHiddenAPI(ctx android.ModuleContext, dexJar OptionalDexJarPath, classesJar android.Path, uncompressedDexState *bool) {
|
||||
|
||||
// Save the classes jars even if this is not active as they may be used by modular hidden API
|
||||
// processing.
|
||||
|
@@ -19,6 +19,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"android/soong/android"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
@@ -277,7 +278,7 @@ func hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, apiScop
|
||||
// hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if
|
||||
// available, or reports an error.
|
||||
func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path {
|
||||
var dexJar android.Path
|
||||
var dexJar OptionalDexJarPath
|
||||
if sdkLibrary, ok := module.(SdkLibraryDependency); ok {
|
||||
dexJar = sdkLibrary.SdkApiStubDexJar(ctx, kind)
|
||||
} else if j, ok := module.(UsesLibraryDependency); ok {
|
||||
@@ -287,10 +288,11 @@ func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.
|
||||
return nil
|
||||
}
|
||||
|
||||
if dexJar == nil {
|
||||
ctx.ModuleErrorf("dependency %s does not provide a dex jar, consider setting compile_dex: true", module)
|
||||
if !dexJar.Valid() {
|
||||
ctx.ModuleErrorf("dependency %s does not provide a dex jar: %s", module, dexJar.InvalidReason())
|
||||
return nil
|
||||
}
|
||||
return dexJar
|
||||
return dexJar.Path()
|
||||
}
|
||||
|
||||
// buildRuleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file.
|
||||
@@ -1159,18 +1161,17 @@ func extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android
|
||||
|
||||
// retrieveBootDexJarFromHiddenAPIModule retrieves the boot dex jar from the hiddenAPIModule.
|
||||
//
|
||||
// If the module does not provide a boot dex jar, i.e. the returned boot dex jar is nil, then that
|
||||
// create a fake path and either report an error immediately or defer reporting of the error until
|
||||
// the path is actually used.
|
||||
// If the module does not provide a boot dex jar, i.e. the returned boot dex jar is unset or
|
||||
// invalid, then create a fake path and either report an error immediately or defer reporting of the
|
||||
// error until the path is actually used.
|
||||
func retrieveBootDexJarFromHiddenAPIModule(ctx android.ModuleContext, module hiddenAPIModule) android.Path {
|
||||
bootDexJar := module.bootDexJar()
|
||||
if bootDexJar == nil {
|
||||
if !bootDexJar.Valid() {
|
||||
fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/boot-dex/%s.jar", module.Name()))
|
||||
bootDexJar = fake
|
||||
|
||||
handleMissingDexBootFile(ctx, module, fake)
|
||||
handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason())
|
||||
return fake
|
||||
}
|
||||
return bootDexJar
|
||||
return bootDexJar.Path()
|
||||
}
|
||||
|
||||
// extractClassesJarsFromModules extracts the class jars from the supplied modules.
|
||||
@@ -1264,7 +1265,7 @@ func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.M
|
||||
|
||||
// handleMissingDexBootFile will either log a warning or create an error rule to create the fake
|
||||
// file depending on the value returned from deferReportingMissingBootDexJar.
|
||||
func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module, fake android.WritablePath) {
|
||||
func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module, fake android.WritablePath, reason string) {
|
||||
if deferReportingMissingBootDexJar(ctx, module) {
|
||||
// Create an error rule that pretends to create the output file but will actually fail if it
|
||||
// is run.
|
||||
@@ -1272,11 +1273,11 @@ func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module,
|
||||
Rule: android.ErrorRule,
|
||||
Output: fake,
|
||||
Args: map[string]string{
|
||||
"error": fmt.Sprintf("missing dependencies: boot dex jar for %s", module),
|
||||
"error": fmt.Sprintf("missing boot dex jar dependency for %s: %s", module, reason),
|
||||
},
|
||||
})
|
||||
} else {
|
||||
ctx.ModuleErrorf("module %s does not provide a dex jar", module)
|
||||
ctx.ModuleErrorf("module %s does not provide a dex jar: %s", module, reason)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1287,14 +1288,13 @@ func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module,
|
||||
// However, under certain conditions, e.g. errors, or special build configurations it will return
|
||||
// a path to a fake file.
|
||||
func retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module android.Module) android.Path {
|
||||
bootDexJar := module.(interface{ DexJarBuildPath() android.Path }).DexJarBuildPath()
|
||||
if bootDexJar == nil {
|
||||
bootDexJar := module.(interface{ DexJarBuildPath() OptionalDexJarPath }).DexJarBuildPath()
|
||||
if !bootDexJar.Valid() {
|
||||
fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/encoded-dex/%s.jar", module.Name()))
|
||||
bootDexJar = fake
|
||||
|
||||
handleMissingDexBootFile(ctx, module, fake)
|
||||
handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason())
|
||||
return fake
|
||||
}
|
||||
return bootDexJar
|
||||
return bootDexJar.Path()
|
||||
}
|
||||
|
||||
// extractEncodedDexJarsFromModules extracts the encoded dex jars from the supplied modules.
|
||||
|
@@ -20,6 +20,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"android/soong/android"
|
||||
|
||||
"github.com/google/blueprint/proptools"
|
||||
)
|
||||
|
||||
@@ -306,7 +307,7 @@ func TestHiddenAPIEncoding_JavaSdkLibrary(t *testing.T) {
|
||||
android.AssertStringEquals(t, "encode embedded java_library", unencodedDexJar, actualUnencodedDexJar.String())
|
||||
|
||||
// Make sure that the encoded dex jar is the exported one.
|
||||
exportedDexJar := moduleForTests.Module().(UsesLibraryDependency).DexJarBuildPath()
|
||||
exportedDexJar := moduleForTests.Module().(UsesLibraryDependency).DexJarBuildPath().Path()
|
||||
android.AssertPathRelativeToTopEquals(t, "encode embedded java_library", encodedDexJar, exportedDexJar)
|
||||
}
|
||||
|
||||
|
23
java/java.go
23
java/java.go
@@ -219,7 +219,7 @@ type ApexDependency interface {
|
||||
|
||||
// Provides build path and install path to DEX jars.
|
||||
type UsesLibraryDependency interface {
|
||||
DexJarBuildPath() android.Path
|
||||
DexJarBuildPath() OptionalDexJarPath
|
||||
DexJarInstallPath() android.Path
|
||||
ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
|
||||
}
|
||||
@@ -1215,7 +1215,7 @@ type Import struct {
|
||||
properties ImportProperties
|
||||
|
||||
// output file containing classes.dex and resources
|
||||
dexJarFile android.Path
|
||||
dexJarFile OptionalDexJarPath
|
||||
dexJarInstallFile android.Path
|
||||
|
||||
combinedClasspathFile android.Path
|
||||
@@ -1370,11 +1370,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
// Get the path of the dex implementation jar from the `deapexer` module.
|
||||
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
|
||||
if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil {
|
||||
j.dexJarFile = dexOutputPath
|
||||
dexJarFile := makeDexJarPathFromPath(dexOutputPath)
|
||||
j.dexJarFile = dexJarFile
|
||||
j.dexJarInstallFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName()))
|
||||
|
||||
// Initialize the hiddenapi structure.
|
||||
j.initHiddenAPI(ctx, dexOutputPath, outputFile, nil)
|
||||
j.initHiddenAPI(ctx, dexJarFile, outputFile, nil)
|
||||
} else {
|
||||
// This should never happen as a variant for a prebuilt_apex is only created if the
|
||||
// prebuilt_apex has been configured to export the java library dex file.
|
||||
@@ -1407,12 +1408,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
}
|
||||
|
||||
// Initialize the hiddenapi structure.
|
||||
j.initHiddenAPI(ctx, dexOutputFile, outputFile, j.dexProperties.Uncompress_dex)
|
||||
j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), outputFile, j.dexProperties.Uncompress_dex)
|
||||
|
||||
// Encode hidden API flags in dex file.
|
||||
dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
|
||||
|
||||
j.dexJarFile = dexOutputFile
|
||||
j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
|
||||
j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName)
|
||||
}
|
||||
}
|
||||
@@ -1450,7 +1451,7 @@ func (j *Import) ImplementationAndResourcesJars() android.Paths {
|
||||
return android.Paths{j.combinedClasspathFile}
|
||||
}
|
||||
|
||||
func (j *Import) DexJarBuildPath() android.Path {
|
||||
func (j *Import) DexJarBuildPath() OptionalDexJarPath {
|
||||
return j.dexJarFile
|
||||
}
|
||||
|
||||
@@ -1595,7 +1596,7 @@ type DexImport struct {
|
||||
|
||||
properties DexImportProperties
|
||||
|
||||
dexJarFile android.Path
|
||||
dexJarFile OptionalDexJarPath
|
||||
|
||||
dexpreopter
|
||||
|
||||
@@ -1686,7 +1687,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
})
|
||||
}
|
||||
|
||||
j.dexJarFile = dexOutputFile
|
||||
j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
|
||||
|
||||
j.dexpreopt(ctx, dexOutputFile)
|
||||
|
||||
@@ -1696,7 +1697,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
}
|
||||
}
|
||||
|
||||
func (j *DexImport) DexJarBuildPath() android.Path {
|
||||
func (j *DexImport) DexJarBuildPath() OptionalDexJarPath {
|
||||
return j.dexJarFile
|
||||
}
|
||||
|
||||
@@ -1865,7 +1866,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
|
||||
// from its CLC should be added to the current CLC.
|
||||
if sdkLib != nil {
|
||||
clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, true,
|
||||
dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
|
||||
dep.DexJarBuildPath().PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
|
||||
} else {
|
||||
clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
|
||||
}
|
||||
|
@@ -600,8 +600,8 @@ func TestPrebuilts(t *testing.T) {
|
||||
}
|
||||
|
||||
barDexJar := barModule.Module().(*Import).DexJarBuildPath()
|
||||
if barDexJar != nil {
|
||||
t.Errorf("bar dex jar build path expected to be nil, got %q", barDexJar)
|
||||
if barDexJar.IsSet() {
|
||||
t.Errorf("bar dex jar build path expected to be set, got %s", barDexJar)
|
||||
}
|
||||
|
||||
if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) {
|
||||
@@ -612,7 +612,7 @@ func TestPrebuilts(t *testing.T) {
|
||||
t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String())
|
||||
}
|
||||
|
||||
bazDexJar := bazModule.Module().(*Import).DexJarBuildPath()
|
||||
bazDexJar := bazModule.Module().(*Import).DexJarBuildPath().Path()
|
||||
expectedDexJar := "out/soong/.intermediates/baz/android_common/dex/baz.jar"
|
||||
android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar)
|
||||
|
||||
|
@@ -540,7 +540,7 @@ type scopePaths struct {
|
||||
// The dex jar for the stubs.
|
||||
//
|
||||
// This is not the implementation jar, it still only contains stubs.
|
||||
stubsDexJarPath android.Path
|
||||
stubsDexJarPath OptionalDexJarPath
|
||||
|
||||
// The API specification file, e.g. system_current.txt.
|
||||
currentApiFilePath android.OptionalPath
|
||||
@@ -906,10 +906,10 @@ func sdkKindToApiScope(kind android.SdkKind) *apiScope {
|
||||
}
|
||||
|
||||
// to satisfy SdkLibraryDependency interface
|
||||
func (c *commonToSdkLibraryAndImport) SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) android.Path {
|
||||
func (c *commonToSdkLibraryAndImport) SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath {
|
||||
paths := c.selectScopePaths(ctx, kind)
|
||||
if paths == nil {
|
||||
return nil
|
||||
return makeUnsetDexJarPath()
|
||||
}
|
||||
|
||||
return paths.stubsDexJarPath
|
||||
@@ -1035,7 +1035,7 @@ type SdkLibraryDependency interface {
|
||||
|
||||
// SdkApiStubDexJar returns the dex jar for the stubs. It is needed by the hiddenapi processing
|
||||
// tool which processes dex files.
|
||||
SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) android.Path
|
||||
SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath
|
||||
|
||||
// SdkRemovedTxtFile returns the optional path to the removed.txt file for the specified sdk kind.
|
||||
SdkRemovedTxtFile(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath
|
||||
@@ -1929,7 +1929,7 @@ type SdkLibraryImport struct {
|
||||
xmlPermissionsFileModule *sdkLibraryXml
|
||||
|
||||
// Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
|
||||
dexJarFile android.Path
|
||||
dexJarFile OptionalDexJarPath
|
||||
|
||||
// Expected install file path of the source module(sdk_library)
|
||||
// or dex implementation jar obtained from the prebuilt_apex, if any.
|
||||
@@ -2220,11 +2220,12 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
|
||||
// Get the path of the dex implementation jar from the `deapexer` module.
|
||||
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
|
||||
if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil {
|
||||
module.dexJarFile = dexOutputPath
|
||||
dexJarFile := makeDexJarPathFromPath(dexOutputPath)
|
||||
module.dexJarFile = dexJarFile
|
||||
installPath := android.PathForModuleInPartitionInstall(
|
||||
ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(module.BaseModuleName()))
|
||||
module.installFile = installPath
|
||||
module.initHiddenAPI(ctx, dexOutputPath, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
|
||||
module.initHiddenAPI(ctx, dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
|
||||
|
||||
// Dexpreopting.
|
||||
module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, installPath)
|
||||
@@ -2269,14 +2270,14 @@ func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleCont
|
||||
}
|
||||
|
||||
// to satisfy UsesLibraryDependency interface
|
||||
func (module *SdkLibraryImport) DexJarBuildPath() android.Path {
|
||||
func (module *SdkLibraryImport) DexJarBuildPath() OptionalDexJarPath {
|
||||
// The dex implementation jar extracted from the .apex file should be used in preference to the
|
||||
// source.
|
||||
if module.dexJarFile != nil {
|
||||
if module.dexJarFile.IsSet() {
|
||||
return module.dexJarFile
|
||||
}
|
||||
if module.implLibraryModule == nil {
|
||||
return nil
|
||||
return makeUnsetDexJarPath()
|
||||
} else {
|
||||
return module.implLibraryModule.DexJarBuildPath()
|
||||
}
|
||||
|
@@ -1258,7 +1258,7 @@ java_sdk_library_import {
|
||||
ctx := android.ModuleInstallPathContextForTesting(result.Config)
|
||||
dexJarBuildPath := func(name string, kind android.SdkKind) string {
|
||||
dep := result.Module(name, "android_common").(java.SdkLibraryDependency)
|
||||
path := dep.SdkApiStubDexJar(ctx, kind)
|
||||
path := dep.SdkApiStubDexJar(ctx, kind).Path()
|
||||
return path.RelativeToTop().String()
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user