diff options
Diffstat (limited to 'java/app.go')
-rw-r--r-- | java/app.go | 266 |
1 files changed, 197 insertions, 69 deletions
diff --git a/java/app.go b/java/app.go index 31c338f4a..17548e74a 100644 --- a/java/app.go +++ b/java/app.go @@ -52,12 +52,6 @@ type FlagsPackages struct { var FlagsPackagesProvider = blueprint.NewProvider[FlagsPackages]() -type AndroidLibraryInfo struct { - // Empty for now -} - -var AndroidLibraryInfoProvider = blueprint.NewProvider[AndroidLibraryInfo]() - func RegisterAppBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("android_app", AndroidAppFactory) ctx.RegisterModuleType("android_test", AndroidTestFactory) @@ -76,6 +70,18 @@ type AppInfo struct { // EmbeddedJNILibs is the list of paths to JNI libraries that were embedded in the APK. EmbeddedJNILibs android.Paths + + MergedManifestFile android.Path + + Prebuilt bool + AppSet bool + Privileged bool + OutputFile android.Path + InstallApkName string + JacocoReportClassesFile android.Path + Certificate Certificate + PrivAppAllowlist android.OptionalPath + OverriddenManifestPackageName *string } var AppInfoProvider = blueprint.NewProvider[*AppInfo]() @@ -405,10 +411,20 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ TestOnly: true, }) - android.SetProvider(ctx, AppInfoProvider, &AppInfo{ + appInfo := &AppInfo{ Updatable: Bool(a.appProperties.Updatable), TestHelperApp: true, - }) + } + setCommonAppInfo(appInfo, a) + android.SetProvider(ctx, AppInfoProvider, appInfo) + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests") + if len(a.appTestHelperAppProperties.Test_suites) > 0 { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.appTestHelperAppProperties.Test_suites...) + } else { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") + } } func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -424,15 +440,28 @@ func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { embeddedJniLibs = append(embeddedJniLibs, jni.path) } } - android.SetProvider(ctx, AppInfoProvider, &AppInfo{ - Updatable: Bool(a.appProperties.Updatable), - TestHelperApp: false, - EmbeddedJNILibs: embeddedJniLibs, - }) - - android.SetProvider(ctx, AndroidLibraryInfoProvider, AndroidLibraryInfo{}) + overriddenName := a.OverriddenManifestPackageName() + appInfo := &AppInfo{ + Updatable: Bool(a.appProperties.Updatable), + TestHelperApp: false, + EmbeddedJNILibs: embeddedJniLibs, + MergedManifestFile: a.mergedManifest, + OverriddenManifestPackageName: &overriddenName, + } + setCommonAppInfo(appInfo, a) + android.SetProvider(ctx, AppInfoProvider, appInfo) a.requiredModuleNames = a.getRequiredModuleNames(ctx) + + if a.dexer.proguardDictionary.Valid() { + android.SetProvider(ctx, ProguardProvider, ProguardInfo{ + ModuleName: ctx.ModuleName(), + Class: "APPS", + ProguardDictionary: a.dexer.proguardDictionary.Path(), + ProguardUsageZip: a.dexer.proguardUsageZip.Path(), + ClassesJar: a.implementationAndResourcesJar, + }) + } } func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string { @@ -509,10 +538,14 @@ func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVer // The domain of cc.sdk_version is "current" and <number> // We can rely on android.SdkSpec to convert it to <number> so that "current" is // handled properly regardless of sdk finalization. - jniSdkVersion, err := android.SdkSpecFrom(ctx, commonInfo.MinSdkVersion).EffectiveVersion(ctx) + ver := "" + if !commonInfo.MinSdkVersion.IsPlatform { + ver = commonInfo.MinSdkVersion.ApiLevel.String() + } + jniSdkVersion, err := android.SdkSpecFrom(ctx, ver).EffectiveVersion(ctx) if err != nil || minSdkVersion.LessThan(jniSdkVersion) { ctx.OtherModuleErrorf(m, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)", - commonInfo.MinSdkVersion, minSdkVersion, ctx.ModuleName()) + ver, minSdkVersion, ctx.ModuleName()) return } @@ -681,7 +714,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) { var staticLibProguardFlagFiles android.Paths - ctx.VisitDirectDeps(func(m android.Module) { + ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider) staticLibProguardFlagFiles = append(staticLibProguardFlagFiles, depProguardInfo.UnconditionallyExportedProguardFlags.ToList()...) if ctx.OtherModuleDependencyTag(m) == staticLibTag { @@ -715,7 +748,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, android.Path) { +func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path, *JavaInfo) { a.dexpreopter.installPath = a.installPath(ctx) a.dexpreopter.isApp = true if a.dexProperties.Uncompress_dex == nil { @@ -761,12 +794,8 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, a packageResources = binaryResources } } - if javaInfo != nil { - setExtraJavaInfo(ctx, a, javaInfo) - android.SetProvider(ctx, JavaInfoProvider, javaInfo) - } - return a.dexJarFile.PathOrNil(), packageResources + return a.dexJarFile.PathOrNil(), packageResources, javaInfo } func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath { @@ -973,7 +1002,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.linter.resources = a.aapt.resourceFiles a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps() - dexJarFile, packageResources := a.dexBuildActions(ctx) + dexJarFile, packageResources, javaInfo := a.dexBuildActions(ctx) // No need to check the SDK version of the JNI deps unless we embed them checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis) @@ -1089,7 +1118,23 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { }, ) + if javaInfo != nil { + javaInfo.OutputFile = a.outputFile + setExtraJavaInfo(ctx, a, javaInfo) + android.SetProvider(ctx, JavaInfoProvider, javaInfo) + } + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"APPS"} + if !a.embeddedJniLibs { + for _, jniLib := range a.jniLibs { + moduleInfoJSON.ExtraRequired = append(moduleInfoJSON.ExtraRequired, jniLib.name) + } + } + a.setOutputFiles(ctx) + + buildComplianceMetadata(ctx) } func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) { @@ -1121,29 +1166,35 @@ func collectAppDeps(ctx android.ModuleContext, app appDepsInterface, app.SdkVersion(ctx).Kind != android.SdkCorePlatform && !app.RequiresStableAPIs(ctx) } jniLib, prebuiltJniPackages := collectJniDeps(ctx, shouldCollectRecursiveNativeDeps, - checkNativeSdkVersion, func(parent, child android.Module) bool { + checkNativeSdkVersion, func(parent, child android.ModuleProxy) bool { apkInApex := ctx.Module().(android.ApexModule).NotInPlatform() - childLinkable, _ := child.(cc.LinkableInterface) - parentLinkable, _ := parent.(cc.LinkableInterface) - useStubsOfDep := childLinkable.IsStubs() - if apkInApex && parentLinkable != nil { + childLinkable, _ := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider) + parentIsLinkable := false + if ctx.EqualModules(ctx.Module(), parent) { + parentLinkable, _ := ctx.Module().(cc.LinkableInterface) + parentIsLinkable = parentLinkable != nil + } else { + _, parentIsLinkable = android.OtherModuleProvider(ctx, parent, cc.LinkableInfoProvider) + } + useStubsOfDep := childLinkable.IsStubs + if apkInApex && parentIsLinkable { // APK-in-APEX // If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary. - useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants() && cc.ShouldUseStubForApex(ctx, parent, child)) + useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants && cc.ShouldUseStubForApex(ctx, parent, child)) } - return !childLinkable.IsNdk(ctx.Config()) && !useStubsOfDep + return !childLinkable.IsNdk && !useStubsOfDep }) var certificates []Certificate var directImplementationDeps android.Paths var transitiveImplementationDeps []depset.DepSet[android.Path] - ctx.VisitDirectDeps(func(module android.Module) { + ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { otherName := ctx.OtherModuleName(module) tag := ctx.OtherModuleDependencyTag(module) if tag == certificateTag { - if dep, ok := module.(*AndroidAppCertificate); ok { + if dep, ok := android.OtherModuleProvider(ctx, module, AndroidAppCertificateInfoProvider); ok { certificates = append(certificates, dep.Certificate) } else { ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", otherName) @@ -1167,22 +1218,25 @@ func collectAppDeps(ctx android.ModuleContext, app appDepsInterface, func collectJniDeps(ctx android.ModuleContext, shouldCollectRecursiveNativeDeps bool, checkNativeSdkVersion bool, - filter func(parent, child android.Module) bool) ([]jniLib, android.Paths) { + filter func(parent, child android.ModuleProxy) bool) ([]jniLib, android.Paths) { var jniLibs []jniLib var prebuiltJniPackages android.Paths seenModulePaths := make(map[string]bool) - ctx.WalkDeps(func(module android.Module, parent android.Module) bool { + ctx.WalkDepsProxy(func(module, parent android.ModuleProxy) bool { + if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled { + return false + } otherName := ctx.OtherModuleName(module) tag := ctx.OtherModuleDependencyTag(module) if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) { - if dep, ok := module.(cc.LinkableInterface); ok { + if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok { if filter != nil && !filter(parent, module) { return false } - lib := dep.OutputFile() + lib := dep.OutputFile if lib.Valid() { path := lib.Path() if seenModulePaths[path.String()] { @@ -1190,7 +1244,8 @@ func collectJniDeps(ctx android.ModuleContext, } seenModulePaths[path.String()] = true - if checkNativeSdkVersion && dep.SdkVersion() == "" { + commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey) + if checkNativeSdkVersion && commonInfo.SdkVersion == "" { ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not", otherName) } @@ -1198,11 +1253,11 @@ func collectJniDeps(ctx android.ModuleContext, jniLibs = append(jniLibs, jniLib{ name: ctx.OtherModuleName(module), path: path, - target: module.Target(), - coverageFile: dep.CoverageOutputFile(), - unstrippedFile: dep.UnstrippedOutputFile(), - partition: dep.Partition(), - installPaths: android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider).InstallFiles, + target: commonInfo.Target, + coverageFile: dep.CoverageOutputFile, + unstrippedFile: dep.UnstrippedOutputFile, + partition: dep.Partition, + installPaths: android.OtherModuleProviderOrDefault(ctx, module, android.InstallFilesProvider).InstallFiles, }) } else if ctx.Config().AllowMissingDependencies() { ctx.AddMissingDependencies([]string{otherName}) @@ -1231,7 +1286,7 @@ func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.P // TODO(ccross): Should this use android.DepIsInSameApex? Right now it is applying the android app // heuristics to every transitive dependency, when it should probably be using the heuristics of the // immediate parent. - isExternal := !a.OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child)) + isExternal := !a.GetDepInSameApexChecker().OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child)) if am, ok := child.(android.ApexModule); ok { if !do(ctx, parent, am, isExternal) { return false @@ -1252,7 +1307,7 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) { // Skip dependencies that are only available to APEXes; they are developed with updatability // in mind and don't need manual approval. - if to.(android.ApexModule).NotAvailableForPlatform() { + if android.OtherModuleProviderOrDefault(ctx, to, android.CommonModuleInfoKey).NotAvailableForPlatform { return true } @@ -1262,18 +1317,9 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) { depsInfo[depName] = info } else { toMinSdkVersion := "(no version)" - if m, ok := to.(interface { - MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel - }); ok { - if v := m.MinSdkVersion(ctx); !v.IsNone() { - toMinSdkVersion = v.String() - } - } else if m, ok := to.(interface{ MinSdkVersion() string }); ok { - // TODO(b/175678607) eliminate the use of MinSdkVersion returning - // string - if v := m.MinSdkVersion(); v != "" { - toMinSdkVersion = v - } + if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoKey); ok && + !info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil { + toMinSdkVersion = info.MinSdkVersion.ApiLevel.String() } depsInfo[depName] = android.ApexModuleDepInfo{ To: depName, @@ -1308,11 +1354,19 @@ func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string { return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "") } -func (a *AndroidApp) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool { +func (m *AndroidApp) GetDepInSameApexChecker() android.DepInSameApexChecker { + return AppDepInSameApexChecker{} +} + +type AppDepInSameApexChecker struct { + android.BaseDepInSameApexChecker +} + +func (m AppDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool { if IsJniDepTag(tag) { return true } - return a.Library.OutgoingDepIsInSameApex(tag) + return depIsInSameApex(tag) } func (a *AndroidApp) Privileged() bool { @@ -1592,6 +1646,24 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...) a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...) a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...) + a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Host_common_data)...) + + // Install test deps + if !ctx.Config().KatiEnabled() { + pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name()) + if a.testConfig != nil { + ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".config", a.testConfig) + } + dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".dynamic", dynamicConfig.Path()) + } + testDeps := append(a.data, a.extraTestConfigs...) + for _, data := range android.SortedUniquePaths(testDeps) { + dataPath := android.DataPath{SrcPath: data} + ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) + } + } android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: testcaseRel(a.data), @@ -1610,6 +1682,22 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { TopLevelTarget: true, }) + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests") + if a.testConfig != nil { + moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.testConfig.String()) + } + moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, a.extraTestConfigs.Strings()...) + if len(a.testProperties.Test_suites) > 0 { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, a.testProperties.Test_suites...) + } else { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") + } + + if _, ok := testConfig.(android.WritablePath); ok { + moduleInfoJSON.AutoTestConfig = []string{"true"} + } + moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...) } func testcaseRel(paths android.Paths) []string { @@ -1783,6 +1871,12 @@ type AndroidAppCertificateProperties struct { Certificate *string } +type AndroidAppCertificateInfo struct { + Certificate Certificate +} + +var AndroidAppCertificateInfoProvider = blueprint.NewProvider[AndroidAppCertificateInfo]() + // android_app_certificate modules can be referenced by the certificates property of android_app modules to select // the signing key. func AndroidAppCertificateFactory() android.Module { @@ -1798,6 +1892,10 @@ func (c *AndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleCo Pem: android.PathForModuleSrc(ctx, cert+".x509.pem"), Key: android.PathForModuleSrc(ctx, cert+".pk8"), } + + android.SetProvider(ctx, AndroidAppCertificateInfoProvider, AndroidAppCertificateInfo{ + Certificate: c.Certificate, + }) } type OverrideAndroidApp struct { @@ -1952,7 +2050,7 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext return clcMap } - ctx.VisitDirectDeps(func(m android.Module) { + ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag) if !isUsesLibTag { return @@ -1960,31 +2058,35 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m)) + javaInfo, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider) + if !ok { + return + } // Skip stub libraries. A dependency on the implementation library has been added earlier, // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed // from implementation libraries by their name, which is different as it has a suffix. - if comp, ok := m.(SdkLibraryComponentDependency); ok { - if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep { + if comp := javaInfo.SdkLibraryComponentDependencyInfo; comp != nil { + if impl := comp.OptionalSdkLibraryImplementation; impl != nil && *impl != dep { return } } - if lib, ok := m.(UsesLibraryDependency); ok { + if lib := javaInfo.UsesLibraryDependencyInfo; lib != nil { if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok { // Skip java_sdk_library dependencies that provide stubs, but not an implementation. // This will be restricted to optional_uses_libs - if tag == usesLibOptTag && lib.DexJarBuildPath(ctx).PathOrNil() == nil { + if tag == usesLibOptTag && javaInfo.DexJarBuildPath.PathOrNil() == nil { u.shouldDisableDexpreopt = true return } } libName := dep - if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil { - libName = *ulib.ProvidesUsesLib() + if ulib := javaInfo.ProvidesUsesLibInfo; ulib != nil && ulib.ProvidesUsesLib != nil { + libName = *ulib.ProvidesUsesLib } clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, - lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(), - lib.ClassLoaderContexts()) + javaInfo.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath, + lib.ClassLoaderContexts) } else if ctx.Config().AllowMissingDependencies() { ctx.AddMissingDependencies([]string{dep}) } else { @@ -2076,3 +2178,29 @@ func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk andr classLoaderContexts *dexpreopt.ClassLoaderContextMap) { u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file } + +// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in +// the same way. +type androidApp interface { + android.Module + Privileged() bool + InstallApkName() string + OutputFile() android.Path + JacocoReportClassesFile() android.Path + Certificate() Certificate + BaseModuleName() string + PrivAppAllowlist() android.OptionalPath +} + +var _ androidApp = (*AndroidApp)(nil) +var _ androidApp = (*AndroidAppImport)(nil) +var _ androidApp = (*AndroidTestHelperApp)(nil) + +func setCommonAppInfo(appInfo *AppInfo, m androidApp) { + appInfo.Privileged = m.Privileged() + appInfo.OutputFile = m.OutputFile() + appInfo.InstallApkName = m.InstallApkName() + appInfo.JacocoReportClassesFile = m.JacocoReportClassesFile() + appInfo.Certificate = m.Certificate() + appInfo.PrivAppAllowlist = m.PrivAppAllowlist() +} |