Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/Mono.Android/Android.Runtime/JNIEnvInit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,7 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args)

args->propagateUncaughtExceptionFn = (IntPtr)(delegate* unmanaged<IntPtr, IntPtr, IntPtr, void>)&PropagateUncaughtException;

if (!RuntimeFeature.TrimmableTypeMap) {
args->registerJniNativesFn = (IntPtr)(delegate* unmanaged<IntPtr, int, IntPtr, IntPtr, int, void>)&RegisterJniNatives;
}
args->registerJniNativesFn = (IntPtr)(delegate* unmanaged<IntPtr, int, IntPtr, IntPtr, int, void>)&RegisterJniNatives;
RunStartupHooksIfNeeded ();
SetSynchronizationContext ();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
<_TypeMapBaseOutputDir>$(IntermediateOutputPath)</_TypeMapBaseOutputDir>
<_TypeMapBaseOutputDir>$(_TypeMapBaseOutputDir.Replace('\','/'))</_TypeMapBaseOutputDir>
<_TypeMapOutputDirectory>$(_TypeMapBaseOutputDir)typemap/</_TypeMapOutputDirectory>
<_TypeMapJavaOutputDirectory>$(_TypeMapBaseOutputDir)typemap/java</_TypeMapJavaOutputDirectory>
</PropertyGroup>

<ItemGroup>
Expand Down Expand Up @@ -55,7 +54,7 @@
<GenerateTrimmableTypeMap
ResolvedAssemblies="@(_TypeMapInputAssemblies)"
OutputDirectory="$(_TypeMapOutputDirectory)"
JavaSourceOutputDirectory="$(_TypeMapJavaOutputDirectory)"
JavaSourceOutputDirectory="$(_AndroidIntermediateJavaSourceDirectory)"
TargetFrameworkVersion="$(TargetFrameworkVersion)"
ManifestTemplate="$(_AndroidManifestAbs)"
MergedAndroidManifestOutput="$(_TypeMapBaseOutputDir)AndroidManifest.xml"
Expand Down Expand Up @@ -99,15 +98,6 @@
Inputs="@(_GenerateJavaStubsInputs)"
Outputs="$(_AndroidStampDirectory)_GenerateJavaStubs.stamp">

<ItemGroup>
<_TypeMapJavaFiles Include="$(_TypeMapJavaOutputDirectory)/**/*.java" />
</ItemGroup>
<Copy SourceFiles="@(_TypeMapJavaFiles)" DestinationFolder="$(IntermediateOutputPath)android/src/%(RecursiveDir)" />

<ItemGroup>
<FileWrites Include="@(_TypeMapJavaFiles->'$(IntermediateOutputPath)android/src/%(RecursiveDir)%(Filename)%(Extension)')" />
</ItemGroup>

<!-- Set properties for ABI/RID used by CoreCLR _AddTrimmableTypeMapAssembliesToStore fallback -->
<PropertyGroup>
<_TypeMapFirstAbi Condition=" '$(AndroidSupportedAbis)' != '' ">$([System.String]::Copy('$(AndroidSupportedAbis)').Split(';')[0])</_TypeMapFirstAbi>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,50 @@ public void BuildAfterUpgradingNuget ([Values] AndroidRuntime runtime)
}
}

[Test]
[NonParallelizable]
public void SwitchingTypeMapImplementationTriggersClean ()
{
var proj = new XamarinAndroidApplicationProject ();
proj.SetRuntime (AndroidRuntime.CoreCLR);

using (var b = CreateApkBuilder ()) {
b.CleanupAfterSuccessfulBuild = b.CleanupOnDispose = false;
b.Verbosity = LoggerVerbosity.Detailed;

var projectDir = Path.Combine (Root, b.ProjectDirectory);
if (Directory.Exists (projectDir))
Directory.Delete (projectDir, true);

// First build with default (llvm-ir) typemap
Assert.IsTrue (b.Build (proj), "first build should have succeeded.");
string build_props = b.Output.GetIntermediaryPath ("build.props");
FileAssert.Exists (build_props, "build.props should exist after first build.");
var firstBuildProps = File.ReadAllText (build_props);
Assert.IsTrue (firstBuildProps.Contains ("_androidtypemapimplementation="),
"build.props should contain _AndroidTypeMapImplementation.");

// Second build with trimmable typemap — should trigger clean
proj.SetProperty ("_AndroidTypeMapImplementation", "trimmable");
b.Save (proj, doNotCleanupOnUpdate: true);
Assert.IsTrue (b.Build (proj), "second build (trimmable) should have succeeded.");
Assert.IsFalse (b.Output.IsTargetSkipped ("_CleanIntermediateIfNeeded"),
"Switching _AndroidTypeMapImplementation should trigger _CleanIntermediateIfNeeded.");

// Third build switching back to llvm-ir — should trigger clean again
proj.SetProperty ("_AndroidTypeMapImplementation", "llvm-ir");
b.Save (proj, doNotCleanupOnUpdate: true);
Assert.IsTrue (b.Build (proj), "third build (llvm-ir) should have succeeded.");
Assert.IsFalse (b.Output.IsTargetSkipped ("_CleanIntermediateIfNeeded"),
"Switching _AndroidTypeMapImplementation back should trigger _CleanIntermediateIfNeeded.");

// Fourth build with no changes — should NOT trigger clean
Assert.IsTrue (b.Build (proj), "fourth build (no changes) should have succeeded.");
Assert.IsTrue (b.Output.IsTargetSkipped ("_CleanIntermediateIfNeeded"),
"A build with no implementation change should skip _CleanIntermediateIfNeeded.");
}
}

[Test]
[Category ("SmokeTests")]
public void BuildInDesignTimeMode (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,7 @@ because xbuild doesn't support framework reference assemblies.
<_PropertyCacheItems Include="AndroidManifestPlaceholders=$(AndroidManifestPlaceholders)" />
<_PropertyCacheItems Include="ProjectFullPath=$(MSBuildProjectFullPath)" />
<_PropertyCacheItems Include="AndroidUseDesignerAssembly=$(AndroidUseDesignerAssembly)" />
<_PropertyCacheItems Include="_AndroidTypeMapImplementation=$(_AndroidTypeMapImplementation)" />
</ItemGroup>
<WriteLinesToFile
File="$(_AndroidBuildPropertiesCache)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ public void Generate_AcwType_HasRegisterNativesStaticBlock ()
AssertContainsLine ("mono.android.Runtime.registerNatives (MainActivity.class);\n", java);
}

[Fact]
public void Generate_AcwType_NeverCallsRuntimeRegister ()
{
var java = GenerateFixture ("my/app/MainActivity");
// Trimmable JCWs must call Runtime.registerNatives(klass) and avoid
// the legacy Runtime.register(typeName, klass, methods) path, which
// relies on reflection-based callback registration and breaks trimming.
AssertContainsLine ("mono.android.Runtime.registerNatives (MainActivity.class);\n", java);
Assert.DoesNotContain ("Runtime.register (\"", java);
}

[Fact]
public void Generate_ApplicationType_SkipsRegisterNatives ()
{
Expand Down