Loading dexpreopt/config.go +26 −8 Original line number Diff line number Diff line Loading @@ -111,12 +111,9 @@ type LibraryPath struct { // LibraryPaths is a map from library name to on-host and on-device paths to its DEX jar. type LibraryPaths map[string]*LibraryPath // Add a new path to the map of library paths, unless a path for this library already exists. func (libPaths LibraryPaths) AddLibraryPath(ctx android.PathContext, lib *string, hostPath, installPath android.Path) { if lib == nil { return } if _, present := libPaths[*lib]; !present { // Add a new library path to the map, unless a path for this library already exists. func (libPaths LibraryPaths) addLibraryPath(ctx android.PathContext, lib string, hostPath, installPath android.Path) { if _, present := libPaths[lib]; !present { var devicePath string if installPath != nil { devicePath = android.InstallPathToOnDevicePath(ctx, installPath.(android.InstallPath)) Loading @@ -127,9 +124,30 @@ func (libPaths LibraryPaths) AddLibraryPath(ctx android.PathContext, lib *string // but we cannot use if for dexpreopt. devicePath = UnknownInstallLibraryPath } libPaths[*lib] = &LibraryPath{hostPath, devicePath} libPaths[lib] = &LibraryPath{hostPath, devicePath} } } // Add a new library path to the map. Ensure that the build path to the library exists. func (libPaths LibraryPaths) AddLibraryPath(ctx android.PathContext, lib string, hostPath, installPath android.Path) { if hostPath != nil { // Add a library only if the build path to it is known. libPaths.addLibraryPath(ctx, lib, hostPath, installPath) } else if !ctx.Config().AllowMissingDependencies() { // Error on libraries with unknown build paths, unless missing dependencies are allowed. android.ReportPathErrorf(ctx, "unknown build path to <uses-library> '%s'", lib) } else { // Not adding a library to the map will likely result in disabling dexpreopt. } } // Add a new library path to the map, if the library exists (name is not nil). func (libPaths LibraryPaths) MaybeAddLibraryPath(ctx android.PathContext, lib *string, hostPath, installPath android.Path) { if lib != nil { // Don't check the build paths, add in any case. Some libraries may be missing from the // build, but their names still need to be added to <uses-library> tags in the manifest. libPaths.addLibraryPath(ctx, *lib, hostPath, installPath) } return } // Add library paths from the second map to the first map (do not override existing entries). Loading dexpreopt/dexpreopt.go +91 −41 Original line number Diff line number Diff line Loading @@ -81,15 +81,14 @@ func GenerateDexpreoptRule(ctx android.PathContext, globalSoong *GlobalSoongConf } if !dexpreoptDisabled(ctx, global, module) { // Don't preopt individual boot jars, they will be preopted together. if !global.BootJars.ContainsJar(module.Name) { if clc := genClassLoaderContext(ctx, global, module); clc != nil { appImage := (generateProfile || module.ForceCreateAppImage || global.DefaultAppImages) && !module.NoCreateAppImage generateDM := shouldGenerateDM(module, global) for archIdx, _ := range module.Archs { dexpreoptCommand(ctx, globalSoong, global, module, rule, archIdx, profile, appImage, generateDM) dexpreoptCommand(ctx, globalSoong, global, module, rule, archIdx, *clc, profile, appImage, generateDM) } } } Loading @@ -102,6 +101,11 @@ func dexpreoptDisabled(ctx android.PathContext, global *GlobalConfig, module *Mo return true } // Don't preopt individual boot jars, they will be preopted together. if global.BootJars.ContainsJar(module.Name) { return true } // Don't preopt system server jars that are updatable. if global.UpdatableSystemServerJars.ContainsJar(module.Name) { return true Loading Loading @@ -214,13 +218,17 @@ func (m classLoaderContextMap) getValue(sdkVer int) *classLoaderContext { return m[sdkVer] } func (m classLoaderContextMap) addLibs(sdkVer int, module *ModuleConfig, libs ...string) { func (m classLoaderContextMap) addLibs(sdkVer int, module *ModuleConfig, libs ...string) bool { clc := m.getValue(sdkVer) for _, lib := range libs { p := pathForLibrary(module, lib) if p := pathForLibrary(module, lib); p != nil { clc.Host = append(clc.Host, p.Host) clc.Target = append(clc.Target, p.Device) } else { return false } } return true } func (m classLoaderContextMap) addSystemServerLibs(sdkVer int, ctx android.PathContext, module *ModuleConfig, libs ...string) { Loading @@ -231,9 +239,79 @@ func (m classLoaderContextMap) addSystemServerLibs(sdkVer int, ctx android.PathC } } // genClassLoaderContext generates host and target class loader context to be passed to the dex2oat // command for the dexpreopted module. There are three possible cases: // // 1. System server jars. They have a special class loader context that includes other system // server jars. // // 2. Library jars or APKs which have precise list of their <uses-library> libs. Their class loader // context includes build and on-device paths to these libs. In some cases it may happen that // the path to a <uses-library> is unknown (e.g. the dexpreopted module may depend on stubs // library, whose implementation library is missing from the build altogether). In such case // dexpreopting with the <uses-library> is impossible, and dexpreopting without it is pointless, // as the runtime classpath won't match and the dexpreopted code will be discarded. Therefore in // such cases the function returns nil, which disables dexpreopt. // // 2. All other library jars or APKs for which the exact <uses-library> list is unknown. They use // the unsafe &-classpath workaround that means empty class loader context and absence of runtime // check that the class loader context provided by the PackageManager agrees with the stored // class loader context recorded in the .odex file. // func genClassLoaderContext(ctx android.PathContext, global *GlobalConfig, module *ModuleConfig) *classLoaderContextMap { classLoaderContexts := make(classLoaderContextMap) systemServerJars := NonUpdatableSystemServerJars(ctx, global) if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 { // System server jars should be dexpreopted together: class loader context of each jar // should include all preceding jars on the system server classpath. classLoaderContexts.addSystemServerLibs(anySdkVersion, ctx, module, systemServerJars[:jarIndex]...) } else if module.EnforceUsesLibraries { // Unconditional class loader context. usesLibs := append(copyOf(module.UsesLibraries), module.OptionalUsesLibraries...) if !classLoaderContexts.addLibs(anySdkVersion, module, usesLibs...) { return nil } // Conditional class loader context for API version < 28. const httpLegacy = "org.apache.http.legacy" if !contains(usesLibs, httpLegacy) { if !classLoaderContexts.addLibs(28, module, httpLegacy) { return nil } } // Conditional class loader context for API version < 29. usesLibs29 := []string{ "android.hidl.base-V1.0-java", "android.hidl.manager-V1.0-java", } if !classLoaderContexts.addLibs(29, module, usesLibs29...) { return nil } // Conditional class loader context for API version < 30. const testBase = "android.test.base" if !contains(usesLibs, testBase) { if !classLoaderContexts.addLibs(30, module, testBase) { return nil } } } else { // Pass special class loader context to skip the classpath and collision check. // This will get removed once LOCAL_USES_LIBRARIES is enforced. // Right now LOCAL_USES_LIBRARIES is opt in, for the case where it's not specified we still default // to the &. } return &classLoaderContexts } func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, global *GlobalConfig, module *ModuleConfig, rule *android.RuleBuilder, archIdx int, profile android.WritablePath, appImage bool, generateDM bool) { module *ModuleConfig, rule *android.RuleBuilder, archIdx int, classLoaderContexts classLoaderContextMap, profile android.WritablePath, appImage bool, generateDM bool) { arch := module.Archs[archIdx] Loading Loading @@ -264,17 +342,12 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g invocationPath := odexPath.ReplaceExtension(ctx, "invocation") classLoaderContexts := make(classLoaderContextMap) systemServerJars := NonUpdatableSystemServerJars(ctx, global) rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String())) rule.Command().FlagWithOutput("rm -f ", odexPath) if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 { // System server jars should be dexpreopted together: class loader context of each jar // should include all preceding jars on the system server classpath. classLoaderContexts.addSystemServerLibs(anySdkVersion, ctx, module, systemServerJars[:jarIndex]...) // Copy the system server jar to a predefined location where dex2oat will find it. dexPathHost := SystemServerDexJarHostPath(ctx, module.Name) rule.Command().Text("mkdir -p").Flag(filepath.Dir(dexPathHost.String())) Loading @@ -288,29 +361,6 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g Implicits(clc.Host). Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + strings.Join(clc.Target, ":") + "]") } else if module.EnforceUsesLibraries { // Unconditional class loader context. usesLibs := append(copyOf(module.UsesLibraries), module.OptionalUsesLibraries...) classLoaderContexts.addLibs(anySdkVersion, module, usesLibs...) // Conditional class loader context for API version < 28. const httpLegacy = "org.apache.http.legacy" if !contains(usesLibs, httpLegacy) { classLoaderContexts.addLibs(28, module, httpLegacy) } // Conditional class loader context for API version < 29. usesLibs29 := []string{ "android.hidl.base-V1.0-java", "android.hidl.manager-V1.0-java", } classLoaderContexts.addLibs(29, module, usesLibs29...) // Conditional class loader context for API version < 30. const testBase = "android.test.base" if !contains(usesLibs, testBase) { classLoaderContexts.addLibs(30, module, testBase) } // Generate command that saves target SDK version in a shell variable. if module.ManifestPath != nil { rule.Command().Text(`target_sdk_version="$(`). Loading Loading @@ -540,11 +590,11 @@ func PathToLocation(path android.Path, arch android.ArchType) string { } func pathForLibrary(module *ModuleConfig, lib string) *LibraryPath { path, ok := module.LibraryPaths[lib] if !ok { panic(fmt.Errorf("unknown library path for %q", lib)) } if path, ok := module.LibraryPaths[lib]; ok && path.Host != nil && path.Device != "error" { return path } else { return nil } } func makefileMatch(pattern, s string) bool { Loading java/aar.go +1 −1 Original line number Diff line number Diff line Loading @@ -390,7 +390,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati // (including the java_sdk_library) itself then append any implicit sdk library // names to the list of sdk libraries to be added to the manifest. if component, ok := module.(SdkLibraryComponentDependency); ok { sdkLibraries.AddLibraryPath(ctx, component.OptionalImplicitSdkLibrary(), sdkLibraries.MaybeAddLibraryPath(ctx, component.OptionalImplicitSdkLibrary(), component.DexJarBuildPath(), component.DexJarInstallPath()) } Loading java/app.go +28 −2 Original line number Diff line number Diff line Loading @@ -586,7 +586,7 @@ func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk") } func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path { func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext, sdkLibs dexpreopt.LibraryPaths) android.Path { a.dexpreopter.installPath = a.installPath(ctx) if a.dexProperties.Uncompress_dex == nil { // If the value was not force-set by the user, use reasonable default based on the module. Loading @@ -597,6 +597,7 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path { a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx) a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx) a.dexpreopter.libraryPaths.AddLibraryPaths(sdkLibs) a.dexpreopter.manifestFile = a.mergedManifestFile a.exportedSdkLibs = make(dexpreopt.LibraryPaths) Loading Loading @@ -767,6 +768,15 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { // Process all building blocks, from AAPT to certificates. a.aaptBuildActions(ctx) // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries. a.usesLibrary.freezeEnforceUsesLibraries() // Add implicit SDK libraries to <uses-library> list. for _, usesLib := range android.SortedStringKeys(a.aapt.sdkLibraries) { a.usesLibrary.addLib(usesLib, inList(usesLib, optionalUsesLibs)) } // Check that the <uses-library> list is coherent with the manifest. if a.usesLibrary.enforceUsesLibraries() { manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile) apkDeps = append(apkDeps, manifestCheckFile) Loading @@ -779,7 +789,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.linter.resources = a.aapt.resourceFiles a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps() dexJarFile := a.dexBuildActions(ctx) dexJarFile := a.dexBuildActions(ctx, a.aapt.sdkLibraries) jniLibs, certificateDeps := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis)) jniJarFile := a.jniBuildActions(jniLibs, ctx) Loading Loading @@ -1888,6 +1898,16 @@ type usesLibrary struct { usesLibraryProperties UsesLibraryProperties } func (u *usesLibrary) addLib(lib string, optional bool) { if !android.InList(lib, u.usesLibraryProperties.Uses_libs) && !android.InList(lib, u.usesLibraryProperties.Optional_uses_libs) { if optional { u.usesLibraryProperties.Optional_uses_libs = append(u.usesLibraryProperties.Optional_uses_libs, lib) } else { u.usesLibraryProperties.Uses_libs = append(u.usesLibraryProperties.Uses_libs, lib) } } } func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) { if !ctx.Config().UnbundledBuild() { ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...) Loading Loading @@ -1960,6 +1980,12 @@ func (u *usesLibrary) enforceUsesLibraries() bool { return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, defaultEnforceUsesLibs) } // Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`. func (u *usesLibrary) freezeEnforceUsesLibraries() { enforce := u.enforceUsesLibraries() u.usesLibraryProperties.Enforce_uses_libs = &enforce } // verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against the ones specified // in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the manifest. func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path { Loading java/app_test.go +27 −4 Original line number Diff line number Diff line Loading @@ -2618,6 +2618,19 @@ func TestUsesLibraries(t *testing.T) { android_app { name: "app", srcs: ["a.java"], libs: ["qux", "quuz"], static_libs: ["static-runtime-helper"], uses_libs: ["foo"], sdk_version: "current", optional_uses_libs: [ "bar", "baz", ], } android_app { name: "app_with_stub_deps", srcs: ["a.java"], libs: ["qux", "quuz.stubs"], static_libs: ["static-runtime-helper"], uses_libs: ["foo"], Loading Loading @@ -2648,6 +2661,7 @@ func TestUsesLibraries(t *testing.T) { run(t, ctx, config) app := ctx.ModuleForTests("app", "android_common") appWithStubDeps := ctx.ModuleForTests("app_with_stub_deps", "android_common") prebuilt := ctx.ModuleForTests("prebuilt", "android_common") // Test that implicit dependencies on java_sdk_library instances are passed to the manifest. Loading Loading @@ -2678,15 +2692,24 @@ func TestUsesLibraries(t *testing.T) { t.Errorf("wanted %q in %q", w, cmd) } // Test that only present libraries are preopted // Test that all present libraries are preopted, including implicit SDK dependencies cmd = app.Rule("dexpreopt").RuleParams.Command if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) { w := `--target-classpath-for-sdk any` + ` /system/framework/foo.jar` + `:/system/framework/quuz.jar` + `:/system/framework/qux.jar` + `:/system/framework/runtime-library.jar` + `:/system/framework/bar.jar` if !strings.Contains(cmd, w) { t.Errorf("wanted %q in %q", w, cmd) } cmd = prebuilt.Rule("dexpreopt").RuleParams.Command // TODO(skvadrik) fix dexpreopt for stub libraries for which the implementation is present if appWithStubDeps.MaybeRule("dexpreopt").RuleParams.Command != "" { t.Errorf("dexpreopt should be disabled for apps with dependencies on stub libraries") } cmd = prebuilt.Rule("dexpreopt").RuleParams.Command if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) { t.Errorf("wanted %q in %q", w, cmd) } Loading Loading
dexpreopt/config.go +26 −8 Original line number Diff line number Diff line Loading @@ -111,12 +111,9 @@ type LibraryPath struct { // LibraryPaths is a map from library name to on-host and on-device paths to its DEX jar. type LibraryPaths map[string]*LibraryPath // Add a new path to the map of library paths, unless a path for this library already exists. func (libPaths LibraryPaths) AddLibraryPath(ctx android.PathContext, lib *string, hostPath, installPath android.Path) { if lib == nil { return } if _, present := libPaths[*lib]; !present { // Add a new library path to the map, unless a path for this library already exists. func (libPaths LibraryPaths) addLibraryPath(ctx android.PathContext, lib string, hostPath, installPath android.Path) { if _, present := libPaths[lib]; !present { var devicePath string if installPath != nil { devicePath = android.InstallPathToOnDevicePath(ctx, installPath.(android.InstallPath)) Loading @@ -127,9 +124,30 @@ func (libPaths LibraryPaths) AddLibraryPath(ctx android.PathContext, lib *string // but we cannot use if for dexpreopt. devicePath = UnknownInstallLibraryPath } libPaths[*lib] = &LibraryPath{hostPath, devicePath} libPaths[lib] = &LibraryPath{hostPath, devicePath} } } // Add a new library path to the map. Ensure that the build path to the library exists. func (libPaths LibraryPaths) AddLibraryPath(ctx android.PathContext, lib string, hostPath, installPath android.Path) { if hostPath != nil { // Add a library only if the build path to it is known. libPaths.addLibraryPath(ctx, lib, hostPath, installPath) } else if !ctx.Config().AllowMissingDependencies() { // Error on libraries with unknown build paths, unless missing dependencies are allowed. android.ReportPathErrorf(ctx, "unknown build path to <uses-library> '%s'", lib) } else { // Not adding a library to the map will likely result in disabling dexpreopt. } } // Add a new library path to the map, if the library exists (name is not nil). func (libPaths LibraryPaths) MaybeAddLibraryPath(ctx android.PathContext, lib *string, hostPath, installPath android.Path) { if lib != nil { // Don't check the build paths, add in any case. Some libraries may be missing from the // build, but their names still need to be added to <uses-library> tags in the manifest. libPaths.addLibraryPath(ctx, *lib, hostPath, installPath) } return } // Add library paths from the second map to the first map (do not override existing entries). Loading
dexpreopt/dexpreopt.go +91 −41 Original line number Diff line number Diff line Loading @@ -81,15 +81,14 @@ func GenerateDexpreoptRule(ctx android.PathContext, globalSoong *GlobalSoongConf } if !dexpreoptDisabled(ctx, global, module) { // Don't preopt individual boot jars, they will be preopted together. if !global.BootJars.ContainsJar(module.Name) { if clc := genClassLoaderContext(ctx, global, module); clc != nil { appImage := (generateProfile || module.ForceCreateAppImage || global.DefaultAppImages) && !module.NoCreateAppImage generateDM := shouldGenerateDM(module, global) for archIdx, _ := range module.Archs { dexpreoptCommand(ctx, globalSoong, global, module, rule, archIdx, profile, appImage, generateDM) dexpreoptCommand(ctx, globalSoong, global, module, rule, archIdx, *clc, profile, appImage, generateDM) } } } Loading @@ -102,6 +101,11 @@ func dexpreoptDisabled(ctx android.PathContext, global *GlobalConfig, module *Mo return true } // Don't preopt individual boot jars, they will be preopted together. if global.BootJars.ContainsJar(module.Name) { return true } // Don't preopt system server jars that are updatable. if global.UpdatableSystemServerJars.ContainsJar(module.Name) { return true Loading Loading @@ -214,13 +218,17 @@ func (m classLoaderContextMap) getValue(sdkVer int) *classLoaderContext { return m[sdkVer] } func (m classLoaderContextMap) addLibs(sdkVer int, module *ModuleConfig, libs ...string) { func (m classLoaderContextMap) addLibs(sdkVer int, module *ModuleConfig, libs ...string) bool { clc := m.getValue(sdkVer) for _, lib := range libs { p := pathForLibrary(module, lib) if p := pathForLibrary(module, lib); p != nil { clc.Host = append(clc.Host, p.Host) clc.Target = append(clc.Target, p.Device) } else { return false } } return true } func (m classLoaderContextMap) addSystemServerLibs(sdkVer int, ctx android.PathContext, module *ModuleConfig, libs ...string) { Loading @@ -231,9 +239,79 @@ func (m classLoaderContextMap) addSystemServerLibs(sdkVer int, ctx android.PathC } } // genClassLoaderContext generates host and target class loader context to be passed to the dex2oat // command for the dexpreopted module. There are three possible cases: // // 1. System server jars. They have a special class loader context that includes other system // server jars. // // 2. Library jars or APKs which have precise list of their <uses-library> libs. Their class loader // context includes build and on-device paths to these libs. In some cases it may happen that // the path to a <uses-library> is unknown (e.g. the dexpreopted module may depend on stubs // library, whose implementation library is missing from the build altogether). In such case // dexpreopting with the <uses-library> is impossible, and dexpreopting without it is pointless, // as the runtime classpath won't match and the dexpreopted code will be discarded. Therefore in // such cases the function returns nil, which disables dexpreopt. // // 2. All other library jars or APKs for which the exact <uses-library> list is unknown. They use // the unsafe &-classpath workaround that means empty class loader context and absence of runtime // check that the class loader context provided by the PackageManager agrees with the stored // class loader context recorded in the .odex file. // func genClassLoaderContext(ctx android.PathContext, global *GlobalConfig, module *ModuleConfig) *classLoaderContextMap { classLoaderContexts := make(classLoaderContextMap) systemServerJars := NonUpdatableSystemServerJars(ctx, global) if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 { // System server jars should be dexpreopted together: class loader context of each jar // should include all preceding jars on the system server classpath. classLoaderContexts.addSystemServerLibs(anySdkVersion, ctx, module, systemServerJars[:jarIndex]...) } else if module.EnforceUsesLibraries { // Unconditional class loader context. usesLibs := append(copyOf(module.UsesLibraries), module.OptionalUsesLibraries...) if !classLoaderContexts.addLibs(anySdkVersion, module, usesLibs...) { return nil } // Conditional class loader context for API version < 28. const httpLegacy = "org.apache.http.legacy" if !contains(usesLibs, httpLegacy) { if !classLoaderContexts.addLibs(28, module, httpLegacy) { return nil } } // Conditional class loader context for API version < 29. usesLibs29 := []string{ "android.hidl.base-V1.0-java", "android.hidl.manager-V1.0-java", } if !classLoaderContexts.addLibs(29, module, usesLibs29...) { return nil } // Conditional class loader context for API version < 30. const testBase = "android.test.base" if !contains(usesLibs, testBase) { if !classLoaderContexts.addLibs(30, module, testBase) { return nil } } } else { // Pass special class loader context to skip the classpath and collision check. // This will get removed once LOCAL_USES_LIBRARIES is enforced. // Right now LOCAL_USES_LIBRARIES is opt in, for the case where it's not specified we still default // to the &. } return &classLoaderContexts } func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, global *GlobalConfig, module *ModuleConfig, rule *android.RuleBuilder, archIdx int, profile android.WritablePath, appImage bool, generateDM bool) { module *ModuleConfig, rule *android.RuleBuilder, archIdx int, classLoaderContexts classLoaderContextMap, profile android.WritablePath, appImage bool, generateDM bool) { arch := module.Archs[archIdx] Loading Loading @@ -264,17 +342,12 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g invocationPath := odexPath.ReplaceExtension(ctx, "invocation") classLoaderContexts := make(classLoaderContextMap) systemServerJars := NonUpdatableSystemServerJars(ctx, global) rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String())) rule.Command().FlagWithOutput("rm -f ", odexPath) if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 { // System server jars should be dexpreopted together: class loader context of each jar // should include all preceding jars on the system server classpath. classLoaderContexts.addSystemServerLibs(anySdkVersion, ctx, module, systemServerJars[:jarIndex]...) // Copy the system server jar to a predefined location where dex2oat will find it. dexPathHost := SystemServerDexJarHostPath(ctx, module.Name) rule.Command().Text("mkdir -p").Flag(filepath.Dir(dexPathHost.String())) Loading @@ -288,29 +361,6 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g Implicits(clc.Host). Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + strings.Join(clc.Target, ":") + "]") } else if module.EnforceUsesLibraries { // Unconditional class loader context. usesLibs := append(copyOf(module.UsesLibraries), module.OptionalUsesLibraries...) classLoaderContexts.addLibs(anySdkVersion, module, usesLibs...) // Conditional class loader context for API version < 28. const httpLegacy = "org.apache.http.legacy" if !contains(usesLibs, httpLegacy) { classLoaderContexts.addLibs(28, module, httpLegacy) } // Conditional class loader context for API version < 29. usesLibs29 := []string{ "android.hidl.base-V1.0-java", "android.hidl.manager-V1.0-java", } classLoaderContexts.addLibs(29, module, usesLibs29...) // Conditional class loader context for API version < 30. const testBase = "android.test.base" if !contains(usesLibs, testBase) { classLoaderContexts.addLibs(30, module, testBase) } // Generate command that saves target SDK version in a shell variable. if module.ManifestPath != nil { rule.Command().Text(`target_sdk_version="$(`). Loading Loading @@ -540,11 +590,11 @@ func PathToLocation(path android.Path, arch android.ArchType) string { } func pathForLibrary(module *ModuleConfig, lib string) *LibraryPath { path, ok := module.LibraryPaths[lib] if !ok { panic(fmt.Errorf("unknown library path for %q", lib)) } if path, ok := module.LibraryPaths[lib]; ok && path.Host != nil && path.Device != "error" { return path } else { return nil } } func makefileMatch(pattern, s string) bool { Loading
java/aar.go +1 −1 Original line number Diff line number Diff line Loading @@ -390,7 +390,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati // (including the java_sdk_library) itself then append any implicit sdk library // names to the list of sdk libraries to be added to the manifest. if component, ok := module.(SdkLibraryComponentDependency); ok { sdkLibraries.AddLibraryPath(ctx, component.OptionalImplicitSdkLibrary(), sdkLibraries.MaybeAddLibraryPath(ctx, component.OptionalImplicitSdkLibrary(), component.DexJarBuildPath(), component.DexJarInstallPath()) } Loading
java/app.go +28 −2 Original line number Diff line number Diff line Loading @@ -586,7 +586,7 @@ func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk") } func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path { func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext, sdkLibs dexpreopt.LibraryPaths) android.Path { a.dexpreopter.installPath = a.installPath(ctx) if a.dexProperties.Uncompress_dex == nil { // If the value was not force-set by the user, use reasonable default based on the module. Loading @@ -597,6 +597,7 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path { a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx) a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx) a.dexpreopter.libraryPaths.AddLibraryPaths(sdkLibs) a.dexpreopter.manifestFile = a.mergedManifestFile a.exportedSdkLibs = make(dexpreopt.LibraryPaths) Loading Loading @@ -767,6 +768,15 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { // Process all building blocks, from AAPT to certificates. a.aaptBuildActions(ctx) // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries. a.usesLibrary.freezeEnforceUsesLibraries() // Add implicit SDK libraries to <uses-library> list. for _, usesLib := range android.SortedStringKeys(a.aapt.sdkLibraries) { a.usesLibrary.addLib(usesLib, inList(usesLib, optionalUsesLibs)) } // Check that the <uses-library> list is coherent with the manifest. if a.usesLibrary.enforceUsesLibraries() { manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile) apkDeps = append(apkDeps, manifestCheckFile) Loading @@ -779,7 +789,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.linter.resources = a.aapt.resourceFiles a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps() dexJarFile := a.dexBuildActions(ctx) dexJarFile := a.dexBuildActions(ctx, a.aapt.sdkLibraries) jniLibs, certificateDeps := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis)) jniJarFile := a.jniBuildActions(jniLibs, ctx) Loading Loading @@ -1888,6 +1898,16 @@ type usesLibrary struct { usesLibraryProperties UsesLibraryProperties } func (u *usesLibrary) addLib(lib string, optional bool) { if !android.InList(lib, u.usesLibraryProperties.Uses_libs) && !android.InList(lib, u.usesLibraryProperties.Optional_uses_libs) { if optional { u.usesLibraryProperties.Optional_uses_libs = append(u.usesLibraryProperties.Optional_uses_libs, lib) } else { u.usesLibraryProperties.Uses_libs = append(u.usesLibraryProperties.Uses_libs, lib) } } } func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) { if !ctx.Config().UnbundledBuild() { ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...) Loading Loading @@ -1960,6 +1980,12 @@ func (u *usesLibrary) enforceUsesLibraries() bool { return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, defaultEnforceUsesLibs) } // Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`. func (u *usesLibrary) freezeEnforceUsesLibraries() { enforce := u.enforceUsesLibraries() u.usesLibraryProperties.Enforce_uses_libs = &enforce } // verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against the ones specified // in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the manifest. func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path { Loading
java/app_test.go +27 −4 Original line number Diff line number Diff line Loading @@ -2618,6 +2618,19 @@ func TestUsesLibraries(t *testing.T) { android_app { name: "app", srcs: ["a.java"], libs: ["qux", "quuz"], static_libs: ["static-runtime-helper"], uses_libs: ["foo"], sdk_version: "current", optional_uses_libs: [ "bar", "baz", ], } android_app { name: "app_with_stub_deps", srcs: ["a.java"], libs: ["qux", "quuz.stubs"], static_libs: ["static-runtime-helper"], uses_libs: ["foo"], Loading Loading @@ -2648,6 +2661,7 @@ func TestUsesLibraries(t *testing.T) { run(t, ctx, config) app := ctx.ModuleForTests("app", "android_common") appWithStubDeps := ctx.ModuleForTests("app_with_stub_deps", "android_common") prebuilt := ctx.ModuleForTests("prebuilt", "android_common") // Test that implicit dependencies on java_sdk_library instances are passed to the manifest. Loading Loading @@ -2678,15 +2692,24 @@ func TestUsesLibraries(t *testing.T) { t.Errorf("wanted %q in %q", w, cmd) } // Test that only present libraries are preopted // Test that all present libraries are preopted, including implicit SDK dependencies cmd = app.Rule("dexpreopt").RuleParams.Command if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) { w := `--target-classpath-for-sdk any` + ` /system/framework/foo.jar` + `:/system/framework/quuz.jar` + `:/system/framework/qux.jar` + `:/system/framework/runtime-library.jar` + `:/system/framework/bar.jar` if !strings.Contains(cmd, w) { t.Errorf("wanted %q in %q", w, cmd) } cmd = prebuilt.Rule("dexpreopt").RuleParams.Command // TODO(skvadrik) fix dexpreopt for stub libraries for which the implementation is present if appWithStubDeps.MaybeRule("dexpreopt").RuleParams.Command != "" { t.Errorf("dexpreopt should be disabled for apps with dependencies on stub libraries") } cmd = prebuilt.Rule("dexpreopt").RuleParams.Command if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) { t.Errorf("wanted %q in %q", w, cmd) } Loading