diff --git a/java/base.go b/java/base.go
index e52cedd..284ec99 100644
--- a/java/base.go
+++ b/java/base.go
@@ -17,6 +17,8 @@
 import (
 	"fmt"
 	"path/filepath"
+	"reflect"
+	"slices"
 	"strconv"
 	"strings"
 
@@ -89,6 +91,9 @@
 	// if not blank, run jarjar using the specified rules file
 	Jarjar_rules *string `android:"path,arch_variant"`
 
+	// if not blank, used as prefix to generate repackage rule
+	Jarjar_prefix *string
+
 	// If not blank, set the java version passed to javac as -source and -target
 	Java_version *string
 
@@ -425,6 +430,8 @@
 	// inserting into the bootclasspath/classpath of another compile
 	headerJarFile android.Path
 
+	repackagedHeaderJarFile android.Path
+
 	// jar file containing implementation classes including static library dependencies but no
 	// resources
 	implementationJarFile android.Path
@@ -489,6 +496,9 @@
 	// expanded Jarjar_rules
 	expandJarjarRules android.Path
 
+	// jarjar rule for inherited jarjar rules
+	repackageJarjarRules android.Path
+
 	// Extra files generated by the module type to be added as java resources.
 	extraResources android.Paths
 
@@ -518,6 +528,10 @@
 
 	// Single aconfig "cache file" merged from this module and all dependencies.
 	mergedAconfigFiles map[string]android.Paths
+
+	// Values that will be set in the JarJarProvider data for jarjar repackaging,
+	// and merged with our dependencies' rules.
+	jarjarRenameRules map[string]string
 }
 
 func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
@@ -1072,6 +1086,19 @@
 }
 
 func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars android.Paths) {
+
+	// Auto-propagating jarjar rules
+	jarjarProviderData := j.collectJarJarRules(ctx)
+	if jarjarProviderData != nil {
+		android.SetProvider(ctx, JarJarProvider, *jarjarProviderData)
+		text := getJarJarRuleText(jarjarProviderData)
+		if text != "" {
+			ruleTextFile := android.PathForModuleOut(ctx, "repackaged-jarjar", "repackaging.txt")
+			android.WriteFileRule(ctx, ruleTextFile, text)
+			j.repackageJarjarRules = ruleTextFile
+		}
+	}
+
 	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)
 
 	deps := j.collectDeps(ctx)
@@ -1170,7 +1197,7 @@
 			ctx.ModuleErrorf("headers_only is enabled but Turbine is disabled.")
 		}
 
-		_, j.headerJarFile =
+		_, j.headerJarFile, _ =
 			j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
 				extraCombinedJars)
 		if ctx.Failed() {
@@ -1285,7 +1312,7 @@
 			// with sharding enabled. See: b/77284273.
 		}
 		extraJars := append(android.CopyOf(extraCombinedJars), kotlinHeaderJars...)
-		headerJarFileWithoutDepsOrJarjar, j.headerJarFile =
+		headerJarFileWithoutDepsOrJarjar, j.headerJarFile, j.repackagedHeaderJarFile =
 			j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
 		if ctx.Failed() {
 			return
@@ -1509,6 +1536,16 @@
 		}
 	}
 
+	// Automatic jarjar rules propagation
+	if j.repackageJarjarRules != nil {
+		repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", jarName).OutputPath
+		TransformJarJar(ctx, repackagedJarjarFile, outputFile, j.repackageJarjarRules)
+		outputFile = repackagedJarjarFile
+		if ctx.Failed() {
+			return
+		}
+	}
+
 	// Check package restrictions if necessary.
 	if len(j.properties.Permitted_packages) > 0 {
 		// Time stamp file created by the package check rule.
@@ -1678,6 +1715,7 @@
 
 	android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
 		HeaderJars:                     android.PathsIfNonNil(j.headerJarFile),
+		RepackagedHeaderJars:           android.PathsIfNonNil(j.repackagedHeaderJarFile),
 		TransitiveLibsHeaderJars:       j.transitiveLibsHeaderJars,
 		TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
 		ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
@@ -1813,7 +1851,7 @@
 
 func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
 	deps deps, flags javaBuilderFlags, jarName string,
-	extraJars android.Paths) (headerJar, jarjarAndDepsHeaderJar android.Path) {
+	extraJars android.Paths) (headerJar, jarjarAndDepsHeaderJar, jarjarAndDepsRepackagedHeaderJar android.Path) {
 
 	var jars android.Paths
 	if len(srcFiles) > 0 || len(srcJars) > 0 {
@@ -1821,7 +1859,7 @@
 		turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
 		TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
 		if ctx.Failed() {
-			return nil, nil
+			return nil, nil, nil
 		}
 		jars = append(jars, turbineJar)
 		headerJar = turbineJar
@@ -1846,11 +1884,22 @@
 		TransformJarJar(ctx, jarjarFile, jarjarAndDepsHeaderJar, j.expandJarjarRules)
 		jarjarAndDepsHeaderJar = jarjarFile
 		if ctx.Failed() {
-			return nil, nil
+			return nil, nil, nil
 		}
 	}
 
-	return headerJar, jarjarAndDepsHeaderJar
+	if j.repackageJarjarRules != nil {
+		repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-turbine-jarjar", jarName)
+		TransformJarJar(ctx, repackagedJarjarFile, jarjarAndDepsHeaderJar, j.repackageJarjarRules)
+		jarjarAndDepsRepackagedHeaderJar = repackagedJarjarFile
+		if ctx.Failed() {
+			return nil, nil, nil
+		}
+	} else {
+		jarjarAndDepsRepackagedHeaderJar = jarjarAndDepsHeaderJar
+	}
+
+	return headerJar, jarjarAndDepsHeaderJar, jarjarAndDepsRepackagedHeaderJar
 }
 
 func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
@@ -2207,6 +2256,10 @@
 				}
 				deps.classpath = append(deps.classpath, dep.HeaderJars...)
 				deps.dexClasspath = append(deps.dexClasspath, dep.HeaderJars...)
+				if len(dep.RepackagedHeaderJars) == 1 && !slices.Contains(dep.HeaderJars, dep.RepackagedHeaderJars[0]) {
+					deps.classpath = append(deps.classpath, dep.RepackagedHeaderJars...)
+					deps.dexClasspath = append(deps.dexClasspath, dep.RepackagedHeaderJars...)
+				}
 				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
 				addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
 				deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
@@ -2311,6 +2364,187 @@
 	return deps
 }
 
+// Provider for jarjar renaming rules.
+//
+// Modules can set their jarjar renaming rules with addJarJarRenameRule, and those renamings will be
+// passed to all rdeps.  The typical way that these renamings will NOT be inherited is when a module
+// links against stubs -- these are not passed through stubs. The classes will remain unrenamed on
+// classes until a module with jarjar_prefix is reached, and all as yet unrenamed classes will then
+// be renamed from that module.
+// TODO: Add another property to suppress the forwarding of
+type JarJarProviderData struct {
+	// Mapping of class names: original --> renamed.  If the value is "", the class will be
+	// renamed by the next rdep that has the jarjar_prefix attribute (or this module if it has
+	// attribute). Rdeps of that module will inherit the renaming.
+	Rename map[string]string
+}
+
+func (this JarJarProviderData) GetDebugString() string {
+	result := ""
+	for k, v := range this.Rename {
+		if strings.Contains(k, "android.companion.virtual.flags.FakeFeatureFlagsImpl") {
+			result += k + "--&gt;" + v + ";"
+		}
+	}
+	return result
+}
+
+var JarJarProvider = blueprint.NewProvider[JarJarProviderData]()
+
+var overridableJarJarPrefix = "com.android.internal.hidden_from_bootclasspath"
+
+func init() {
+	android.SetJarJarPrefixHandler(mergeJarJarPrefixes)
+}
+
+// BaseJarJarProviderData contains information that will propagate across dependencies regardless of
+// whether they are java modules or not.
+type BaseJarJarProviderData struct {
+	JarJarProviderData JarJarProviderData
+}
+
+func (this BaseJarJarProviderData) GetDebugString() string {
+	return this.JarJarProviderData.GetDebugString()
+}
+
+var BaseJarJarProvider = blueprint.NewProvider[BaseJarJarProviderData]()
+
+// mergeJarJarPrefixes is called immediately before module.GenerateAndroidBuildActions is called.
+// Since there won't be a JarJarProvider, we create the BaseJarJarProvider if any of our deps have
+// either JarJarProvider or BaseJarJarProvider.
+func mergeJarJarPrefixes(ctx android.ModuleContext) {
+	mod := ctx.Module()
+	// Explicitly avoid propagating into some module types.
+	switch reflect.TypeOf(mod).String() {
+	case "*java.Droidstubs":
+		return
+	}
+	jarJarData := collectDirectDepsProviders(ctx)
+	if jarJarData != nil {
+		providerData := BaseJarJarProviderData{
+			JarJarProviderData: *jarJarData,
+		}
+		android.SetProvider(ctx, BaseJarJarProvider, providerData)
+	}
+
+}
+
+// Add a jarjar renaming rule to this module, to be inherited to all dependent modules.
+func (module *Module) addJarJarRenameRule(original string, renamed string) {
+	if module.jarjarRenameRules == nil {
+		module.jarjarRenameRules = make(map[string]string)
+	}
+	module.jarjarRenameRules[original] = renamed
+}
+
+func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProviderData) {
+	// Gather repackage information from deps
+	// If the dep jas a JarJarProvider, it is used.  Otherwise, any BaseJarJarProvider is used.
+	ctx.VisitDirectDepsIgnoreBlueprint(func(m android.Module) {
+		merge := func(theirs *JarJarProviderData) {
+			for orig, renamed := range theirs.Rename {
+				if result == nil {
+					result = &JarJarProviderData{
+						Rename: make(map[string]string),
+					}
+				}
+				if preexisting, exists := (*result).Rename[orig]; !exists || preexisting == "" {
+					result.Rename[orig] = renamed
+				} else if preexisting != "" && renamed != "" && preexisting != renamed {
+					if strings.HasPrefix(preexisting, overridableJarJarPrefix) {
+						result.Rename[orig] = renamed
+					} else if !strings.HasPrefix(renamed, overridableJarJarPrefix) {
+						ctx.ModuleErrorf("1. Conflicting jarjar rules inherited for class: %s (%s and %s)", orig, renamed, preexisting, ctx.ModuleName(), m.Name())
+						continue
+					}
+				}
+			}
+		}
+		if theirs, ok := android.OtherModuleProvider(ctx, m, JarJarProvider); ok {
+			merge(&theirs)
+		} else if theirs, ok := android.OtherModuleProvider(ctx, m, BaseJarJarProvider); ok {
+			// TODO: if every java.Module should have a JarJarProvider, and we find only the
+			// BaseJarJarProvider, then there is a bug.  Consider seeing if m can be cast
+			// to java.Module.
+			merge(&theirs.JarJarProviderData)
+		}
+	})
+	return
+}
+
+func (this Module) GetDebugString() string {
+	return "sdk_version=" + proptools.String(this.deviceProperties.Sdk_version)
+}
+
+// Merge the jarjar rules we inherit from our dependencies, any that have been added directly to
+// us, and if it's been set, apply the jarjar_prefix property to rename them.
+func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProviderData {
+	// Gather repackage information from deps
+	result := collectDirectDepsProviders(ctx)
+
+	// Update that with entries we've stored for ourself
+	for orig, renamed := range module.jarjarRenameRules {
+		if result == nil {
+			result = &JarJarProviderData{
+				Rename: make(map[string]string),
+			}
+		}
+		if renamed != "" {
+			if preexisting, exists := (*result).Rename[orig]; exists && preexisting != renamed {
+				ctx.ModuleErrorf("Conflicting jarjar rules inherited for class: %s (%s and %s)", orig, renamed, preexisting)
+				continue
+			}
+		}
+		(*result).Rename[orig] = renamed
+	}
+
+	// If there are no renamings, then jarjar_prefix does nothing, so skip the extra work.
+	if result == nil {
+		return nil
+	}
+
+	// If they've given us a jarjar_prefix property, then we will use that to rename any classes
+	// that have not yet been renamed.
+	prefix := proptools.String(module.properties.Jarjar_prefix)
+	if prefix != "" {
+		if prefix[0] == '.' {
+			ctx.PropertyErrorf("jarjar_prefix", "jarjar_prefix can not start with '.'")
+			return nil
+		}
+		if prefix[len(prefix)-1] == '.' {
+			ctx.PropertyErrorf("jarjar_prefix", "jarjar_prefix can not end with '.'")
+			return nil
+		}
+
+		var updated map[string]string
+		for orig, renamed := range (*result).Rename {
+			if renamed == "" {
+				if updated == nil {
+					updated = make(map[string]string)
+				}
+				updated[orig] = prefix + "." + orig
+			}
+		}
+		for orig, renamed := range updated {
+			(*result).Rename[orig] = renamed
+		}
+	}
+
+	return result
+}
+
+// Get the jarjar rule text for a given provider for the fully resolved rules. Classes that map
+// to "" won't be in this list because they shouldn't be renamed yet.
+func getJarJarRuleText(provider *JarJarProviderData) string {
+	result := ""
+	for orig, renamed := range provider.Rename {
+		if renamed != "" {
+			result += "rule " + orig + " " + renamed + "\n"
+		}
+	}
+	return result
+}
+
 func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) {
 	deps.processorPath = append(deps.processorPath, pluginJars...)
 	deps.processorClasses = append(deps.processorClasses, pluginClasses...)
