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

Commit 9b879594 authored by Paul Duffin's avatar Paul Duffin
Browse files

java_sdk_library: Expose implementation within APEX

Access to the implementation JARs is restricted to avoid code from
depending on implementation details that could change from one release
to the next which could cause compatibility issues. That is not a
problem when referenced from within the APEX that contains the
java_sdk_library.

As references from within the same APEX often need to access
implementation specific details of the java_sdk_library and doing that
from within the same APEX is safe this change all references to a
java_sdk_library made within the same APEX to use the implementation
jars instead of stub jars.

Bug: 155164730
Test: m droid
Change-Id: If239059690de61683c2ad2d8a0ce2e47286a3637
parent daaa3328
Loading
Loading
Loading
Loading
+103 −8
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import (
	"os"
	"path"
	"reflect"
	"regexp"
	"sort"
	"strings"
	"testing"
@@ -4256,6 +4257,15 @@ func TestLegacyAndroid10Support(t *testing.T) {
	}
}

var filesForSdkLibrary = map[string][]byte{
	"api/current.txt":        nil,
	"api/removed.txt":        nil,
	"api/system-current.txt": nil,
	"api/system-removed.txt": nil,
	"api/test-current.txt":   nil,
	"api/test-removed.txt":   nil,
}

func TestJavaSDKLibrary(t *testing.T) {
	ctx, _ := testApex(t, `
		apex {
@@ -4276,14 +4286,7 @@ func TestJavaSDKLibrary(t *testing.T) {
			api_packages: ["foo"],
			apex_available: [ "myapex" ],
		}
	`, withFiles(map[string][]byte{
		"api/current.txt":        nil,
		"api/removed.txt":        nil,
		"api/system-current.txt": nil,
		"api/system-removed.txt": nil,
		"api/test-current.txt":   nil,
		"api/test-removed.txt":   nil,
	}))
	`, withFiles(filesForSdkLibrary))

	// java_sdk_library installs both impl jar and permission XML
	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
@@ -4295,6 +4298,98 @@ func TestJavaSDKLibrary(t *testing.T) {
	ensureContains(t, sdkLibrary.RuleParams.Command, `<library name=\"foo\" file=\"/apex/myapex/javalib/foo.jar\"`)
}

func TestJavaSDKLibrary_WithinApex(t *testing.T) {
	ctx, _ := testApex(t, `
		apex {
			name: "myapex",
			key: "myapex.key",
			java_libs: ["foo", "bar"],
		}

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

		java_sdk_library {
			name: "foo",
			srcs: ["a.java"],
			api_packages: ["foo"],
			apex_available: ["myapex"],
			sdk_version: "none",
			system_modules: "none",
		}

		java_library {
			name: "bar",
			srcs: ["a.java"],
			libs: ["foo"],
			apex_available: ["myapex"],
			sdk_version: "none",
			system_modules: "none",
		}
	`, withFiles(filesForSdkLibrary))

	// java_sdk_library installs both impl jar and permission XML
	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
		"javalib/bar.jar",
		"javalib/foo.jar",
		"etc/permissions/foo.xml",
	})

	// The bar library should depend on the implementation jar.
	barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
	if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
		t.Errorf("expected %q, found %#q", expected, actual)
	}
}

func TestJavaSDKLibrary_CrossBoundary(t *testing.T) {
	ctx, _ := testApex(t, `
		apex {
			name: "myapex",
			key: "myapex.key",
			java_libs: ["foo"],
		}

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

		java_sdk_library {
			name: "foo",
			srcs: ["a.java"],
			api_packages: ["foo"],
			apex_available: ["myapex"],
			sdk_version: "none",
			system_modules: "none",
		}

		java_library {
			name: "bar",
			srcs: ["a.java"],
			libs: ["foo"],
			sdk_version: "none",
			system_modules: "none",
		}
	`, withFiles(filesForSdkLibrary))

	// java_sdk_library installs both impl jar and permission XML
	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
		"javalib/foo.jar",
		"etc/permissions/foo.xml",
	})

	// The bar library should depend on the stubs jar.
	barLibrary := ctx.ModuleForTests("bar", "android_common").Rule("javac")
	if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
		t.Errorf("expected %q, found %#q", expected, actual)
	}
}

func TestCompatConfig(t *testing.T) {
	ctx, _ := testApex(t, `
		apex {
+20 −1
Original line number Diff line number Diff line
@@ -1293,6 +1293,24 @@ func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s sdkSpec) and
	return android.Paths{jarPath.Path()}
}

// Get the apex name for module, "" if it is for platform.
func getApexNameForModule(module android.Module) string {
	if apex, ok := module.(android.ApexModule); ok {
		return apex.ApexName()
	}

	return ""
}

// Check to see if the other module is within the same named APEX as this module.
//
// If either this or the other module are on the platform then this will return
// false.
func (module *SdkLibrary) withinSameApexAs(other android.Module) bool {
	name := module.ApexName()
	return name != "" && getApexNameForModule(other) == name
}

func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {

	// Only provide access to the implementation library if it is actually built.
@@ -1301,7 +1319,8 @@ func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkS
		//
		// Only allow access to the implementation library in the following condition:
		// * No sdk_version specified on the referencing module.
		if sdkVersion.kind == sdkPrivate {
		// * The referencing module is in the same apex as this.
		if sdkVersion.kind == sdkPrivate || module.withinSameApexAs(ctx.Module()) {
			if headerJars {
				return module.HeaderJars()
			} else {