Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
060ffd3
NativeAOT Android test working locally
jtschuster Jul 21, 2025
a3d30c1
Undo extra changes, add reference in tests.proj
jtschuster Jul 24, 2025
ae6a9ce
Remove emtpy 'if' case
jtschuster Jul 24, 2025
5797ccc
Merge branch 'main' of https://github.com/dotnet/runtime into Android…
jtschuster Jul 24, 2025
68b972a
Remove extra android->linux translations
jtschuster Jul 24, 2025
044b176
Remove redundant IsNativeAOT check
jtschuster Jul 25, 2025
d74d3ec
Fix build to work in CI
jtschuster Jul 28, 2025
ce32f11
Merge branch 'main' of https://github.com/dotnet/runtime into Android…
jtschuster Jul 28, 2025
87a4cca
Fix apkbuilder.cs errors after merge
jtschuster Jul 28, 2025
8de0a57
Undo deleted line in ILC.targets, build libs.tests in pipeline
jtschuster Jul 28, 2025
36dfe61
Add missing args to build command
jtschuster Jul 28, 2025
152ec03
Set CppCompilerAndLinker to NDK clang when targeting android
jtschuster Jul 28, 2025
0facf06
Ensure Android build runs after CopyNativeBinary
jtschuster Jul 28, 2025
407b4db
Merge branch 'main' into AndroidAppBuilderNaot
jtschuster Jul 28, 2025
5e7feaa
Test CI in Debug config
jtschuster Jul 30, 2025
56553a7
Merge branch 'main' into AndroidAppBuilderNaot
jtschuster Jul 30, 2025
3c86a91
Move leg to runtime-extra-platforms
jtschuster Jul 30, 2025
28600f9
Merge branch 'AndroidAppBuilderNaot' of https://github.com/jtschuster…
jtschuster Jul 30, 2025
05deb8f
Remove jobs from runtime
jtschuster Jul 30, 2025
248dddd
Exclude nativeaot test on non-nativeaot builds
jtschuster Jul 30, 2025
54b995d
Add thread.inl to interoplibinterface_java.cpp to fix loadLibrary fai…
jtschuster Jul 31, 2025
b7e58a1
Remove android rids from targetpack rids
jtschuster Jul 31, 2025
7e98286
Run release build in CI
jtschuster Jul 31, 2025
972719a
Use AppBundle as AndroidBundleDir as Helix expects
jtschuster Jul 31, 2025
d8ac52a
Merge branch 'main' into AndroidAppBuilderNaot
jtschuster Jul 31, 2025
0e306b2
Tighten OutputType condition in singlefile test targets
jtschuster Jul 31, 2025
2b93e83
Add job to runtime-extra-platforms-androidemulator.yml
jtschuster Aug 4, 2025
7137d36
Update CrossCompileAbi condition
jtschuster Aug 4, 2025
fcbbd79
Merge branch 'AndroidAppBuilderNaot' of https://github.com/jtschuster…
jtschuster Aug 4, 2025
acdb04b
Add Collections tests project to android nativeaot test list
jtschuster Aug 4, 2025
4e91c92
Use UseNativeAOTRuntime property to test if using nativeaot instead o…
jtschuster Aug 4, 2025
36f02b8
DirectPInvoke and DirectPInvokeList is not plural in naot
jtschuster Aug 4, 2025
aaaa078
Add args to main, don't run all coreclr test projects on nativeaot an…
jtschuster Aug 5, 2025
377e8e5
Working Crypto tests
jtschuster Aug 11, 2025
e7a7fed
Merge branch 'main' of https://github.com/dotnet/runtime into Android…
jtschuster Aug 11, 2025
30eda43
Fix tests after merge
jtschuster Aug 11, 2025
b112dc1
Add Globalization and Interop tests for NAOT on Android
jtschuster Aug 11, 2025
9722757
Remove extraneous changes
jtschuster Aug 11, 2025
b7af561
Use xunit-excludes file for -notrait args
jtschuster Aug 12, 2025
b3ef5b1
Remove System.IO.Ports.Native from NetCoreAppNativeLibrary
jtschuster Aug 12, 2025
a02ba75
Condition OpenSsl test on IsOpenSslSupported
jtschuster Aug 13, 2025
9133298
Merge branch 'main' into AndroidCollectionsTests
jtschuster Aug 15, 2025
32e83f6
Merge branch 'main' into AndroidCollectionsTests
jtschuster Aug 20, 2025
dfe5d3e
Merge branch 'main' into AndroidCollectionsTests
jtschuster Sep 2, 2025
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
13 changes: 11 additions & 2 deletions eng/testing/tests.android.targets
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@
<BundleTestAndroidAppDependsOn>AndroidBuild</BundleTestAndroidAppDependsOn>
</PropertyGroup>

<PropertyGroup Condition="'$(RuntimeFlavor)' == 'CoreCLR'">
<PropertyGroup Condition="'$(RuntimeFlavor)' == 'CoreCLR' and '$(IsFunctionalTest)' != 'true'">
<DefineConstants>$(DefineConstants);SINGLE_FILE_TEST_RUNNER</DefineConstants>
</PropertyGroup>

<ItemGroup Condition="'$(TestNativeAOT)' == 'true'">
<Compile Include="$(RepoTasksDir)AndroidAppBuilder\Templates\monodroid-nativeaot.cs" />
</ItemGroup>
<PropertyGroup Condition="'$(TestNativeAOT)' == 'true'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<_UseNativeLibPrefix>true</_UseNativeLibPrefix>
</PropertyGroup>

<!-- Target that kicks off the whole test build and run flow -->
<Target Name="BundleTestAndroidApp" DependsOnTargets="$(BundleTestAndroidAppDependsOn)" />

Expand All @@ -25,7 +33,8 @@
<WriteLinesToFile File="$(PublishDir)xunit-excludes.txt" Lines="$(XunitExcludesTxtFileContent)" Overwrite="true" />

<PropertyGroup>
<MainLibraryFileName Condition="'$(MainLibraryFileName)' == ''">AndroidTestRunner.dll</MainLibraryFileName>
<MainLibraryFileName Condition="'$(MainLibraryFileName)' == '' and '$(TestNativeAOT)' != 'true'">AndroidTestRunner.dll</MainLibraryFileName>
<MainLibraryFileName Condition="'$(MainLibraryFileName)' == '' and '$(TestNativeAOT)' == 'true'">lib$(TargetName).so</MainLibraryFileName>

<AndroidBuildDir>$(PublishDir)</AndroidBuildDir>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion eng/testing/tests.mobile.targets
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<!-- OutDir is not set early enough to set this property in .props file. -->
<BundleDir>$([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle'))</BundleDir>
<BundleDir Condition="'$(BundleDir)' == ''">$([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle'))</BundleDir>
<PublishDir Condition="'$(UseAppBundleRootForBuildingTests)' == 'true' and '$(IgnoreForCI)' != 'true' and '$(IsFunctionalTest)' != 'true'">$(AppBundleRoot)tests\$(AssemblyName)</PublishDir>
<PublishDir Condition="'$(UseAppBundleRootForBuildingTests)' == 'true' and '$(IgnoreForCI)' != 'true' and '$(IsFunctionalTest)' == 'true'">$(AppBundleRoot)runonly\$(AssemblyName)</PublishDir>
<BundleDir Condition="'$(UseAppBundleRootForBuildingTests)' == 'true' and '$(IgnoreForCI)' != 'true'">$([MSBuild]::NormalizeDirectory('$(PublishDir)', 'AppBundle'))</BundleDir>
Expand Down
2 changes: 1 addition & 1 deletion eng/testing/tests.singlefile.targets
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<SelfContained>true</SelfContained>
</PropertyGroup>

<PropertyGroup Condition="'$(PublishSingleFile)' == 'true' or '$(TestNativeAot)' == 'true'">
<PropertyGroup Condition="('$(PublishSingleFile)' == 'true' or '$(TestNativeAot)' == 'true') and '$(IsFunctionalTest)' != 'true'">
<DefineConstants>$(DefineConstants);SINGLE_FILE_TEST_RUNNER</DefineConstants>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Formats.Asn1;
using System.Linq;
using Microsoft.DotNet.RemoteExecutor;
using Microsoft.DotNet.XUnitExtensions;
using Xunit;
using Xunit.Sdk;

Expand Down Expand Up @@ -60,6 +61,7 @@ public static void ImportBadPrivateKey_ShortTradKey(CompositeMLDsaAlgorithm algo
}

[Theory]
[SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void ImportBadPrivateKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
Expand Down Expand Up @@ -311,6 +313,7 @@ public static void ImportBadPublicKey_ShortTradKey(CompositeMLDsaAlgorithm algor
}

[Theory]
[SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void ImportBadPublicKey_TrailingData(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
Expand All @@ -321,6 +324,7 @@ public static void ImportBadPublicKey_TrailingData(CompositeMLDsaTestData.Compos
}

[Theory]
[SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedECDsaAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void ImportBadPublicKey_ECDsa_Uncompressed(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
Expand Down Expand Up @@ -419,6 +423,7 @@ public static void AlgorithmMatches_GenerateKey(CompositeMLDsaAlgorithm algorith
}

[Theory]
[SkipOnPlatform(TestPlatforms.Android, "Not supported on Android")]
[MemberData(nameof(CompositeMLDsaTestData.SupportedAlgorithmIetfVectorsTestData), MemberType = typeof(CompositeMLDsaTestData))]
public static void AlgorithmMatches_Import(CompositeMLDsaTestData.CompositeMLDsaTestVector vector)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ public static bool IsMetadataTokenSupported
public static bool IsDomainJoinedMachine => !Environment.MachineName.Equals(Environment.UserDomainName, StringComparison.OrdinalIgnoreCase);
public static bool IsNotDomainJoinedMachine => !IsDomainJoinedMachine;

public static bool IsOpenSslSupported => IsLinux || IsFreeBSD || Isillumos || IsSolaris;
public static bool IsOpenSslSupported => (IsLinux && !IsAndroid) || IsFreeBSD || Isillumos || IsSolaris;
public static bool OpenSslNotPresentOnSystem => !OpenSslPresentOnSystem;

public static bool UsesAppleCrypto => IsOSX || IsMacCatalyst || IsiOS || IstvOS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ internal static partial class Interop
{
internal static partial class AndroidCrypto
{
[DllImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_EcKeyCreateByOid")]
internal static extern System.IntPtr EcKeyCreateByOid(string oid);
[LibraryImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_EcKeyCreateByOid", StringMarshalling = StringMarshalling.Utf8)]
internal static partial System.IntPtr EcKeyCreateByOid(string oid);

[DllImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_EcKeyDestroy")]
internal static extern void EcKeyDestroy(System.IntPtr r);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public static void Pbkdf2_Rfc6070(string password, string salt, int iterations,
Assert.Equal(expected, actual);
}

[Theory]
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsOpenSslSupported))]
[MemberData(nameof(Pbkdf2_OpenSsl_Vectors))]
public static void Pbkdf2_OpenSsl(string hashAlgorithm, string password, string salt, int iterations, string expectedHex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ public static void BuildWithEmptyHashAlgorithm(CertKind certKind)

[Theory]
[MemberData(nameof(NoHashAlgorithmCertKinds))]
[SkipOnPlatform(TestPlatforms.Android, "No algorithms are supported")]
public static void BuildPqcWithHashAlgorithm(CertKind certKind)
{
BuildCertificateAndRun(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace System.Security.Cryptography.X509Certificates.Tests
{
internal static class TestFiles
{
internal const string TestDataFolder = "TestData";
internal static readonly string? TestDataRoot = Environment.GetEnvironmentVariable("ASSETS_DIR") ?? AppContext.BaseDirectory;
internal static readonly string TestDataFolder = Path.Combine(TestDataRoot, "TestData");

// Certs
internal static readonly string MsCertificateDerFile = Path.Combine(TestDataFolder, "MS.cer");
Expand Down
3 changes: 3 additions & 0 deletions src/libraries/tests.proj
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,9 @@

<ItemGroup Condition="'$(TargetOS)' == 'android' and '$(TestNativeAOT)' == 'true'">
<SmokeTestProject Include="$(RepoRoot)src\tests\FunctionalTests\Android\Device_Emulator\NativeAOT\*.Test.csproj"/>
<SmokeTestProject Include="$(MSBuildThisFileDirectory)System.Runtime\tests\System.Globalization.Tests\System.Globalization.Tests.csproj" />
<SmokeTestProject Include="$(MSBuildThisFileDirectory)System.Security.Cryptography\tests\System.Security.Cryptography.Tests.csproj" />
<SmokeTestProject Include="$(MSBuildThisFileDirectory)System.Runtime.InteropServices\tests\System.Runtime.InteropServices.UnitTests\System.Runtime.InteropServices.Tests.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
7 changes: 4 additions & 3 deletions src/mono/msbuild/android/build/AndroidBuild.props
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<CppCompilerAndLinker>$(ANDROID_NDK_ROOT)\toolchains\llvm\prebuilt\$(NdkToolchainPrebuiltOS)\bin\clang</CppCompilerAndLinker>

<AndroidBuildAfterThisTarget Condition="'$(AndroidBuildAfterThisTarget)' == ''">Publish</AndroidBuildAfterThisTarget>

<AndroidBuildDependsOn Condition="'$(UseMonoRuntime)' == 'true'">
$(_ReadRuntimeComponentsManifestTargetName);
_InitializeCommonProperties;
Expand All @@ -42,9 +43,9 @@
_AfterAndroidBuild
</AndroidBuildDependsOn>
<AndroidBuildDependsOn Condition="'$(UseNativeAOTRuntime)' == 'true'">
$(AndroidBuildDependsOn);
CopyNativeBinary;
_CopyAotSymbols
CopyNativeBinary;
_CopyAotSymbols;
$(AndroidBuildDependsOn)
</AndroidBuildDependsOn>

<!-- When building on Helix $(_CommonTargetsDir) will be properly set, otherwise we have to set it to a in-tree location -->
Expand Down
1 change: 1 addition & 0 deletions src/tasks/AndroidAppBuilder/Templates/MonoRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public static void initializeRuntime(String entryPointLibName, Context context)

// set environment variables
setEnv("HOME", filesDir);
setEnv("ASSETS_DIR", filesDir);
setEnv("TMPDIR", cacheDir);
setEnv("TEST_RESULTS_DIR", testResultsDir);

Expand Down
53 changes: 47 additions & 6 deletions src/tasks/AndroidAppBuilder/Templates/monodroid-nativeaot.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;
using System.Runtime;
using System;
using System.IO;
using System.Linq;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

using JObject = nint;
using JString = nint;
using JObjectArray = nint;
using JSize = int;

namespace MonoDroid.NativeAOT;

Expand All @@ -21,14 +24,18 @@ public static void SetEnv(JNIEnv* env, JObject thiz, JString j_key, JString j_va
{
string? key = env->GetStringUTFChars(j_key);
string? value = env->GetStringUTFChars(j_value);
Console.WriteLine($"SetEnv: {key ?? "null"} = {value ?? "null"}");
if (key != null && value != null)
{
Environment.SetEnvironmentVariable(key, value);
}
}

// int Java_net_dot_MonoRunner_initRuntime (JNIEnv* env, jobject thiz, jstring j_files_dir, jstring j_entryPointLibName, long current_local_time);
[UnmanagedCallersOnly(EntryPoint = "Java_net_dot_MonoRunner_initRuntime", CallConvs = [typeof(CallConvCdecl)])]
public static int InitRuntime(JNIEnv* env, JObject thiz, JString j_files_dir, JString j_entryPointLibName, long current_local_time)
{
Console.WriteLine("Initializing Android crypto native library");
// The NativeAOT runtime does not need to be initialized, but the crypto library does.
JavaVM* javaVM = env->GetJavaVM();
AndroidCryptoNative_InitLibraryOnLoad(javaVM, null);
Expand All @@ -42,7 +49,26 @@ public static int InitRuntime(JNIEnv* env, JObject thiz, JString j_files_dir, JS
[UnmanagedCallersOnly(EntryPoint = "Java_net_dot_MonoRunner_execEntryPoint", CallConvs = [typeof(CallConvCdecl)])]
public static int ExecEntryPoint(JNIEnv* env, JObject thiz, JString j_entryPointLibName, JObjectArray j_args)
{
return Program.Main();
int argc = env->GetArrayLength(j_args);
string[] args = new string[argc];
for (int i = 0; i < argc; i++)
{
JObject j_arg = env->GetObjectArrayElement(j_args, i);
args[i] = env->GetStringUTFChars((JString)j_arg);
}

#if SINGLE_FILE_TEST_RUNNER
string excludesFile = Path.Combine(Environment.GetEnvironmentVariable("HOME"), "xunit-excludes.txt");
if (File.Exists(excludesFile))
{
args = args.Concat(File.ReadAllLines(excludesFile).SelectMany(trait => new string[]{"-notrait", trait})).ToArray();
}
// SingleFile unit tests
return SingleFileTestRunner.Main(args);
#else
// Functional tests
return Program.Main(args);
#endif
}

// void Java_net_dot_MonoRunner_freeNativeResources (JNIEnv* env, jobject thiz);
Expand Down Expand Up @@ -88,6 +114,22 @@ internal unsafe struct JNIEnv
}
}

public JSize GetArrayLength(JObjectArray array)
{
fixed (JNIEnv* thisptr = &this)
{
return NativeInterface->GetArrayLength(thisptr, array);
}
}

public JObject GetObjectArrayElement(JObjectArray array, JSize index)
{
fixed (JNIEnv* thisptr = &this)
{
return NativeInterface->GetObjectArrayElement(thisptr, array, index);
}
}

[StructLayout(LayoutKind.Sequential)]
unsafe struct JNINativeInterface
{
Expand Down Expand Up @@ -312,11 +354,10 @@ unsafe struct JNINativeInterface
delegate* unmanaged[Cdecl]<JNIEnv*, JString, int> GetStringUTFLength;
public delegate* unmanaged[Cdecl]<JNIEnv*, JString, out byte, byte*> GetStringUTFChars;
public delegate* unmanaged[Cdecl]<JNIEnv*, JString, byte*, void> ReleaseStringUTFChars;

void* GetArrayLength;
public delegate* unmanaged[Cdecl]<JNIEnv*, JObjectArray, JSize> GetArrayLength;

void* NewObjectArray;
void* GetObjectArrayElement;
public delegate* unmanaged[Cdecl]<JNIEnv*, JObjectArray, JSize, JObject> GetObjectArrayElement;
void* SetObjectArrayElement;

void* NewBooleanArray;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

public class Program
{
public static int Main()
public static int Main(string[] args)
{
Console.WriteLine("Hello, Android!"); // logcat
return 42;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,12 @@
<OutputType>Library</OutputType>
<TestRuntime>true</TestRuntime>
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<TargetName>lib$(MSBuildProjectName)</TargetName>
<MainLibraryFileName>$(TargetName).so</MainLibraryFileName>
<ExpectedExitCode>42</ExpectedExitCode>
<UseNativeAOTRuntime>true</UseNativeAOTRuntime>
<PublishAOT>true</PublishAOT>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\..\..\..\..\tasks\AndroidAppBuilder\Templates\monodroid-nativeaot.cs" />
<DirectPInvoke Include="System.Security.Cryptography.Native.Android" />
</ItemGroup>

<ItemGroup>
<Compile Include="Program.cs" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

public class Program
{
public static int Main()
public static int Main(string[] args)
{
string message = "Hello, Android!";
Console.WriteLine(message); // logcat
Expand Down
Loading