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

Commit 7dbc5786 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Fix library order in class loader context to agree with PackageManager."

parents 74c8436c c9f2b949
Loading
Loading
Loading
Loading
+22 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ package dexpreopt

import (
	"fmt"
	"sort"
	"strconv"
	"strings"

@@ -238,8 +239,8 @@ var OptionalCompatUsesLibs30 = []string{
	AndroidTestMock,
}
var CompatUsesLibs29 = []string{
	AndroidHidlBase,
	AndroidHidlManager,
	AndroidHidlBase,
}
var OptionalCompatUsesLibs = append(android.CopyOf(OptionalCompatUsesLibs28), OptionalCompatUsesLibs30...)
var CompatUsesLibs = android.CopyOf(CompatUsesLibs29)
@@ -462,7 +463,26 @@ func validateClassLoaderContextRec(sdkVer int, clcs []*ClassLoaderContext) (bool
// Perform a depth-first preorder traversal of the class loader context tree for each SDK version.
// Return the resulting string and a slice of on-host build paths to all library dependencies.
func ComputeClassLoaderContext(clcMap ClassLoaderContextMap) (clcStr string, paths android.Paths) {
	for _, sdkVer := range android.SortedIntKeys(clcMap) { // determinisitc traversal order
	// CLC for different SDK versions should come in specific order that agrees with PackageManager.
	// Since PackageManager processes SDK versions in ascending order and prepends compatibility
	// libraries at the front, the required order is descending, except for AnySdkVersion that has
	// numerically the largest order, but must be the last one. Example of correct order: [30, 29,
	// 28, AnySdkVersion]. There are Soong tests to ensure that someone doesn't change this by
	// accident, but there is no way to guard against changes in the PackageManager, except for
	// grepping logcat on the first boot for absence of the following messages:
	//
	//   `logcat | grep -E 'ClassLoaderContext [a-z ]+ mismatch`
	//
	versions := make([]int, 0, len(clcMap))
	for ver, _ := range clcMap {
		if ver != AnySdkVersion {
			versions = append(versions, ver)
		}
	}
	sort.Sort(sort.Reverse(sort.IntSlice(versions))) // descending order
	versions = append(versions, AnySdkVersion)

	for _, sdkVer := range versions {
		sdkVerStr := fmt.Sprintf("%d", sdkVer)
		if sdkVer == AnySdkVersion {
			sdkVerStr = "any" // a special keyword that means any SDK version
+42 −0
Original line number Diff line number Diff line
@@ -209,6 +209,48 @@ func TestCLCNestedConditional(t *testing.T) {
	checkError(t, err, "nested class loader context shouldn't have conditional part")
}

// Test for SDK version order in conditional CLC: no matter in what order the libraries are added,
// they end up in the order that agrees with PackageManager.
func TestCLCSdkVersionOrder(t *testing.T) {
	ctx := testContext()
	m := make(ClassLoaderContextMap)
	m.AddContextForSdk(ctx, 28, "a", buildPath(ctx, "a"), installPath(ctx, "a"), nil)
	m.AddContextForSdk(ctx, 29, "b", buildPath(ctx, "b"), installPath(ctx, "b"), nil)
	m.AddContextForSdk(ctx, 30, "c", buildPath(ctx, "c"), installPath(ctx, "c"), nil)
	m.AddContextForSdk(ctx, AnySdkVersion, "d", buildPath(ctx, "d"), installPath(ctx, "d"), nil)

	valid, validationError := validateClassLoaderContext(m)

	fixClassLoaderContext(m)

	var haveStr string
	if valid && validationError == nil {
		haveStr, _ = ComputeClassLoaderContext(m)
	}

	// Test that validation is successful (all paths are known).
	t.Run("validate", func(t *testing.T) {
		if !(valid && validationError == nil) {
			t.Errorf("invalid class loader context")
		}
	})

	// Test that class loader context structure is correct.
	t.Run("string", func(t *testing.T) {
		wantStr := " --host-context-for-sdk 30 PCL[out/c.jar]" +
			" --target-context-for-sdk 30 PCL[/system/c.jar]" +
			" --host-context-for-sdk 29 PCL[out/b.jar]" +
			" --target-context-for-sdk 29 PCL[/system/b.jar]" +
			" --host-context-for-sdk 28 PCL[out/a.jar]" +
			" --target-context-for-sdk 28 PCL[/system/a.jar]" +
			" --host-context-for-sdk any PCL[out/d.jar]" +
			" --target-context-for-sdk any PCL[/system/d.jar]"
		if wantStr != haveStr {
			t.Errorf("\nwant class loader context: %s\nhave class loader context: %s", wantStr, haveStr)
		}
	})
}

func checkError(t *testing.T, have error, want string) {
	if have == nil {
		t.Errorf("\nwant error: '%s'\nhave: none", want)
+2 −2
Original line number Diff line number Diff line
@@ -2896,8 +2896,8 @@ func TestUsesLibraries(t *testing.T) {

	// Test conditional context for target SDK version 29.
	if w := `--target-context-for-sdk 29` +
		` PCL[/system/framework/android.hidl.base-V1.0-java.jar]` +
		`#PCL[/system/framework/android.hidl.manager-V1.0-java.jar] `; !strings.Contains(cmd, w) {
		` PCL[/system/framework/android.hidl.manager-V1.0-java.jar]` +
		`#PCL[/system/framework/android.hidl.base-V1.0-java.jar] `; !strings.Contains(cmd, w) {
		t.Errorf("wanted %q in %q", w, cmd)
	}