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

Commit 950deca3 authored by Spandan Das's avatar Spandan Das
Browse files

Install dexpreopt artifacts of apex system server jars in same partition

e.g. If a system server jar providing apex is installed in /system_ext,
the dexpreopt files of that jar will also be installed in /system_ext.
Currently, all of these artifacts are installed in /system

This behavior will be flag guarded by
RELEASE_INSTALL_APEX_SYSTEMSERVER_DEXPREOPT_SAME_PARTITION. This is
necessary because the ART runtime needs to be updated to look in the new
/system_ext location. Since some release configs build with ART
prebuilts, the runtime in those prebuilt apexes will not have the
additional search path introduced in https://r.android.com/3287191

Test: Verified that "Could not check odex file" does not appear for
service-compos (a system_ext apex systemserver jar)

Bug: 369678122
Change-Id: I752bdc7f5f69226b503800ce25726a211302cb07
parent 32325372
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -2105,3 +2105,10 @@ func (c *config) BoardAvbEnable() bool {
func (c *config) BoardAvbSystemAddHashtreeFooterArgs() []string {
	return c.productVariables.BoardAvbSystemAddHashtreeFooterArgs
}

// Returns true if RELEASE_INSTALL_APEX_SYSTEMSERVER_DEXPREOPT_SAME_PARTITION is set to true.
// If true, dexpreopt files of apex system server jars will be installed in the same partition as the parent apex.
// If false, all these files will be installed in /system partition.
func (c Config) InstallApexSystemServerDexpreoptSamePartition() bool {
	return c.config.productVariables.GetBuildFlagBool("RELEASE_INSTALL_APEX_SYSTEMSERVER_DEXPREOPT_SAME_PARTITION")
}
+5 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ type Module interface {
	InstallInOdm() bool
	InstallInProduct() bool
	InstallInVendor() bool
	InstallInSystemExt() bool
	InstallForceOS() (*OsType, *ArchType)
	PartitionTag(DeviceConfig) string
	HideFromMake()
@@ -1514,6 +1515,10 @@ func (m *ModuleBase) InstallInVendor() bool {
	return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary)
}

func (m *ModuleBase) InstallInSystemExt() bool {
	return Bool(m.commonProperties.System_ext_specific)
}

func (m *ModuleBase) InstallInRoot() bool {
	return false
}
+4 −0
Original line number Diff line number Diff line
@@ -191,6 +191,10 @@ type ModuleConfig struct {
	ForceCreateAppImage bool

	PresignedPrebuilt bool

	// ApexPartition is the partition in which the dexpreopt files of apex system server jars (if any) are installed.
	// This is a noop unless the module is apex system server jar.
	ApexPartition string
}

type globalSoongConfigSingleton struct{}
+3 −3
Original line number Diff line number Diff line
@@ -219,9 +219,9 @@ func GetSystemServerDexLocation(ctx android.PathContext, global *GlobalConfig, l
}

// Returns the location to the odex file for the dex file at `path`.
func ToOdexPath(path string, arch android.ArchType) string {
func ToOdexPath(path string, arch android.ArchType, partition string) string {
	if strings.HasPrefix(path, "/apex/") {
		return filepath.Join("/system/framework/oat", arch.String(),
		return filepath.Join(partition, "framework/oat", arch.String(),
			strings.ReplaceAll(path[1:], "/", "@")+"@classes.odex")
	}

@@ -245,7 +245,7 @@ func dexpreoptCommand(ctx android.BuilderContext, globalSoong *GlobalSoongConfig

	odexPath := module.BuildPath.InSameDir(ctx, "oat", arch.String(), pathtools.ReplaceExtension(base, "odex"))
	odexSymbolsPath := odexPath.ReplaceExtension(ctx, "symbols.odex")
	odexInstallPath := ToOdexPath(module.DexLocation, arch)
	odexInstallPath := ToOdexPath(module.DexLocation, arch, module.ApexPartition)
	if odexOnSystemOther(module, global) {
		odexInstallPath = filepath.Join(SystemOtherPartition, odexInstallPath)
	}
+46 −1
Original line number Diff line number Diff line
@@ -42,12 +42,14 @@ func testModuleConfig(ctx android.PathContext, name, partition string) *ModuleCo
}

func testApexModuleConfig(ctx android.PathContext, name, apexName string) *ModuleConfig {
	return createTestModuleConfig(
	ret := createTestModuleConfig(
		name,
		fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, name),
		android.PathForOutput(ctx, fmt.Sprintf("%s/dexpreopt/%s.jar", name, name)),
		android.PathForOutput(ctx, fmt.Sprintf("%s/aligned/%s.jar", name, name)),
		android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
	ret.ApexPartition = "/system"
	return ret
}

func testPlatformSystemServerModuleConfig(ctx android.PathContext, name string) *ModuleConfig {
@@ -221,6 +223,49 @@ func TestDexPreoptApexSystemServerJars(t *testing.T) {
	DexpreoptRunningInSoong = oldDexpreoptRunningInSoong
}

// Same as `TestDexPreoptApexSystemServerJars`, but the apex jar is in /system_ext
func TestDexPreoptApexSystemServerJarsSystemExt(t *testing.T) {
	// modify the global variable for test
	var oldDexpreoptRunningInSoong = DexpreoptRunningInSoong
	DexpreoptRunningInSoong = true

	// test begin
	config := android.TestConfig("out", nil, "", nil)
	ctx := android.BuilderContextForTesting(config)
	globalSoong := globalSoongConfigForTests(ctx)
	global := GlobalConfigForTests(ctx)
	module := testApexModuleConfig(ctx, "service-A", "com.android.apex1")
	module.ApexPartition = "/system_ext"
	productPackages := android.PathForTesting("product_packages.txt")

	global.ApexSystemServerJars = android.CreateTestConfiguredJarList(
		[]string{"com.android.apex1:service-A"})

	rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
	if err != nil {
		t.Fatal(err)
	}

	wantInstalls := android.RuleBuilderInstalls{
		{android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system_ext/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.odex"},
		{android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system_ext/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.vdex"},
	}

	android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())

	android.AssertStringListContains(t, "apex sscp jar copy", rule.Outputs().Strings(), "out/soong/system_server_dexjars/service-A.jar")

	// rule with apex sscp cp as false
	rule, err = GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, false)
	if err != nil {
		t.Fatal(err)
	}
	android.AssertStringListDoesNotContain(t, "apex sscp jar copy", rule.Outputs().Strings(), "out/soong/system_server_dexjars/service-A.jar")

	// cleanup the global variable for test
	DexpreoptRunningInSoong = oldDexpreoptRunningInSoong
}

func TestDexPreoptStandaloneSystemServerJars(t *testing.T) {
	config := android.TestConfig("out", nil, "", nil)
	ctx := android.BuilderContextForTesting(config)
Loading