Enable hiddenapi check for exportable stubs am: bd093457e2 am: c32db5a7ad am: e1678131d3

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/2889892

Change-Id: Idb07d662b8e37dcd0138f4e7d086ef2eefb9d23b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/android/config.go b/android/config.go
index e9b1edd..1d0141a 100644
--- a/android/config.go
+++ b/android/config.go
@@ -214,6 +214,10 @@
 	return c.config.productVariables.GetBuildFlagBool("RELEASE_NDK_ABI_MONITORED")
 }
 
+func (c Config) ReleaseHiddenApiExportableStubs() bool {
+	return c.config.productVariables.GetBuildFlagBool("RELEASE_HIDDEN_API_EXPORTABLE_STUBS")
+}
+
 // A DeviceConfig object represents the configuration for a particular device
 // being built. For now there will only be one of these, but in the future there
 // may be multiple devices being built.
diff --git a/android/sdk_version.go b/android/sdk_version.go
index 73568af..9355667 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -109,6 +109,17 @@
 	}
 }
 
+func (k SdkKind) DefaultExportableJavaLibraryName() string {
+	switch k {
+	case SdkPublic, SdkSystem, SdkTest, SdkModule, SdkSystemServer:
+		return k.DefaultJavaLibraryName() + "_exportable"
+	case SdkCore:
+		return k.DefaultJavaLibraryName() + ".exportable"
+	default:
+		panic(fmt.Errorf("API surface %v does not provide exportable stubs", k))
+	}
+}
+
 // SdkSpec represents the kind and the version of an SDK for a module to build against
 type SdkSpec struct {
 	Kind     SdkKind
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index b431661..f1e71b0 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -53,7 +53,11 @@
 		java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
 		java.FixtureConfigureApexBootJars("someapex:foo", "someapex:bar"),
 		prepareForTestWithArtApex,
-
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.BuildFlags = map[string]string{
+				"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+			}
+		}),
 		java.PrepareForTestWithJavaSdkLibraryFiles,
 		java.FixtureWithLastReleaseApis("foo", "baz"),
 	).RunTestWithBp(t, `
@@ -154,9 +158,9 @@
 	artFragment := result.Module("art-bootclasspath-fragment", "android_common")
 	artInfo, _ := android.SingletonModuleProvider(result, artFragment, java.HiddenAPIInfoProvider)
 
-	bazPublicStubs := "out/soong/.intermediates/baz.stubs/android_common/dex/baz.stubs.jar"
-	bazSystemStubs := "out/soong/.intermediates/baz.stubs.system/android_common/dex/baz.stubs.system.jar"
-	bazTestStubs := "out/soong/.intermediates/baz.stubs.test/android_common/dex/baz.stubs.test.jar"
+	bazPublicStubs := "out/soong/.intermediates/baz.stubs.exportable/android_common/dex/baz.stubs.exportable.jar"
+	bazSystemStubs := "out/soong/.intermediates/baz.stubs.exportable.system/android_common/dex/baz.stubs.exportable.system.jar"
+	bazTestStubs := "out/soong/.intermediates/baz.stubs.exportable.test/android_common/dex/baz.stubs.exportable.test.jar"
 
 	checkAPIScopeStubs("art", artInfo, java.PublicHiddenAPIScope, bazPublicStubs)
 	checkAPIScopeStubs("art", artInfo, java.SystemHiddenAPIScope, bazSystemStubs)
@@ -167,8 +171,8 @@
 	otherFragment := result.Module("other-bootclasspath-fragment", "android_common")
 	otherInfo, _ := android.SingletonModuleProvider(result, otherFragment, java.HiddenAPIInfoProvider)
 
-	fooPublicStubs := "out/soong/.intermediates/foo.stubs/android_common/dex/foo.stubs.jar"
-	fooSystemStubs := "out/soong/.intermediates/foo.stubs.system/android_common/dex/foo.stubs.system.jar"
+	fooPublicStubs := "out/soong/.intermediates/foo.stubs.exportable/android_common/dex/foo.stubs.exportable.jar"
+	fooSystemStubs := "out/soong/.intermediates/foo.stubs.exportable.system/android_common/dex/foo.stubs.exportable.system.jar"
 
 	checkAPIScopeStubs("other", otherInfo, java.PublicHiddenAPIScope, bazPublicStubs, fooPublicStubs)
 	checkAPIScopeStubs("other", otherInfo, java.SystemHiddenAPIScope, bazSystemStubs, fooSystemStubs)
@@ -696,6 +700,11 @@
 
 		java.PrepareForTestWithJavaSdkLibraryFiles,
 		java.FixtureWithLastReleaseApis("foo", "quuz"),
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.BuildFlags = map[string]string{
+				"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+			}
+		}),
 	).RunTestWithBp(t, `
 		apex {
 			name: "com.android.art",
@@ -807,11 +816,11 @@
 		"foo",
 	})
 
-	fooStubs := getDexJarPath(result, "foo.stubs")
-	quuzPublicStubs := getDexJarPath(result, "quuz.stubs")
-	quuzSystemStubs := getDexJarPath(result, "quuz.stubs.system")
-	quuzTestStubs := getDexJarPath(result, "quuz.stubs.test")
-	quuzModuleLibStubs := getDexJarPath(result, "quuz.stubs.module_lib")
+	fooStubs := getDexJarPath(result, "foo.stubs.exportable")
+	quuzPublicStubs := getDexJarPath(result, "quuz.stubs.exportable")
+	quuzSystemStubs := getDexJarPath(result, "quuz.stubs.exportable.system")
+	quuzTestStubs := getDexJarPath(result, "quuz.stubs.exportable.test")
+	quuzModuleLibStubs := getDexJarPath(result, "quuz.stubs.exportable.module_lib")
 
 	// Make sure that the fragment uses the quuz stub dex jars when generating the hidden API flags.
 	fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index 01b616b..161941d 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -252,6 +252,11 @@
 		java.FixtureWithLastReleaseApis("foo"),
 		java.PrepareForTestWithDexpreopt,
 		dexpreopt.FixtureDisableDexpreoptBootImages(false),
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.BuildFlags = map[string]string{
+				"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+			}
+		}),
 	).RunTestWithBp(t, `
 		apex {
 			name: "com.android.art",
@@ -386,10 +391,10 @@
 		`platform:all_apex_contributions`,
 
 		// The following are stubs.
-		`platform:android_stubs_current`,
-		`platform:android_system_stubs_current`,
-		`platform:android_test_stubs_current`,
-		`platform:legacy.core.platform.api.stubs`,
+		`platform:android_stubs_current_exportable`,
+		`platform:android_system_stubs_current_exportable`,
+		`platform:android_test_stubs_current_exportable`,
+		`platform:legacy.core.platform.api.stubs.exportable`,
 
 		// Needed for generating the boot image.
 		`platform:dex2oatd`,
@@ -422,6 +427,9 @@
 		java.PrepareForTestWithJavaSdkLibraryFiles,
 		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
 			variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
+			variables.BuildFlags = map[string]string{
+				"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+			}
 		}),
 		java.FixtureWithPrebuiltApis(map[string][]string{
 			"current": {},
@@ -546,7 +554,7 @@
 		"platform:prebuilt_sdk_test_current_android",
 
 		// Not a prebuilt as no prebuilt existed when it was added.
-		"platform:legacy.core.platform.api.stubs",
+		"platform:legacy.core.platform.api.stubs.exportable",
 
 		// The platform_bootclasspath intentionally adds dependencies on both source and prebuilt
 		// modules when available as it does not know which one will be preferred.
diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go
index 216c3b3..95cd4a9 100644
--- a/java/bootclasspath_fragment_test.go
+++ b/java/bootclasspath_fragment_test.go
@@ -222,6 +222,11 @@
 		PrepareForTestWithJavaSdkLibraryFiles,
 		FixtureWithLastReleaseApis("mysdklibrary", "myothersdklibrary", "mycoreplatform"),
 		FixtureConfigureApexBootJars("someapex:mysdklibrary"),
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.BuildFlags = map[string]string{
+				"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+			}
+		}),
 	).RunTestWithBp(t, `
 		bootclasspath_fragment {
 			name: "myfragment",
@@ -277,11 +282,11 @@
 	stubsJar := "out/soong/.intermediates/mystublib/android_common/dex/mystublib.jar"
 
 	// Stubs jars for mysdklibrary
-	publicStubsJar := "out/soong/.intermediates/mysdklibrary.stubs/android_common/dex/mysdklibrary.stubs.jar"
-	systemStubsJar := "out/soong/.intermediates/mysdklibrary.stubs.system/android_common/dex/mysdklibrary.stubs.system.jar"
+	publicStubsJar := "out/soong/.intermediates/mysdklibrary.stubs.exportable/android_common/dex/mysdklibrary.stubs.exportable.jar"
+	systemStubsJar := "out/soong/.intermediates/mysdklibrary.stubs.exportable.system/android_common/dex/mysdklibrary.stubs.exportable.system.jar"
 
 	// Stubs jars for myothersdklibrary
-	otherPublicStubsJar := "out/soong/.intermediates/myothersdklibrary.stubs/android_common/dex/myothersdklibrary.stubs.jar"
+	otherPublicStubsJar := "out/soong/.intermediates/myothersdklibrary.stubs.exportable/android_common/dex/myothersdklibrary.stubs.exportable.jar"
 
 	// Check that SdkPublic uses public stubs for all sdk libraries.
 	android.AssertPathsRelativeToTopEquals(t, "public dex stubs jar", []string{otherPublicStubsJar, publicStubsJar, stubsJar}, info.TransitiveStubDexJarsByScope.StubDexJarsForScope(PublicHiddenAPIScope))
diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp
index c6ab561..8ffe511 100644
--- a/java/core-libraries/Android.bp
+++ b/java/core-libraries/Android.bp
@@ -38,9 +38,6 @@
     visibility: ["//visibility:public"],
     sdk_version: "none",
     system_modules: "none",
-    dist: {
-        targets: dist_targets,
-    },
 }
 
 java_library {
@@ -89,6 +86,32 @@
     },
 }
 
+java_library {
+    name: "core.current.stubs.exportable.from-source",
+    defaults: [
+        "core.current.stubs.defaults",
+    ],
+    static_libs: [
+        "art.module.public.api.stubs.exportable",
+        "conscrypt.module.public.api.stubs.exportable",
+        "i18n.module.public.api.stubs.exportable",
+    ],
+    dist: {
+        targets: dist_targets,
+        dest: "core.current.stubs.jar",
+    },
+}
+
+java_library {
+    name: "core.current.stubs.exportable",
+    defaults: [
+        "core.current.stubs.defaults",
+    ],
+    static_libs: [
+        "core.current.stubs.exportable.from-source",
+    ],
+}
+
 // Distributed with the SDK for turning into system modules to compile apps
 // against.
 //
@@ -298,6 +321,19 @@
     ],
 }
 
+java_library {
+    name: "legacy.core.platform.api.stubs.exportable.from-source",
+    visibility: core_platform_visibility,
+    defaults: [
+        "core.platform.api.stubs.defaults",
+    ],
+    static_libs: [
+        "art.module.public.api.stubs.exportable.module_lib",
+        "conscrypt.module.platform.api.stubs.exportable",
+        "legacy.i18n.module.platform.api.stubs.exportable",
+    ],
+}
+
 java_defaults {
     name: "android_core_platform_stubs_current_contributions",
     api_surface: "core_platform",
@@ -345,6 +381,17 @@
     },
 }
 
+java_library {
+    name: "legacy.core.platform.api.stubs.exportable",
+    visibility: core_platform_visibility,
+    defaults: [
+        "core.platform.api.stubs.defaults",
+    ],
+    static_libs: [
+        "legacy.core.platform.api.stubs.exportable.from-source",
+    ],
+}
+
 java_defaults {
     name: "core.platform.api.stubs.defaults",
     hostdex: true,
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index a512860..06e17c9 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -245,12 +245,22 @@
 		testStubModules = append(testStubModules, "sdk_test_current_android")
 	} else {
 		// Use stub modules built from source
-		publicStubModules = append(publicStubModules, android.SdkPublic.DefaultJavaLibraryName())
-		systemStubModules = append(systemStubModules, android.SdkSystem.DefaultJavaLibraryName())
-		testStubModules = append(testStubModules, android.SdkTest.DefaultJavaLibraryName())
+		if config.ReleaseHiddenApiExportableStubs() {
+			publicStubModules = append(publicStubModules, android.SdkPublic.DefaultExportableJavaLibraryName())
+			systemStubModules = append(systemStubModules, android.SdkSystem.DefaultExportableJavaLibraryName())
+			testStubModules = append(testStubModules, android.SdkTest.DefaultExportableJavaLibraryName())
+		} else {
+			publicStubModules = append(publicStubModules, android.SdkPublic.DefaultJavaLibraryName())
+			systemStubModules = append(systemStubModules, android.SdkSystem.DefaultJavaLibraryName())
+			testStubModules = append(testStubModules, android.SdkTest.DefaultJavaLibraryName())
+		}
 	}
 	// We do not have prebuilts of the core platform api yet
-	corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs")
+	if config.ReleaseHiddenApiExportableStubs() {
+		corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs.exportable")
+	} else {
+		corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs")
+	}
 
 	// Allow products to define their own stubs for custom product jars that apps can use.
 	publicStubModules = append(publicStubModules, config.ProductHiddenAPIStubs()...)
@@ -289,7 +299,12 @@
 func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path {
 	var dexJar OptionalDexJarPath
 	if sdkLibrary, ok := module.(SdkLibraryDependency); ok {
-		dexJar = sdkLibrary.SdkApiStubDexJar(ctx, kind)
+		if ctx.Config().ReleaseHiddenApiExportableStubs() {
+			dexJar = sdkLibrary.SdkApiExportableStubDexJar(ctx, kind)
+		} else {
+			dexJar = sdkLibrary.SdkApiStubDexJar(ctx, kind)
+		}
+
 	} else if j, ok := module.(UsesLibraryDependency); ok {
 		dexJar = j.DexJarBuildPath(ctx)
 	} else {
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index 37afe29..c1fee21 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -177,10 +177,10 @@
 		{
 			name:             "testBundled",
 			unbundledBuild:   false,
-			publicStub:       "android_stubs_current",
-			systemStub:       "android_system_stubs_current",
-			testStub:         "android_test_stubs_current",
-			corePlatformStub: "legacy.core.platform.api.stubs",
+			publicStub:       "android_stubs_current_exportable",
+			systemStub:       "android_system_stubs_current_exportable",
+			testStub:         "android_test_stubs_current_exportable",
+			corePlatformStub: "legacy.core.platform.api.stubs.exportable",
 			preparer:         android.GroupFixturePreparers(),
 		}, {
 			name:             "testUnbundled",
@@ -188,7 +188,7 @@
 			publicStub:       "sdk_public_current_android",
 			systemStub:       "sdk_system_current_android",
 			testStub:         "sdk_test_current_android",
-			corePlatformStub: "legacy.core.platform.api.stubs",
+			corePlatformStub: "legacy.core.platform.api.stubs.exportable",
 			preparer:         PrepareForTestWithPrebuiltsOfCurrentApi,
 		},
 	}
@@ -200,6 +200,9 @@
 				prepareForTestWithDefaultPlatformBootclasspath,
 				android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
 					variables.Always_use_prebuilt_sdks = proptools.BoolPtr(tc.unbundledBuild)
+					variables.BuildFlags = map[string]string{
+						"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+					}
 				}),
 			).RunTest(t)
 
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 058862b..74e2da4 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -104,9 +104,16 @@
 	// The name of the property in the java_sdk_library_import
 	propertyName string
 
-	// The tag to use to depend on the stubs library module.
+	// The tag to use to depend on the stubs library module if the parent module
+	// does not differentiate everything and exportable stubs (e.g. sdk_library_import).
 	stubsTag scopeDependencyTag
 
+	// The tag to use to depend on the everything stubs library module.
+	everythingStubsTag scopeDependencyTag
+
+	// The tag to use to depend on the exportable stubs library module.
+	exportableStubsTag scopeDependencyTag
+
 	// The tag to use to depend on the stubs source module (if separate from the API module).
 	stubsSourceTag scopeDependencyTag
 
@@ -172,6 +179,16 @@
 		apiScope:         scope,
 		depInfoExtractor: (*scopePaths).extractStubsLibraryInfoFromDependency,
 	}
+	scope.everythingStubsTag = scopeDependencyTag{
+		name:             name + "-stubs-everything",
+		apiScope:         scope,
+		depInfoExtractor: (*scopePaths).extractEverythingStubsLibraryInfoFromDependency,
+	}
+	scope.exportableStubsTag = scopeDependencyTag{
+		name:             name + "-stubs-exportable",
+		apiScope:         scope,
+		depInfoExtractor: (*scopePaths).extractExportableStubsLibraryInfoFromDependency,
+	}
 	scope.stubsSourceTag = scopeDependencyTag{
 		name:             name + "-stubs-source",
 		apiScope:         scope,
@@ -669,6 +686,11 @@
 	// This is not the implementation jar, it still only contains stubs.
 	stubsDexJarPath OptionalDexJarPath
 
+	// The exportable dex jar for the stubs.
+	// This is not the implementation jar, it still only contains stubs.
+	// Includes unflagged apis and flagged apis enabled by release configurations.
+	exportableStubsDexJarPath OptionalDexJarPath
+
 	// The API specification file, e.g. system_current.txt.
 	currentApiFilePath android.OptionalPath
 
@@ -695,6 +717,30 @@
 
 		libDep := dep.(UsesLibraryDependency)
 		paths.stubsDexJarPath = libDep.DexJarBuildPath(ctx)
+		paths.exportableStubsDexJarPath = libDep.DexJarBuildPath(ctx)
+		return nil
+	} else {
+		return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
+	}
+}
+
+func (paths *scopePaths) extractEverythingStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error {
+	if lib, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
+		paths.stubsHeaderPath = lib.HeaderJars
+		paths.stubsImplPath = lib.ImplementationJars
+
+		libDep := dep.(UsesLibraryDependency)
+		paths.stubsDexJarPath = libDep.DexJarBuildPath(ctx)
+		return nil
+	} else {
+		return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
+	}
+}
+
+func (paths *scopePaths) extractExportableStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error {
+	if _, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
+		libDep := dep.(UsesLibraryDependency)
+		paths.exportableStubsDexJarPath = libDep.DexJarBuildPath(ctx)
 		return nil
 	} else {
 		return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
@@ -1132,6 +1178,16 @@
 }
 
 // to satisfy SdkLibraryDependency interface
+func (c *commonToSdkLibraryAndImport) SdkApiExportableStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath {
+	paths := c.selectScopePaths(ctx, kind)
+	if paths == nil {
+		return makeUnsetDexJarPath()
+	}
+
+	return paths.exportableStubsDexJarPath
+}
+
+// to satisfy SdkLibraryDependency interface
 func (c *commonToSdkLibraryAndImport) SdkRemovedTxtFile(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath {
 	apiScope := sdkKindToApiScope(kind)
 	paths := c.findScopePaths(apiScope)
@@ -1249,10 +1305,16 @@
 	// they are identical to the corresponding header jars.
 	SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths
 
-	// SdkApiStubDexJar returns the dex jar for the stubs. It is needed by the hiddenapi processing
-	// tool which processes dex files.
+	// SdkApiStubDexJar returns the dex jar for the stubs for the prebuilt
+	// java_sdk_library_import module. It is needed by the hiddenapi processing tool which
+	// processes dex files.
 	SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath
 
+	// SdkApiExportableStubDexJar returns the exportable dex jar for the stubs for
+	// java_sdk_library module. It is needed by the hiddenapi processing tool which processes
+	// dex files.
+	SdkApiExportableStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath
+
 	// SdkRemovedTxtFile returns the optional path to the removed.txt file for the specified sdk kind.
 	SdkRemovedTxtFile(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath
 
@@ -1365,8 +1427,10 @@
 	for _, apiScope := range module.getGeneratedApiScopes(ctx) {
 		// Add dependencies to the stubs library
 		stubModuleName := module.stubsLibraryModuleName(apiScope)
+		ctx.AddVariationDependencies(nil, apiScope.everythingStubsTag, stubModuleName)
 
-		ctx.AddVariationDependencies(nil, apiScope.stubsTag, stubModuleName)
+		exportableStubModuleName := module.exportableStubsLibraryModuleName(apiScope)
+		ctx.AddVariationDependencies(nil, apiScope.exportableStubsTag, exportableStubModuleName)
 
 		// Add a dependency on the stubs source in order to access both stubs source and api information.
 		ctx.AddVariationDependencies(nil, apiScope.stubsSourceAndApiTag, module.stubsSourceModuleName(apiScope))
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index c14f3e6..3326ec5 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -38,6 +38,11 @@
 		android.FixtureModifyConfig(func(config android.Config) {
 			config.SetApiLibraries([]string{"foo"})
 		}),
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.BuildFlags = map[string]string{
+				"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+			}
+		}),
 	).RunTestWithBp(t, `
 		droiddoc_exported_dir {
 			name: "droiddoc-templates-sdk",
@@ -139,6 +144,9 @@
 		"foo.api.public.latest",
 		"foo.api.system.latest",
 		"foo.stubs",
+		"foo.stubs.exportable",
+		"foo.stubs.exportable.system",
+		"foo.stubs.exportable.test",
 		"foo.stubs.source",
 		"foo.stubs.source.system",
 		"foo.stubs.source.test",
@@ -529,6 +537,11 @@
 		prepareForJavaTest,
 		PrepareForTestWithJavaSdkLibraryFiles,
 		FixtureWithLastReleaseApis("sdklib"),
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.BuildFlags = map[string]string{
+				"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+			}
+		}),
 	).RunTestWithBp(t, `
 		java_sdk_library {
 			name: "sdklib",
@@ -547,6 +560,7 @@
 		`sdklib.api.public.latest`,
 		`sdklib.impl`,
 		`sdklib.stubs`,
+		`sdklib.stubs.exportable`,
 		`sdklib.stubs.source`,
 		`sdklib.xml`,
 	})
@@ -919,6 +933,11 @@
 		prepareForJavaTest,
 		PrepareForTestWithJavaSdkLibraryFiles,
 		FixtureWithLastReleaseApis("sdklib"),
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.BuildFlags = map[string]string{
+				"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+			}
+		}),
 	).RunTestWithBp(t, `
 		java_sdk_library {
 			name: "sdklib",
@@ -945,6 +964,7 @@
 		`sdklib.api.public.latest`,
 		`sdklib.impl`,
 		`sdklib.stubs`,
+		`sdklib.stubs.exportable`,
 		`sdklib.stubs.source`,
 		`sdklib.xml`,
 	})
@@ -966,6 +986,11 @@
 		PrepareForTestWithJavaSdkLibraryFiles,
 		FixtureWithLastReleaseApis("sdklib"),
 		preparer,
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.BuildFlags = map[string]string{
+				"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+			}
+		}),
 	).RunTestWithBp(t, `
 		java_sdk_library {
 			name: "sdklib",
@@ -1018,6 +1043,7 @@
 		`sdklib.api.public.latest`,
 		`sdklib.impl`,
 		`sdklib.stubs`,
+		`sdklib.stubs.exportable`,
 		`sdklib.stubs.source`,
 		`sdklib.xml`,
 	})
diff --git a/java/testing.go b/java/testing.go
index 5959c49..04e8c73 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -407,6 +407,14 @@
 		"legacy.core.platform.api.stubs",
 		"stable.core.platform.api.stubs",
 
+		"android_stubs_current_exportable",
+		"android_system_stubs_current_exportable",
+		"android_test_stubs_current_exportable",
+		"android_module_lib_stubs_current_exportable",
+		"android_system_server_stubs_current_exportable",
+		"core.current.stubs.exportable",
+		"legacy.core.platform.api.stubs.exportable",
+
 		"kotlin-stdlib",
 		"kotlin-stdlib-jdk7",
 		"kotlin-stdlib-jdk8",
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 273a5cf..16dde59 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -997,6 +997,12 @@
 			"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": targetBuildRelease,
 		}),
 
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.BuildFlags = map[string]string{
+				"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+			}
+		}),
+
 		android.FixtureWithRootAndroidBp(`
 			sdk {
 				name: "mysdk",
@@ -1103,7 +1109,7 @@
 		// On S the stub flags should only be generated from mysdklibrary as mynewsdklibrary is not part
 		// of the snapshot.
 		expectedStubFlagsInputs := []string{
-			"out/soong/.intermediates/mysdklibrary.stubs/android_common/dex/mysdklibrary.stubs.jar",
+			"out/soong/.intermediates/mysdklibrary.stubs.exportable/android_common/dex/mysdklibrary.stubs.exportable.jar",
 			"out/soong/.intermediates/mysdklibrary/android_common/aligned/mysdklibrary.jar",
 		}
 
@@ -1184,9 +1190,9 @@
 		// On tiramisu the stub flags should be generated from both mynewsdklibrary and mysdklibrary as
 		// they are both part of the snapshot.
 		expectedStubFlagsInputs := []string{
-			"out/soong/.intermediates/mynewsdklibrary.stubs/android_common/dex/mynewsdklibrary.stubs.jar",
+			"out/soong/.intermediates/mynewsdklibrary.stubs.exportable/android_common/dex/mynewsdklibrary.stubs.exportable.jar",
 			"out/soong/.intermediates/mynewsdklibrary/android_common/aligned/mynewsdklibrary.jar",
-			"out/soong/.intermediates/mysdklibrary.stubs/android_common/dex/mysdklibrary.stubs.jar",
+			"out/soong/.intermediates/mysdklibrary.stubs.exportable/android_common/dex/mysdklibrary.stubs.exportable.jar",
 			"out/soong/.intermediates/mysdklibrary/android_common/aligned/mysdklibrary.jar",
 		}
 
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 592c005..5165b4a 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -1162,7 +1162,14 @@
 }
 
 func TestSnapshotWithJavaSdkLibrary_CompileDex(t *testing.T) {
-	result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, `
+	result := android.GroupFixturePreparers(
+		prepareForSdkTestWithJavaSdkLibrary,
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.BuildFlags = map[string]string{
+				"RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+			}
+		}),
+	).RunTestWithBp(t, `
 		sdk {
 			name: "mysdk",
 			java_sdk_libs: ["myjavalib"],
@@ -1214,21 +1221,22 @@
 			ctx := android.ModuleInstallPathContextForTesting(result.Config)
 			dexJarBuildPath := func(name string, kind android.SdkKind) string {
 				dep := result.Module(name, "android_common").(java.SdkLibraryDependency)
-				path := dep.SdkApiStubDexJar(ctx, kind).Path()
+				path := dep.SdkApiExportableStubDexJar(ctx, kind).Path()
 				return path.RelativeToTop().String()
 			}
 
 			dexJarPath := dexJarBuildPath("myjavalib", android.SdkPublic)
-			android.AssertStringEquals(t, "source dex public stubs jar build path", "out/soong/.intermediates/myjavalib.stubs/android_common/dex/myjavalib.stubs.jar", dexJarPath)
+			android.AssertStringEquals(t, "source dex public stubs jar build path", "out/soong/.intermediates/myjavalib.stubs.exportable/android_common/dex/myjavalib.stubs.exportable.jar", dexJarPath)
 
 			dexJarPath = dexJarBuildPath("myjavalib", android.SdkSystem)
-			systemDexJar := "out/soong/.intermediates/myjavalib.stubs.system/android_common/dex/myjavalib.stubs.system.jar"
+			systemDexJar := "out/soong/.intermediates/myjavalib.stubs.exportable.system/android_common/dex/myjavalib.stubs.exportable.system.jar"
 			android.AssertStringEquals(t, "source dex system stubs jar build path", systemDexJar, dexJarPath)
 
 			// This should fall back to system as module is not available.
 			dexJarPath = dexJarBuildPath("myjavalib", android.SdkModule)
 			android.AssertStringEquals(t, "source dex module stubs jar build path", systemDexJar, dexJarPath)
 
+			// Prebuilt dex jar does not come from the exportable stubs.
 			dexJarPath = dexJarBuildPath(android.PrebuiltNameFromSource("myjavalib"), android.SdkPublic)
 			android.AssertStringEquals(t, "prebuilt dex public stubs jar build path", "out/soong/.intermediates/snapshot/prebuilt_myjavalib.stubs/android_common/dex/myjavalib.stubs.jar", dexJarPath)
 		}),