Allow sdk_version: "system_server_current" modules to access module-lib APIs

Previously, a java module with sdk_version: "system_server_current",
would only be able to access the system server or public API of a
java_sdk_library. This change allows it to access the system server,
module lib, system and public APIs in that order.

The apiScope structs define the characteristics of each of the
different API scopes used as required by the java_sdk_library. They are
organized into a hierarchy which is used for two different purposes.

The first purpose is to define an extension hierachy. If scope X
extends Y then X provides a superset of all API elements (classes,
fields, methods, etc) provided by Y. That is reflected in the fact that
the .txt file for X would be a delta on the .txt file for Y. So, system
extends public and so system_current.txt only contains additional API
elements to add to current.txt.

The second purpose is when a java_sdk_library/import is asked to
provide a specific API scope. e.g. a library that has:
    sdk_version: "module_current"
will ask each of the SDK libraries it depends upon for a module-lib
API. However, not all of them will provide an API for that scope. In
that case it will find the closest suitable API scope.

Previously, it did that by traversing up the API extension until it
found an API scope that it did provide and return that. As
system_server_current extended the public API that meant that a library
which has:
    sdk_version: "system_server_current"
would provide a system server API if available, and if not fall
straight back to public. That meant that the library could not access
system or module-lib APIs even though it is running in the system
server which should be able to access all APIs.

One way to fix this would have been to just have system server API
scope extend module-lib but that would have had a number of nasty
side effects:
* It would have created a significant overhead as every module that
  provides a system server API would also have to provide a module-lib
  and system API, along with their corresponding .txt files.
* Each existing java_sdk_library that provided a system server API
  would need those .txt files created.
* Generating sdk snapshots for older releases would have been more
  complicated.
* It would have confused developers.

All of that would be unnecessary because the system server API scope is
intended to be provided by libraries that are used solely by the system
server so there is no point in them providing anything other than a
system server API.

So, instead a separate access hierarchy was added which is the same as
the extension hierarchy for all existing scopes except for the
system server scope, which instead of just being able to access the
public API will be able to access the module-lib scope, which can in
turn access system and it can in turn access public.

That achieves what we want which is a library that is loaded into the
system server to be able to access all API scopes.

Bug: 204176972
Test: m nothing
Change-Id: I854df63fcaeba32afbc1eb0d1a501238022673d0
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 59ffff5..fad1df7 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -65,8 +65,27 @@
 	name string
 
 	// The api scope that this scope extends.
+	//
+	// This organizes the scopes into an extension hierarchy.
+	//
+	// If set this means that the API provided by this scope includes the API provided by the scope
+	// set in this field.
 	extends *apiScope
 
+	// The next api scope that a library that uses this scope can access.
+	//
+	// This organizes the scopes into an access hierarchy.
+	//
+	// If set this means that a library that can access this API can also access the API provided by
+	// the scope set in this field.
+	//
+	// A module that sets sdk_version: "<scope>_current" should have access to the <scope> API of
+	// every java_sdk_library that it depends on. If the library does not provide an API for <scope>
+	// then it will traverse up this access hierarchy to find an API that it does provide.
+	//
+	// If this is not set then it defaults to the scope set in extends.
+	canAccess *apiScope
+
 	// The legacy enabled status for a specific scope can be dependent on other
 	// properties that have been specified on the library so it is provided by
 	// a function that can determine the status by examining those properties.
@@ -107,7 +126,7 @@
 	// The scope specific prefix to add to the api file base of "current.txt" or "removed.txt".
 	apiFilePrefix string
 
-	// The scope specific prefix to add to the sdk library module name to construct a scope specific
+	// The scope specific suffix to add to the sdk library module name to construct a scope specific
 	// module name.
 	moduleSuffix string
 
@@ -193,6 +212,11 @@
 		}
 	}
 
+	// By default, a library that can access a scope can also access the scope it extends.
+	if scope.canAccess == nil {
+		scope.canAccess = scope.extends
+	}
+
 	// Escape any special characters in the arguments. This is needed because droidstubs
 	// passes these directly to the shell command.
 	scope.droidstubsArgs = proptools.ShellEscapeList(scopeSpecificArgs)
@@ -310,6 +334,14 @@
 	apiScopeSystemServer = initApiScope(&apiScope{
 		name:    "system-server",
 		extends: apiScopePublic,
+
+		// The system-server scope can access the module-lib scope.
+		//
+		// A module that provides a system-server API is appended to the standard bootclasspath that is
+		// used by the system server. So, it should be able to access module-lib APIs provided by
+		// libraries on the bootclasspath.
+		canAccess: apiScopeModuleLib,
+
 		// The system-server scope is disabled by default in legacy mode.
 		//
 		// Enabling this would break existing usages.
@@ -926,7 +958,7 @@
 // If this does not support the requested api scope then find the closest available
 // scope it does support. Returns nil if no such scope is available.
 func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *scopePaths {
-	for s := scope; s != nil; s = s.extends {
+	for s := scope; s != nil; s = s.canAccess {
 		if paths := c.findScopePaths(s); paths != nil {
 			return paths
 		}