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

Commit 4bb01067 authored by Nicolas Geoffray's avatar Nicolas Geoffray
Browse files

Never strip and store dex files uncompressed when they are preopted on system.

In order for the runtime module to always be able to compile apps,
make sure we keep a copy of the dex files optimally.

Gated by a product flag if a product doesn't include the module yet.

Test: build
Change-Id: I4bfe00184fcfdf44b8d1866c5c550838b869c60a
parent eebdf433
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ type GlobalConfig struct {
	SystemServerCompilerFilter string // default compiler filter to pass to dex2oat for system server jars

	GenerateDMFiles     bool // generate Dex Metadata files
	NeverAllowStripping bool // whether stripping should not be done - used as build time check to make sure dex files are always available

	NoDebugInfo                 bool // don't generate debug info by default
	AlwaysSystemServerDebugInfo bool // always generate mini debug info for system server modules (overrides NoDebugInfo=true)
+10 −3
Original line number Diff line number Diff line
@@ -68,6 +68,9 @@ func GenerateStripRule(global GlobalConfig, module ModuleConfig) (rule *android.
	strip := shouldStripDex(module, global)

	if strip {
		if global.NeverAllowStripping {
			panic(fmt.Errorf("Stripping requested on %q, though the product does not allow it", module.DexLocation))
		}
		// Only strips if the dex files are not already uncompressed
		rule.Command().
			Textf(`if (zipinfo %s '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, module.StripInputPath).
@@ -499,7 +502,7 @@ func shouldGenerateDM(module ModuleConfig, global GlobalConfig) bool {
		contains(module.PreoptFlags, "--compiler-filter=verify")
}

func odexOnSystemOther(module ModuleConfig, global GlobalConfig) bool {
func OdexOnSystemOtherByName(name string, dexLocation string, global GlobalConfig) bool {
	if !global.HasSystemOther {
		return false
	}
@@ -508,12 +511,12 @@ func odexOnSystemOther(module ModuleConfig, global GlobalConfig) bool {
		return false
	}

	if contains(global.SpeedApps, module.Name) || contains(global.SystemServerApps, module.Name) {
	if contains(global.SpeedApps, name) || contains(global.SystemServerApps, name) {
		return false
	}

	for _, f := range global.PatternsOnSystemOther {
		if makefileMatch(filepath.Join(SystemPartition, f), module.DexLocation) {
		if makefileMatch(filepath.Join(SystemPartition, f), dexLocation) {
			return true
		}
	}
@@ -521,6 +524,10 @@ func odexOnSystemOther(module ModuleConfig, global GlobalConfig) bool {
	return false
}

func odexOnSystemOther(module ModuleConfig, global GlobalConfig) bool {
	return OdexOnSystemOtherByName(module.Name, module.DexLocation, global)
}

func pathForLibrary(module ModuleConfig, lib string) string {
	path := module.LibraryPaths[lib]
	if path == "" {
+18 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ var testGlobalConfig = GlobalConfig{
	DefaultCompilerFilter:              "",
	SystemServerCompilerFilter:         "",
	GenerateDMFiles:                    false,
	NeverAllowStripping:                false,
	NoDebugInfo:                        false,
	AlwaysSystemServerDebugInfo:        false,
	NeverSystemServerDebugInfo:         false,
@@ -110,6 +111,23 @@ func TestDexPreopt(t *testing.T) {
	}
}

func TestDexPreoptStrip(t *testing.T) {
	// Test that we panic if we strip in a configuration where stripping is not allowed.
	global, module := testGlobalConfig, testModuleConfig

	global.NeverAllowStripping = true
	module.NoStripping = false
	module.Name = "test"
	module.DexLocation = "/system/app/test/test.apk"
	module.BuildPath = "out/test/test.apk"
	module.Archs = []string{"arm"}

	_, err := GenerateStripRule(global, module)
	if err == nil {
		t.Errorf("Expected an error when calling GenerateStripRule on a stripped module")
	}
}

func TestDexPreoptSystemOther(t *testing.T) {
	global, module := testGlobalConfig, testModuleConfig

+14 −3
Original line number Diff line number Diff line
@@ -162,9 +162,18 @@ func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
	}

	// Uncompress dex in APKs of privileged apps, and modules used by privileged apps.
	return ctx.Config().UncompressPrivAppDex() &&
	if ctx.Config().UncompressPrivAppDex() &&
		(Bool(a.appProperties.Privileged) ||
			inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()))
			inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules())) {
		return true
	}

	// Uncompress if the dex files is preopted on /system.
	if !a.dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, a.dexpreopter.installPath)) {
		return true
	}

	return false
}

func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
@@ -223,7 +232,6 @@ func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
}

func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
	a.deviceProperties.UncompressDex = a.shouldUncompressDex(ctx)

	var installDir string
	if ctx.ModuleName() == "framework-res" {
@@ -235,6 +243,9 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
		installDir = filepath.Join("app", a.installApkName)
	}
	a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
	a.dexpreopter.isInstallable = Bool(a.properties.Installable)
	a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
	a.deviceProperties.UncompressDex = a.dexpreopter.uncompressedDex

	if ctx.ModuleName() != "framework-res" {
		a.Module.compile(ctx, a.aaptSrcJar)
+14 −5
Original line number Diff line number Diff line
@@ -83,11 +83,7 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool {

var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")

func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.ModuleOutPath) android.ModuleOutPath {
	if d.dexpreoptDisabled(ctx) {
		return dexJarFile
	}

func getGlobalConfig(ctx android.ModuleContext) dexpreopt.GlobalConfig {
	globalConfig := ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
		if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
			ctx.AddNinjaFileDeps(f)
@@ -99,6 +95,19 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
		}
		return dexpreopt.GlobalConfig{}
	}).(dexpreopt.GlobalConfig)
	return globalConfig
}

func odexOnSystemOther(ctx android.ModuleContext, installPath android.OutputPath) bool {
	return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), getGlobalConfig(ctx))
}

func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.ModuleOutPath) android.ModuleOutPath {
	if d.dexpreoptDisabled(ctx) {
		return dexJarFile
	}

	globalConfig := getGlobalConfig(ctx)

	var archs []string
	for _, a := range ctx.MultiTargets() {
Loading