Prebuilt stub not available to platform is handled correctly

When a shared library providing stubs is included in an APEX, only the
stub variant (i.e. version:"1", etc.) gets emitted to Android.mk. This
enforces that everything in the Make world to link to the stub providing
only the public APIs of the library. The non-stub variant (i.e.
version:"") isn't exposed, otherwise, others will be able to access
private part of the lib which isn't guaranteed to be stable.

This has been done by unhiding the stub variant when it is known that
the library is actually included in an APEX. Note that stub variants are
by default hidden.

The above mechanism however doesn't work when the shared library is
replaced by a prebuilt and when the APEX is also replaced by a prebuilt.
Then, the fact that the prebuilt library is actually in the APEX gets
lost.  In that case, AnyVariantDirectlyInAnyApex() returns false for the
prebuilt library. As a result, the stub variant remains hidden and not
emitted to Android.mk.

This change fixes the problem by checking if the lib isn't available for
the platform at all. If not available for the platform (e.g.
apex_available doesn't have "//apex_available:platform"), the lib is
assumed to be included in an APEX even when it actually didn't go
through the apex mutator (... because it's a prebuilt).

Bug: 175166063
Test: m nothing

Change-Id: I41fabd5b368baecf4dc3c5a080b466f8bcd79d77
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 4f4b047..187a2ff 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -46,7 +46,7 @@
 	InRamdisk() bool
 	InVendorRamdisk() bool
 	InRecovery() bool
-	AnyVariantDirectlyInAnyApex() bool
+	NotInPlatform() bool
 }
 
 type subAndroidMkProvider interface {
@@ -281,10 +281,15 @@
 			}
 		})
 	}
-	if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.AnyVariantDirectlyInAnyApex() &&
+	// If a library providing a stub is included in an APEX, the private APIs of the library
+	// is accessible only inside the APEX. From outside of the APEX, clients can only use the
+	// public APIs via the stub. To enforce this, the (latest version of the) stub gets the
+	// name of the library. The impl library instead gets the `.bootstrap` suffix to so that
+	// they can be exceptionally used directly when APEXes are not available (e.g. during the
+	// very early stage in the boot process).
+	if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.NotInPlatform() &&
 		!ctx.InRamdisk() && !ctx.InVendorRamdisk() && !ctx.InRecovery() && !ctx.UseVndk() && !ctx.static() {
 		if library.buildStubs() && library.isLatestStubVersion() {
-			// reference the latest version via its name without suffix when it is provided by apex
 			entries.SubName = ""
 		}
 		if !library.buildStubs() {
diff --git a/cc/cc.go b/cc/cc.go
index 9383e39..0e58436 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1586,13 +1586,14 @@
 		}
 		c.outputFile = android.OptionalPathForPath(outputFile)
 
-		// If a lib is directly included in any of the APEXes, unhide the stubs
-		// variant having the latest version gets visible to make. In addition,
-		// the non-stubs variant is renamed to <libname>.bootstrap. This is to
-		// force anything in the make world to link against the stubs library.
-		// (unless it is explicitly referenced via .bootstrap suffix or the
-		// module is marked with 'bootstrap: true').
-		if c.HasStubsVariants() && c.AnyVariantDirectlyInAnyApex() && !c.InRamdisk() &&
+		// If a lib is directly included in any of the APEXes or is not available to the
+		// platform (which is often the case when the stub is provided as a prebuilt),
+		// unhide the stubs variant having the latest version gets visible to make. In
+		// addition, the non-stubs variant is renamed to <libname>.bootstrap. This is to
+		// force anything in the make world to link against the stubs library.  (unless it
+		// is explicitly referenced via .bootstrap suffix or the module is marked with
+		// 'bootstrap: true').
+		if c.HasStubsVariants() && c.NotInPlatform() && !c.InRamdisk() &&
 			!c.InRecovery() && !c.UseVndk() && !c.static() && !c.isCoverageVariant() &&
 			c.IsStubs() && !c.InVendorRamdisk() {
 			c.Properties.HideFromMake = false // unhide
@@ -2472,7 +2473,7 @@
 						// an APEX (and not from platform)
 						// However, for host, ramdisk, vendor_ramdisk, recovery or bootstrap modules,
 						// always link to non-stub variant
-						useStubs = dep.(android.ApexModule).AnyVariantDirectlyInAnyApex() && !c.bootstrap()
+						useStubs = dep.(android.ApexModule).NotInPlatform() && !c.bootstrap()
 						// Another exception: if this module is bundled with an APEX, then
 						// it is linked with the non-stub variant of a module in the APEX
 						// as if this is part of the APEX.