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

Commit b3090501 authored by satayev's avatar satayev
Browse files

Append platform classpath proto configs with missing apex jars.

Any apex classpath fragment that doesn't generate its own classpaths
proto, must still propagate it's boot jars for the platform classpath
fragment to include for complete CLASSPATH variables on device.

Bug: 191127295
Test: atest CtsClasspathsTestCases derive_classpath_test
Change-Id: I93687f69006741fcd66eb6e04891a4b4bbcc3b47
parent f93d3883
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -481,3 +481,62 @@ func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, varia
	pairs := java.ApexNamePairsFromModules(ctx, modules)
	android.AssertDeepEquals(t, "module dependencies", expected, pairs)
}

// TestPlatformBootclasspath_IncludesRemainingApexJars verifies that any apex boot jar is present in
// platform_bootclasspath's classpaths.proto config, if the apex does not generate its own config
// by setting generate_classpaths_proto property to false.
func TestPlatformBootclasspath_IncludesRemainingApexJars(t *testing.T) {
	result := android.GroupFixturePreparers(
		prepareForTestWithPlatformBootclasspath,
		prepareForTestWithMyapex,
		java.FixtureConfigureUpdatableBootJars("myapex:foo"),
		android.FixtureWithRootAndroidBp(`
			platform_bootclasspath {
				name: "platform-bootclasspath",
				fragments: [
					{
						apex: "myapex",
						module:"foo-fragment",
					},
				],
			}

			apex {
				name: "myapex",
				key: "myapex.key",
				bootclasspath_fragments: ["foo-fragment"],
				updatable: false,
			}

			apex_key {
				name: "myapex.key",
				public_key: "testkey.avbpubkey",
				private_key: "testkey.pem",
			}

			bootclasspath_fragment {
				name: "foo-fragment",
				generate_classpaths_proto: false,
				contents: ["foo"],
				apex_available: ["myapex"],
			}

			java_library {
				name: "foo",
				srcs: ["a.java"],
				system_modules: "none",
				sdk_version: "none",
				compile_dex: true,
				apex_available: ["myapex"],
				permitted_packages: ["foo"],
			}
		`),
	).RunTest(t)

	java.CheckClasspathFragmentProtoContentInfoProvider(t, result,
		true,         // proto should be generated
		"myapex:foo", // apex doesn't generate its own config, so must be in platform_bootclasspath
		"bootclasspath.pb",
		"out/soong/target/product/test_device/system/etc/classpaths",
	)
}
+4 −3
Original line number Diff line number Diff line
@@ -496,13 +496,14 @@ func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleC
// generateClasspathProtoBuildActions generates all required build actions for classpath.proto config
func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
	var classpathJars []classpathJar
	configuredJars := b.configuredJars(ctx)
	if "art" == proptools.String(b.properties.Image_name) {
		// ART and platform boot jars must have a corresponding entry in DEX2OATBOOTCLASSPATH
		classpathJars = configuredJarListToClasspathJars(ctx, b.configuredJars(ctx), BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
		classpathJars = configuredJarListToClasspathJars(ctx, configuredJars, BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
	} else {
		classpathJars = configuredJarListToClasspathJars(ctx, b.configuredJars(ctx), b.classpathType)
		classpathJars = configuredJarListToClasspathJars(ctx, configuredJars, b.classpathType)
	}
	b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars)
	b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
}

func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
+5 −1
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ func configuredJarListToClasspathJars(ctx android.ModuleContext, configuredJars
	return jars
}

func (c *ClasspathFragmentBase) generateClasspathProtoBuildActions(ctx android.ModuleContext, jars []classpathJar) {
func (c *ClasspathFragmentBase) generateClasspathProtoBuildActions(ctx android.ModuleContext, configuredJars android.ConfiguredJarList, jars []classpathJar) {
	generateProto := proptools.BoolDefault(c.properties.Generate_classpaths_proto, true)
	if generateProto {
		outputFilename := strings.ToLower(c.classpathType.String()) + ".pb"
@@ -129,6 +129,7 @@ func (c *ClasspathFragmentBase) generateClasspathProtoBuildActions(ctx android.M

	classpathProtoInfo := ClasspathFragmentProtoContentInfo{
		ClasspathFragmentProtoGenerated:  generateProto,
		ClasspathFragmentProtoContents:   configuredJars,
		ClasspathFragmentProtoInstallDir: c.installDirPath,
		ClasspathFragmentProtoOutput:     c.outputFilepath,
	}
@@ -177,6 +178,9 @@ type ClasspathFragmentProtoContentInfo struct {
	// Whether the classpaths.proto config is generated for the fragment.
	ClasspathFragmentProtoGenerated bool

	// ClasspathFragmentProtoContents contains a list of jars that are part of this classpath fragment.
	ClasspathFragmentProtoContents android.ConfiguredJarList

	// ClasspathFragmentProtoOutput is an output path for the generated classpaths.proto config of this module.
	//
	// The file should be copied to a relevant place on device, see ClasspathFragmentProtoInstallDir
+19 −3
Original line number Diff line number Diff line
@@ -198,13 +198,29 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo

// Generate classpaths.proto config
func (b *platformBootclasspathModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
	configuredJars := b.configuredJars(ctx)
	// ART and platform boot jars must have a corresponding entry in DEX2OATBOOTCLASSPATH
	classpathJars := configuredJarListToClasspathJars(ctx, b.configuredJars(ctx), BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
	b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars)
	classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
	b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
}

func (b *platformBootclasspathModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
	return b.getImageConfig(ctx).modules
	// Include all non APEX jars
	jars := b.getImageConfig(ctx).modules

	// Include jars from APEXes that don't populate their classpath proto config.
	remainingJars := dexpreopt.GetGlobalConfig(ctx).UpdatableBootJars
	for _, fragment := range b.fragments {
		info := ctx.OtherModuleProvider(fragment, ClasspathFragmentProtoContentInfoProvider).(ClasspathFragmentProtoContentInfo)
		if info.ClasspathFragmentProtoGenerated {
			remainingJars = remainingJars.RemoveList(info.ClasspathFragmentProtoContents)
		}
	}
	for i := 0; i < remainingJars.Len(); i++ {
		jars = jars.Append(remainingJars.Apex(i), remainingJars.Jar(i))
	}

	return jars
}

// checkNonUpdatableModules ensures that the non-updatable modules supplied are not part of an
+8 −6
Original line number Diff line number Diff line
@@ -48,13 +48,14 @@ func (p *platformSystemServerClasspathModule) AndroidMkEntries() (entries []andr
}

func (p *platformSystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	classpathJars := configuredJarListToClasspathJars(ctx, p.configuredJars(ctx), p.classpathType)
	p.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars)
	configuredJars := p.configuredJars(ctx)
	classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, p.classpathType)
	p.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
}

func (p *platformSystemServerClasspathModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
	global := dexpreopt.GetGlobalConfig(ctx)
	return global.SystemServerJars
	// TODO(satayev): include any apex jars that don't populate their classpath proto config.
	return dexpreopt.GetGlobalConfig(ctx).SystemServerJars
}

type SystemServerClasspathModule struct {
@@ -94,8 +95,9 @@ func (s *SystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.Mo
		ctx.PropertyErrorf("contents", "empty contents are not allowed")
	}

	classpathJars := configuredJarListToClasspathJars(ctx, s.configuredJars(ctx), s.classpathType)
	s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars)
	configuredJars := s.configuredJars(ctx)
	classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, s.classpathType)
	s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)

	// Collect the module directory for IDE info in java/jdeps.go.
	s.modulePaths = append(s.modulePaths, ctx.ModuleDir())
Loading