Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91a86d41 authored by Jihoon Kang's avatar Jihoon Kang Committed by Gerrit Code Review
Browse files

Merge "Add dep_api_srcs property to java_api_library module"

parents 7a646211 01e522ca
Loading
Loading
Loading
Loading
+82 −14
Original line number Diff line number Diff line
@@ -388,6 +388,8 @@ var (
	jniLibTag               = dependencyTag{name: "jnilib", runtimeLinked: true}
	r8LibraryJarTag         = dependencyTag{name: "r8-libraryjar", runtimeLinked: true}
	syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
	javaApiContributionTag  = dependencyTag{name: "java-api-contribution"}
	depApiSrcsTag           = dependencyTag{name: "dep-api-srcs"}
	jniInstallTag           = installDependencyTag{name: "jni install"}
	binaryInstallTag        = installDependencyTag{name: "binary install"}
	usesLibReqTag           = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
@@ -1609,6 +1611,13 @@ func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleCon
	})
}

type JavaApiLibraryDepsInfo struct {
	StubsJar    android.Path
	StubsSrcJar android.Path
}

var JavaApiLibraryDepsProvider = blueprint.NewProvider(JavaApiLibraryDepsInfo{})

type ApiLibrary struct {
	android.ModuleBase
	android.DefaultableModuleBase
@@ -1620,6 +1629,8 @@ type ApiLibrary struct {

	stubsSrcJar               android.WritablePath
	stubsJar                  android.WritablePath
	stubsJarWithoutStaticLibs android.WritablePath
	extractedSrcJar           android.WritablePath
	// .dex of stubs, used for hiddenapi processing
	dexJarFile OptionalDexJarPath
}
@@ -1645,8 +1656,13 @@ type JavaApiLibraryProperties struct {
	Libs []string

	// List of java libs that this module has static dependencies to and will be
	// passed in metalava invocation
	// merge zipped after metalava invocation
	Static_libs []string

	// Java Api library to provide the full API surface text files and jar file.
	// If this property is set, the provided full API surface text files and
	// jar file are passed to metalava invocation.
	Dep_api_srcs *string
}

func ApiLibraryFactory() android.Module {
@@ -1725,7 +1741,36 @@ func (al *ApiLibrary) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBui
	}
}

var javaApiContributionTag = dependencyTag{name: "java-api-contribution"}
// This method extracts the stub java files from the srcjar file provided from dep_api_srcs module
// and replaces the java stubs generated by invoking metalava in this module.
// This method is used because metalava can generate compilable from-text stubs only when
// the codebase encompasses all classes listed in the input API text file, but a class can extend
// a class that is not within the same API domain.
func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.RuleBuilder, stubsDir android.OptionalPath, depApiSrcsSrcJar android.Path) {
	generatedStubsList := android.PathForModuleOut(ctx, "metalava", "sources.txt")
	unzippedSrcJarDir := android.PathForModuleOut(ctx, "metalava", "unzipDir")

	rule.Command().
		BuiltTool("list_files").
		Text(stubsDir.String()).
		FlagWithOutput("--out ", generatedStubsList).
		FlagWithArg("--extensions ", ".java").
		FlagWithArg("--root ", unzippedSrcJarDir.String())

	rule.Command().
		Text("unzip").
		Flag("-q").
		Input(depApiSrcsSrcJar).
		FlagWithArg("-d ", unzippedSrcJarDir.String())

	rule.Command().
		BuiltTool("soong_zip").
		Flag("-srcjar").
		Flag("-write_if_changed").
		FlagWithArg("-C ", unzippedSrcJarDir.String()).
		FlagWithInput("-l ", generatedStubsList).
		FlagWithOutput("-o ", al.stubsSrcJar)
}

func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
	apiContributions := al.properties.Api_contributions
@@ -1734,6 +1779,9 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
	}
	ctx.AddVariationDependencies(nil, libTag, al.properties.Libs...)
	ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs...)
	if al.properties.Dep_api_srcs != nil {
		ctx.AddVariationDependencies(nil, depApiSrcsTag, String(al.properties.Dep_api_srcs))
	}
}

func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1754,6 +1802,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	var srcFiles android.Paths
	var classPaths android.Paths
	var staticLibs android.Paths
	var depApiSrcsStubsSrcJar android.Path
	ctx.VisitDirectDeps(func(dep android.Module) {
		tag := ctx.OtherModuleDependencyTag(dep)
		switch tag {
@@ -1770,6 +1819,10 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		case staticLibTag:
			provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
			staticLibs = append(staticLibs, provider.HeaderJars...)
		case depApiSrcsTag:
			provider := ctx.OtherModuleProvider(dep, JavaApiLibraryDepsProvider).(JavaApiLibraryDepsInfo)
			classPaths = append(classPaths, provider.StubsJar)
			depApiSrcsStubsSrcJar = provider.StubsSrcJar
		}
	})

@@ -1780,11 +1833,19 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		srcFiles = append(srcFiles, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), api))
	}

	if srcFiles == nil {
		ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName())
	}

	cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir)

	al.stubsFlags(ctx, cmd, stubsDir)

	al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar")

	if depApiSrcsStubsSrcJar != nil {
		al.extractApiSrcs(ctx, rule, stubsDir, depApiSrcsStubsSrcJar)
	} else {
		rule.Command().
			BuiltTool("soong_zip").
			Flag("-write_if_changed").
@@ -1792,9 +1853,11 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
			FlagWithOutput("-o ", al.stubsSrcJar).
			FlagWithArg("-C ", stubsDir.String()).
			FlagWithArg("-D ", stubsDir.String())
	}

	rule.Build("metalava", "metalava merged")
	compiledStubs := android.PathForModuleOut(ctx, ctx.ModuleName(), "stubs.jar")

	al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, ctx.ModuleName(), "stubs.jar")
	al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName()))

	var flags javaBuilderFlags
@@ -1802,14 +1865,14 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	flags.javacFlags = strings.Join(al.properties.Javacflags, " ")
	flags.classpath = classpath(classPaths)

	TransformJavaToClasses(ctx, compiledStubs, 0, android.Paths{},
	TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{},
		android.Paths{al.stubsSrcJar}, flags, android.Paths{})

	builder := android.NewRuleBuilder(pctx, ctx)
	builder.Command().
		BuiltTool("merge_zips").
		Output(al.stubsJar).
		Inputs(android.Paths{compiledStubs}).
		Inputs(android.Paths{al.stubsJarWithoutStaticLibs}).
		Inputs(staticLibs)
	builder.Build("merge_zips", "merge jar files")

@@ -1835,6 +1898,11 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		ImplementationJars:             android.PathsIfNonNil(al.stubsJar),
		AidlIncludeDirs:                android.Paths{},
	})

	ctx.SetProvider(JavaApiLibraryDepsProvider, JavaApiLibraryDepsInfo{
		StubsJar:    al.stubsJar,
		StubsSrcJar: al.stubsSrcJar,
	})
}

func (al *ApiLibrary) DexJarBuildPath() OptionalDexJarPath {
+44 −0
Original line number Diff line number Diff line
@@ -2209,6 +2209,50 @@ func TestJavaApiLibraryStaticLibsLink(t *testing.T) {
	}
}

func TestJavaApiLibraryDepApiSrcs(t *testing.T) {
	provider_bp_a := `
	java_api_contribution {
		name: "foo1",
		api_file: "foo1.txt",
	}
	`
	provider_bp_b := `
	java_api_contribution {
		name: "foo2",
		api_file: "foo2.txt",
	}
	`
	lib_bp_a := `
	java_api_library {
		name: "lib1",
		api_surface: "public",
		api_contributions: ["foo1", "foo2"],
	}
	`

	ctx, _ := testJavaWithFS(t, `
		java_api_library {
			name: "bar1",
			api_surface: "public",
			api_contributions: ["foo1"],
			dep_api_srcs: "lib1",
		}
		`,
		map[string][]byte{
			"a/Android.bp": []byte(provider_bp_a),
			"b/Android.bp": []byte(provider_bp_b),
			"c/Android.bp": []byte(lib_bp_a),
		})

	m := ctx.ModuleForTests("bar1", "android_common")
	manifest := m.Output("metalava.sbox.textproto")
	sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest)
	manifestCommand := sboxProto.Commands[0].GetCommand()

	android.AssertStringDoesContain(t, "Command expected to contain module srcjar file", manifestCommand, "bar1-stubs.srcjar")
	android.AssertStringDoesContain(t, "Command expected to contain output files list text file flag", manifestCommand, "--out __SBOX_SANDBOX_DIR__/out/sources.txt")
}

func TestTradefedOptions(t *testing.T) {
	result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
java_test_host {