diff --git a/Documentation/docs-mobile/building-apps/build-properties.md b/Documentation/docs-mobile/building-apps/build-properties.md
index 11d6036471b..faf7be24058 100644
--- a/Documentation/docs-mobile/building-apps/build-properties.md
+++ b/Documentation/docs-mobile/building-apps/build-properties.md
@@ -465,6 +465,17 @@ removing the existing one(s) and adding your own AOT profiles.
This property is `False` by default.
+## AndroidEnableR8JniNameObfuscation
+
+A boolean property that enables R8 obfuscation of Java type, method, and field names
+referenced by managed JNI metadata. The build uses an R8-generated mapping to rewrite
+managed assemblies before trimming or NativeAOT compilation, then applies the same
+mapping during the final R8 invocation.
+
+This property requires `AndroidLinkTool=r8`,
+`AndroidTypeMapImplementation=trimmable`, and either NativeAOT or CoreCLR with
+`PublishTrimmed=true`.
+The default value is `False`.
## AndroidEnableRestrictToAttributes
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets
index b12f80fdc8f..adf0089ffee 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets
@@ -5,10 +5,11 @@
<_TrimmableRuntimeProviderJavaName Condition=" '$(_TrimmableRuntimeProviderJavaName)' == '' ">mono.MonoRuntimeProvider
+ <_CompileToDalvikDependsOnTargets>$(_CompileToDalvikDependsOnTargets);_GenerateProguardConfiguration
- <_GenerateProguardAfterTargets Condition=" '$(_GenerateProguardAfterTargets)' == '' ">ILLink
+ <_GenerateProguardAfterTargets Condition=" '$(_GenerateProguardAfterTargets)' == '' ">_RunILLink
@@ -23,6 +24,57 @@
+
+
+ <_AndroidR8JniRewrittenAssemblyDirectory>$(IntermediateOutputPath)r8-jni-rewritten/
+ <_AndroidR8JniRewriteStamp>$(_AndroidStampDirectory)_AndroidRewriteJniNamesBeforeILLink.stamp
+
+
+ <_AndroidR8JniOriginalManagedAssembly Remove="@(_AndroidR8JniOriginalManagedAssembly)" />
+ <_AndroidR8JniHashedManagedAssembly Remove="@(_AndroidR8JniHashedManagedAssembly)" />
+ <_AndroidR8JniRewrittenManagedAssembly Remove="@(_AndroidR8JniRewrittenManagedAssembly)" />
+ <_AndroidR8JniExpectedRewriteOutput Remove="@(_AndroidR8JniExpectedRewriteOutput)" />
+ <_AndroidR8JniMissingRewriteOutput Remove="@(_AndroidR8JniMissingRewriteOutput)" />
+ <_AndroidR8JniOriginalManagedAssembly Include="@(ManagedAssemblyToLink)" />
+
+
+
+
+
+ <_AndroidR8JniRewrittenManagedAssembly Include="@(_AndroidR8JniHashedManagedAssembly->'$(_AndroidR8JniRewrittenAssemblyDirectory)%(Hash)/%(Filename)%(Extension)')" />
+ <_AndroidR8JniExpectedRewriteOutput Include="@(_AndroidR8JniRewrittenManagedAssembly);$(_AndroidR8JniRewriteManifest)" />
+ <_AndroidR8JniMissingRewriteOutput Include="@(_AndroidR8JniExpectedRewriteOutput)" Condition="!Exists('%(Identity)')" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_AndroidR8JniExpectedRewriteOutput Remove="@(_AndroidR8JniExpectedRewriteOutput)" />
+ <_AndroidR8JniMissingRewriteOutput Remove="@(_AndroidR8JniMissingRewriteOutput)" />
+
+
+
+ Inputs="@(_LinkedAssemblyForProguard);$(_AndroidR8JniSeedMapping);$(_AndroidR8JniRewriteManifest)"
+ Outputs="$(_ProguardProjectConfiguration);$(_AndroidR8JniReachabilityManifest)">
+ OutputFile="$(_ProguardProjectConfiguration)"
+ R8MappingFile="$(_AndroidR8JniSeedMapping)"
+ R8RewriteManifestFile="$(_AndroidR8JniRewriteManifest)"
+ R8ReachabilityManifestFile="$(_AndroidR8JniReachabilityManifest)" />
+
+
+
false
<_TrimmableRuntimeProviderJavaName Condition=" '$(_TrimmableRuntimeProviderJavaName)' == '' ">net.dot.jni.nativeaot.NativeAotRuntimeProvider
- r8
d8
True
True
@@ -73,6 +72,64 @@
+
+
+ <_AndroidR8JniRewrittenAssemblyDirectory>$(IntermediateOutputPath)r8-jni-rewritten/
+ <_AndroidR8JniRewriteStamp>$(_AndroidStampDirectory)_AndroidRewriteJniNamesBeforeIlc.stamp
+
+
+ <_AndroidR8JniIlcAssembly Remove="@(_AndroidR8JniIlcAssembly)" />
+ <_AndroidR8JniHashedIlcAssembly Remove="@(_AndroidR8JniHashedIlcAssembly)" />
+ <_AndroidR8JniRewrittenIlcAssembly Remove="@(_AndroidR8JniRewrittenIlcAssembly)" />
+ <_AndroidR8JniExpectedRewriteOutput Remove="@(_AndroidR8JniExpectedRewriteOutput)" />
+ <_AndroidR8JniMissingRewriteOutput Remove="@(_AndroidR8JniMissingRewriteOutput)" />
+ <_AndroidR8JniIlcAssembly Include="@(ManagedBinary)">
+ ManagedBinary
+
+ <_AndroidR8JniIlcAssembly Include="@(IlcReference)">
+ IlcReference
+
+ <_AndroidR8JniIlcAssembly Remove="@(_AndroidR8JniIlcAssembly)" Condition=" '%(Extension)' != '.dll' " />
+
+
+
+
+
+ <_AndroidR8JniRewrittenIlcAssembly Include="@(_AndroidR8JniHashedIlcAssembly->'$(_AndroidR8JniRewrittenAssemblyDirectory)%(Hash)/%(Filename)%(Extension)')" />
+ <_AndroidR8JniExpectedRewriteOutput Include="@(_AndroidR8JniRewrittenIlcAssembly);$(_AndroidR8JniRewriteManifest)" />
+ <_AndroidR8JniMissingRewriteOutput Include="@(_AndroidR8JniExpectedRewriteOutput)" Condition="!Exists('%(Identity)')" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_AndroidR8JniExpectedRewriteOutput Remove="@(_AndroidR8JniExpectedRewriteOutput)" />
+ <_AndroidR8JniMissingRewriteOutput Remove="@(_AndroidR8JniMissingRewriteOutput)" />
+
+
+
- <_PreTrimTypeMapAcwMapOutputFile Condition=" '$(_AndroidRuntime)' != 'CoreCLR' or '$(PublishTrimmed)' != 'true' ">$(IntermediateOutputPath)acw-map.txt
- <_PreTrimTypeMapApplicationRegistrationOutputFile Condition=" '$(_AndroidRuntime)' != 'CoreCLR' or '$(PublishTrimmed)' != 'true' ">$(IntermediateOutputPath)android/src/net/dot/android/ApplicationRegistration.java
+ <_PreTrimTypeMapAcwMapOutputFile Condition=" '$(_AndroidEnableR8JniNameRewriting)' == 'true' ">$(_AndroidR8JniSeedAcwMap)
+ <_PreTrimTypeMapApplicationRegistrationOutputFile Condition=" '$(_AndroidEnableR8JniNameRewriting)' == 'true' ">$(_AndroidR8JniSeedApplicationRegistration)
+ <_PreTrimTypeMapAcwMapOutputFile Condition=" '$(_PreTrimTypeMapAcwMapOutputFile)' == '' and ('$(_AndroidRuntime)' != 'CoreCLR' or '$(PublishTrimmed)' != 'true') ">$(IntermediateOutputPath)acw-map.txt
+ <_PreTrimTypeMapApplicationRegistrationOutputFile Condition=" '$(_PreTrimTypeMapApplicationRegistrationOutputFile)' == '' and ('$(_AndroidRuntime)' != 'CoreCLR' or '$(PublishTrimmed)' != 'true') ">$(IntermediateOutputPath)android/src/net/dot/android/ApplicationRegistration.java
<_TrimmableTypeMapOutputStamp>$(_TypeMapOutputDirectory)_GenerateTrimmableTypeMap.stamp
+ <_AndroidR8JniSeedMapping Condition=" '$(_AndroidEnableR8JniNameRewriting)' == 'true' ">$(_AndroidR8JniSeedDirectory)mapping.txt
+ <_AndroidR8JniRewriteManifest Condition=" '$(_AndroidEnableR8JniNameRewriting)' == 'true' ">$(_AndroidR8JniManifestBaseOutputDir)r8-jni-rewrite-manifest.txt
+ <_AndroidR8JniReachabilityManifest Condition=" '$(_AndroidEnableR8JniNameRewriting)' == 'true' ">$(_AndroidR8JniManifestBaseOutputDir)r8-jni-reachability-manifest.txt
+ <_AndroidR8JniSeedApplicationConfiguration Condition=" '$(_AndroidEnableR8JniNameRewriting)' == 'true' ">$(_AndroidR8JniSeedDirectory)acw-keep.cfg
+ <_AndroidR8JniSeedXamarinConfiguration Condition=" '$(_AndroidEnableR8JniNameRewriting)' == 'true' ">$(_AndroidR8JniSeedDirectory)xamarin.cfg
+ <_AndroidR8JniSeedJavaClassDirectory Condition=" '$(_AndroidEnableR8JniNameRewriting)' == 'true' ">$(_AndroidR8JniSeedDirectory)classes/
+ <_AndroidR8JniSeedJavaStamp Condition=" '$(_AndroidEnableR8JniNameRewriting)' == 'true' ">$(_AndroidR8JniSeedDirectory)compile-java.stamp
<_TrimmableRemoveRegisterFlag>$(_AndroidStampDirectory)_RemoveRegisterAttribute.stamp
<_TrimmableRemoveRegisterTarget Condition=" '$(_AndroidRuntime)' == 'CoreCLR' ">_RemoveRegisterAttributeCoreClr
<_TrimmableRemoveRegisterTarget Condition=" '$(_AndroidRuntime)' == 'NativeAOT' ">_RemoveRegisterAttributeNativeAot
@@ -54,6 +73,7 @@
Both are touched only when their producing target actually runs, so _GenerateJavaStubs
stays incremental while still reacting to post-trim JCW regeneration. -->
<_TrimmableJavaSourceStamp Condition=" '$(_TrimmableJavaSourceStamp)' == '' and '$(_AndroidRuntime)' == 'CoreCLR' and '$(PublishTrimmed)' == 'true' ">$(_PostTrimTrimmableTypeMapJavaStamp)
+ <_TrimmableJavaSourceStamp Condition=" '$(_AndroidEnableR8JniNameRewriting)' == 'true' ">$(_TrimmableTypeMapOutputStamp)
<_TrimmableJavaSourceStamp Condition=" '$(_TrimmableJavaSourceStamp)' == '' ">$(_TrimmableTypeMapOutputStamp)
@@ -67,6 +87,120 @@
+
+
+ <_AndroidR8JniSeedJavaSource Include="$(_TypeMapJavaOutputDirectory)/**/*.java" />
+ <_AndroidR8JniSeedJavaSource Include="$(_AndroidR8JniSeedApplicationRegistration)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_AndroidR8JniSeedClassFile Include="$(_AndroidR8JniSeedJavaClassDirectory)**\*.class" />
+ <_AndroidR8JniSeedProguardConfiguration Include="@(_ProguardConfiguration)" />
+ <_AndroidR8JniSeedProguardConfiguration Remove="$(IntermediateOutputPath)proguard\proguard_xamarin.cfg;$(_ProguardProjectConfiguration);$(IntermediateOutputPath)proguard\proguard_project_primary.cfg;$(IntermediateOutputPath)aapt_rules.txt" />
+ <_AndroidR8JniSeedMapDiagnostics Condition=" '$(AndroidR8IgnoreWarnings)' == 'true' " Include="warning" To="info" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+