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

Commit d8d8e726 authored by Ulyana Trafimovich's avatar Ulyana Trafimovich Committed by Gerrit Code Review
Browse files

Merge changes Iebfbf2ff,Ibd974268

* changes:
  Rename fields and methods to reflect class loader context changes.
  Do not add dependencies of shared SDK libraries to manifest_fixer.
parents e3d308b5 b23d28c6
Loading
Loading
Loading
Loading
+27 −16
Original line number Diff line number Diff line
@@ -71,6 +71,10 @@ type ClassLoaderContext struct {

	// Nested class loader subcontexts for dependencies.
	Subcontexts []*ClassLoaderContext

	// If the library is a shared library. This affects which elements of class loader context are
	// added as <uses-library> tags by the manifest_fixer (dependencies of shared libraries aren't).
	IsSharedLibrary bool
}

// ClassLoaderContextMap is a map from SDK version to a class loader context.
@@ -81,7 +85,7 @@ type ClassLoaderContextMap map[int][]*ClassLoaderContext

// Add class loader context for the given library to the map entry for the given SDK version.
func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathContext, sdkVer int, lib string,
	hostPath, installPath android.Path, strict bool, nestedClcMap ClassLoaderContextMap) error {
	shared bool, hostPath, installPath android.Path, strict bool, nestedClcMap ClassLoaderContextMap) error {

	// If missing dependencies are allowed, the build shouldn't fail when a <uses-library> is
	// not found. However, this is likely to result is disabling dexpreopt, as it won't be
@@ -132,42 +136,42 @@ func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathCont
		Host:            hostPath,
		Device:          devicePath,
		Subcontexts:     subcontexts,
		IsSharedLibrary: shared,
	})
	return nil
}

// Wrapper around addContext that reports errors.
func (clcMap ClassLoaderContextMap) addContextOrReportError(ctx android.ModuleInstallPathContext, sdkVer int, lib string,
	hostPath, installPath android.Path, strict bool, nestedClcMap ClassLoaderContextMap) {
	shared bool, hostPath, installPath android.Path, strict bool, nestedClcMap ClassLoaderContextMap) {

	err := clcMap.addContext(ctx, sdkVer, lib, hostPath, installPath, strict, nestedClcMap)
	err := clcMap.addContext(ctx, sdkVer, lib, shared, hostPath, installPath, strict, nestedClcMap)
	if err != nil {
		ctx.ModuleErrorf(err.Error())
		android.ReportPathErrorf(ctx, err.Error())
	}
}

// Add class loader context. Fail on unknown build/install paths.
func (clcMap ClassLoaderContextMap) AddContext(ctx android.ModuleInstallPathContext, lib string,
	hostPath, installPath android.Path) {
	shared bool, hostPath, installPath android.Path) {

	clcMap.addContextOrReportError(ctx, AnySdkVersion, lib, hostPath, installPath, true, nil)
	clcMap.addContextOrReportError(ctx, AnySdkVersion, lib, shared, hostPath, installPath, true, nil)
}

// Add class loader context if the library exists. Don't fail on unknown build/install paths.
func (clcMap ClassLoaderContextMap) MaybeAddContext(ctx android.ModuleInstallPathContext, lib *string,
	hostPath, installPath android.Path) {
	shared bool, hostPath, installPath android.Path) {

	if lib != nil {
		clcMap.addContextOrReportError(ctx, AnySdkVersion, *lib, hostPath, installPath, false, nil)
		clcMap.addContextOrReportError(ctx, AnySdkVersion, *lib, shared, hostPath, installPath, false, nil)
	}
}

// Add class loader context for the given SDK version. Fail on unknown build/install paths.
func (clcMap ClassLoaderContextMap) AddContextForSdk(ctx android.ModuleInstallPathContext, sdkVer int,
	lib string, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) {
	lib string, shared bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) {

	clcMap.addContextOrReportError(ctx, sdkVer, lib, hostPath, installPath, true, nestedClcMap)
	clcMap.addContextOrReportError(ctx, sdkVer, lib, shared, hostPath, installPath, true, nestedClcMap)
}

// Merge the other class loader context map into this one, do not override existing entries.
@@ -204,7 +208,9 @@ func (clcMap ClassLoaderContextMap) AddContextMap(otherClcMap ClassLoaderContext
	}
}

// List of libraries in the unconditional class loader context, excluding dependencies of shared libraries.
// List of libraries in the unconditional class loader context, excluding dependencies of shared
// libraries. These libraries should be in the <uses-library> tags in the manifest. Some of them may
// be present in the original manifest, others are added by the manifest_fixer.
func (clcMap ClassLoaderContextMap) UsesLibs() (ulibs []string) {
	if clcMap != nil {
		// compatibility libraries (those in conditional context) are not added to <uses-library> tags
@@ -217,8 +223,13 @@ func (clcMap ClassLoaderContextMap) UsesLibs() (ulibs []string) {
func usesLibsRec(clcs []*ClassLoaderContext) (ulibs []string) {
	for _, clc := range clcs {
		ulibs = append(ulibs, clc.Name)
		// <uses-library> tags in the manifest should not include dependencies of shared libraries,
		// because PackageManager already tracks all such dependencies and automatically adds their
		// class loader contexts as subcontext of the shared library.
		if !clc.IsSharedLibrary {
			ulibs = append(ulibs, usesLibsRec(clc.Subcontexts)...)
		}
	}
	return ulibs
}

+28 −23
Original line number Diff line number Diff line
@@ -25,6 +25,11 @@ import (
	"android/soong/android"
)

const (
	shared    = true  // dependencies are not added to uses libs
	nonshared = false // dependencies are added to uses libs
)

func TestCLC(t *testing.T) {
	// Construct class loader context with the following structure:
	// .
@@ -50,36 +55,36 @@ func TestCLC(t *testing.T) {

	m := make(ClassLoaderContextMap)

	m.AddContext(ctx, "a", buildPath(ctx, "a"), installPath(ctx, "a"))
	m.AddContext(ctx, "b", buildPath(ctx, "b"), installPath(ctx, "b"))
	m.AddContext(ctx, "a", nonshared, buildPath(ctx, "a"), installPath(ctx, "a"))
	m.AddContext(ctx, "b", shared, buildPath(ctx, "b"), installPath(ctx, "b"))

	// "Maybe" variant in the good case: add as usual.
	c := "c"
	m.MaybeAddContext(ctx, &c, buildPath(ctx, "c"), installPath(ctx, "c"))
	m.MaybeAddContext(ctx, &c, nonshared, buildPath(ctx, "c"), installPath(ctx, "c"))

	// "Maybe" variant in the bad case: don't add library with unknown name, keep going.
	m.MaybeAddContext(ctx, nil, nil, nil)
	m.MaybeAddContext(ctx, nil, nonshared, nil, nil)

	// Add some libraries with nested subcontexts.

	m1 := make(ClassLoaderContextMap)
	m1.AddContext(ctx, "a1", buildPath(ctx, "a1"), installPath(ctx, "a1"))
	m1.AddContext(ctx, "b1", buildPath(ctx, "b1"), installPath(ctx, "b1"))
	m1.AddContext(ctx, "a1", nonshared, buildPath(ctx, "a1"), installPath(ctx, "a1"))
	m1.AddContext(ctx, "b1", shared, buildPath(ctx, "b1"), installPath(ctx, "b1"))

	m2 := make(ClassLoaderContextMap)
	m2.AddContext(ctx, "a2", buildPath(ctx, "a2"), installPath(ctx, "a2"))
	m2.AddContext(ctx, "b2", buildPath(ctx, "b2"), installPath(ctx, "b2"))
	m2.AddContextForSdk(ctx, AnySdkVersion, "c2", buildPath(ctx, "c2"), installPath(ctx, "c2"), m1)
	m2.AddContext(ctx, "a2", nonshared, buildPath(ctx, "a2"), installPath(ctx, "a2"))
	m2.AddContext(ctx, "b2", shared, buildPath(ctx, "b2"), installPath(ctx, "b2"))
	m2.AddContextForSdk(ctx, AnySdkVersion, "c2", shared, buildPath(ctx, "c2"), installPath(ctx, "c2"), m1)

	m3 := make(ClassLoaderContextMap)
	m3.AddContext(ctx, "a3", buildPath(ctx, "a3"), installPath(ctx, "a3"))
	m3.AddContext(ctx, "b3", buildPath(ctx, "b3"), installPath(ctx, "b3"))
	m3.AddContext(ctx, "a3", nonshared, buildPath(ctx, "a3"), installPath(ctx, "a3"))
	m3.AddContext(ctx, "b3", shared, buildPath(ctx, "b3"), installPath(ctx, "b3"))

	m.AddContextForSdk(ctx, AnySdkVersion, "d", buildPath(ctx, "d"), installPath(ctx, "d"), m2)
	m.AddContextForSdk(ctx, AnySdkVersion, "d", nonshared, buildPath(ctx, "d"), installPath(ctx, "d"), m2)
	// When the same library is both in conditional and unconditional context, it should be removed
	// from conditional context.
	m.AddContextForSdk(ctx, 42, "f", buildPath(ctx, "f"), installPath(ctx, "f"), nil)
	m.AddContextForSdk(ctx, AnySdkVersion, "f", buildPath(ctx, "f"), installPath(ctx, "f"), nil)
	m.AddContextForSdk(ctx, 42, "f", nonshared, buildPath(ctx, "f"), installPath(ctx, "f"), nil)
	m.AddContextForSdk(ctx, AnySdkVersion, "f", nonshared, buildPath(ctx, "f"), installPath(ctx, "f"), nil)

	// Merge map with implicit root library that is among toplevel contexts => does nothing.
	m.AddContextMap(m1, "c")
@@ -88,12 +93,12 @@ func TestCLC(t *testing.T) {
	m.AddContextMap(m3, "m_g")

	// Compatibility libraries with unknown install paths get default paths.
	m.AddContextForSdk(ctx, 29, AndroidHidlManager, buildPath(ctx, AndroidHidlManager), nil, nil)
	m.AddContextForSdk(ctx, 29, AndroidHidlBase, buildPath(ctx, AndroidHidlBase), nil, nil)
	m.AddContextForSdk(ctx, 29, AndroidHidlManager, nonshared, buildPath(ctx, AndroidHidlManager), nil, nil)
	m.AddContextForSdk(ctx, 29, AndroidHidlBase, nonshared, buildPath(ctx, AndroidHidlBase), nil, nil)

	// Add "android.test.mock" to conditional CLC, observe that is gets removed because it is only
	// needed as a compatibility library if "android.test.runner" is in CLC as well.
	m.AddContextForSdk(ctx, 30, AndroidTestMock, buildPath(ctx, AndroidTestMock), nil, nil)
	m.AddContextForSdk(ctx, 30, AndroidTestMock, nonshared, buildPath(ctx, AndroidTestMock), nil, nil)

	valid, validationError := validateClassLoaderContext(m)

@@ -153,7 +158,7 @@ func TestCLC(t *testing.T) {

	// Test for libraries that are added by the manifest_fixer.
	t.Run("uses libs", func(t *testing.T) {
		wantUsesLibs := []string{"a", "b", "c", "d", "a2", "b2", "c2", "a1", "b1", "f", "a3", "b3"}
		wantUsesLibs := []string{"a", "b", "c", "d", "a2", "b2", "c2", "f", "a3", "b3"}
		if !reflect.DeepEqual(wantUsesLibs, haveUsesLibs) {
			t.Errorf("\nwant uses libs: %s\nhave uses libs: %s", wantUsesLibs, haveUsesLibs)
		}
@@ -164,7 +169,7 @@ func TestCLC(t *testing.T) {
func TestCLCUnknownBuildPath(t *testing.T) {
	ctx := testContext()
	m := make(ClassLoaderContextMap)
	err := m.addContext(ctx, AnySdkVersion, "a", nil, nil, true, nil)
	err := m.addContext(ctx, AnySdkVersion, "a", nonshared, nil, nil, true, nil)
	checkError(t, err, "unknown build path to <uses-library> \"a\"")
}

@@ -172,7 +177,7 @@ func TestCLCUnknownBuildPath(t *testing.T) {
func TestCLCUnknownInstallPath(t *testing.T) {
	ctx := testContext()
	m := make(ClassLoaderContextMap)
	err := m.addContext(ctx, AnySdkVersion, "a", buildPath(ctx, "a"), nil, true, nil)
	err := m.addContext(ctx, AnySdkVersion, "a", nonshared, buildPath(ctx, "a"), nil, true, nil)
	checkError(t, err, "unknown install path to <uses-library> \"a\"")
}

@@ -181,7 +186,7 @@ func TestCLCMaybeAdd(t *testing.T) {

	m := make(ClassLoaderContextMap)
	a := "a"
	m.MaybeAddContext(ctx, &a, nil, nil)
	m.MaybeAddContext(ctx, &a, nonshared, nil, nil)

	// The library should be added to <uses-library> tags by the manifest_fixer.
	t.Run("maybe add", func(t *testing.T) {
@@ -203,9 +208,9 @@ func TestCLCMaybeAdd(t *testing.T) {
func TestCLCNestedConditional(t *testing.T) {
	ctx := testContext()
	m1 := make(ClassLoaderContextMap)
	m1.AddContextForSdk(ctx, 42, "a", buildPath(ctx, "a"), installPath(ctx, "a"), nil)
	m1.AddContextForSdk(ctx, 42, "a", nonshared, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
	m := make(ClassLoaderContextMap)
	err := m.addContext(ctx, AnySdkVersion, "b", buildPath(ctx, "b"), installPath(ctx, "b"), true, m1)
	err := m.addContext(ctx, AnySdkVersion, "b", nonshared, buildPath(ctx, "b"), installPath(ctx, "b"), true, m1)
	checkError(t, err, "nested class loader context shouldn't have conditional part")
}

+12 −12
Original line number Diff line number Diff line
@@ -259,16 +259,16 @@ var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
	})

func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext,
	sdkLibraries dexpreopt.ClassLoaderContextMap, extraLinkFlags ...string) {
	classLoaderContexts dexpreopt.ClassLoaderContextMap, extraLinkFlags ...string) {

	transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags :=
		aaptLibs(ctx, sdkContext, sdkLibraries)
		aaptLibs(ctx, sdkContext, classLoaderContexts)

	// App manifest file
	manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
	manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)

	manifestPath := manifestFixer(ctx, manifestSrcPath, sdkContext, sdkLibraries,
	manifestPath := manifestFixer(ctx, manifestSrcPath, sdkContext, classLoaderContexts,
		a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex, a.hasNoCode,
		a.LoggingParent)

@@ -389,15 +389,15 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext,
}

// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, sdkLibraries dexpreopt.ClassLoaderContextMap) (
func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderContexts dexpreopt.ClassLoaderContextMap) (
	transitiveStaticLibs, transitiveStaticLibManifests android.Paths, staticRRODirs []rroDir, assets, deps android.Paths, flags []string) {

	var sharedLibs android.Paths

	if sdkLibraries == nil {
	if classLoaderContexts == nil {
		// Not all callers need to compute class loader context, those who don't just pass nil.
		// Create a temporary class loader context here (it will be computed, but not used).
		sdkLibraries = make(dexpreopt.ClassLoaderContextMap)
		classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
	}

	sdkDep := decodeSdkDep(ctx, sdkContext)
@@ -426,7 +426,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, sdkLibraries dex
			// (including the java_sdk_library) itself then append any implicit sdk library
			// names to the list of sdk libraries to be added to the manifest.
			if component, ok := module.(SdkLibraryComponentDependency); ok {
				sdkLibraries.MaybeAddContext(ctx, component.OptionalImplicitSdkLibrary(),
				classLoaderContexts.MaybeAddContext(ctx, component.OptionalImplicitSdkLibrary(), true,
					component.DexJarBuildPath(), component.DexJarInstallPath())
			}

@@ -439,7 +439,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, sdkLibraries dex
				transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...)
				transitiveStaticLibs = append(transitiveStaticLibs, exportPackage)
				transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...)
				sdkLibraries.AddContextMap(aarDep.ExportedSdkLibs(), depName)
				classLoaderContexts.AddContextMap(aarDep.ClassLoaderContexts(), depName)
				if aarDep.ExportedAssets().Valid() {
					assets = append(assets, aarDep.ExportedAssets().Path())
				}
@@ -461,7 +461,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, sdkLibraries dex
		// Add nested dependencies after processing the direct dependency: if it is a <uses-library>,
		// nested context is added as its subcontext, and should not be re-added at the top-level.
		if dep, ok := module.(Dependency); ok {
			sdkLibraries.AddContextMap(dep.ExportedSdkLibs(), depName)
			classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), depName)
		}
	})

@@ -514,8 +514,8 @@ func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {

func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	a.aapt.isLibrary = true
	a.exportedSdkLibs = make(dexpreopt.ClassLoaderContextMap)
	a.aapt.buildActions(ctx, sdkContext(a), a.exportedSdkLibs)
	a.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
	a.aapt.buildActions(ctx, sdkContext(a), a.classLoaderContexts)

	a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()

@@ -832,7 +832,7 @@ func (a *AARImport) AidlIncludeDirs() android.Paths {
	return nil
}

func (a *AARImport) ExportedSdkLibs() dexpreopt.ClassLoaderContextMap {
func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
	return nil
}

+2 −2
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ var manifestMergerRule = pctx.AndroidStaticRule("manifestMerger",

// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext sdkContext,
	sdkLibraries dexpreopt.ClassLoaderContextMap, isLibrary, useEmbeddedNativeLibs, usesNonSdkApis,
	classLoaderContexts dexpreopt.ClassLoaderContextMap, isLibrary, useEmbeddedNativeLibs, usesNonSdkApis,
	useEmbeddedDex, hasNoCode bool, loggingParent string) android.Path {

	var args []string
@@ -71,7 +71,7 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext
		args = append(args, "--use-embedded-dex")
	}

	for _, usesLib := range sdkLibraries.UsesLibs() {
	for _, usesLib := range classLoaderContexts.UsesLibs() {
		if inList(usesLib, dexpreopt.OptionalCompatUsesLibs) {
			args = append(args, "--optional-uses-library", usesLib)
		} else {
+1 −1
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
						entries.SetPath("LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR", library.jacocoReportClassesFile)
					}

					entries.AddStrings("LOCAL_EXPORT_SDK_LIBRARIES", library.exportedSdkLibs.UsesLibs()...)
					entries.AddStrings("LOCAL_EXPORT_SDK_LIBRARIES", library.classLoaderContexts.UsesLibs()...)

					if len(library.additionalCheckedModules) != 0 {
						entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", library.additionalCheckedModules.Strings()...)
Loading