chore: Update to .NET 10 Preview 7#21256
Conversation
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-21256/wasm-skia-net9/index.html |
9bc2a4b to
1d48b65
Compare
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-21256/wasm-skia-net9/index.html |
1d48b65 to
6d7cf90
Compare
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-21256/wasm-skia-net9/index.html |
|
Hi @Youssef1313! We're having some trouble with Which seems to be in a generated portion of the test framework. Would you have an idea of what could cause this mismatch? Thanks!! |
6d7cf90 to
f775fa1
Compare
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-21256/wasm-skia-net9/index.html |
2cda356 to
4c01f28
Compare
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-21256/wasm-skia-net9/index.html |
1 similar comment
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-21256/wasm-skia-net9/index.html |
|
|
6b63cb1 to
f03304d
Compare
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-21256/wasm-skia-net9/index.html |
f03304d to
d7c9645
Compare
|
🤖 Your WebAssembly Skia Sample App stage site is ready! Visit it here: https://unowasmprstaging.z20.web.core.windows.net/pr-21256/wasm-skia-net9/index.html |
…droid Context: #21256 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time, we've decided to introduce a new stage to build and run these unit tests within a NativeAOT environment. Initially, though, this PR *won't* build for NativeAOT. This is to ensure that the various build artifacts are built in the expected locations. Once the non-NativeAOT build works, we'll enable it. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. TODO: * Figure out why the older and untouched `.azure-devops-tests-android-skia.yml` stage is now failing (?!). * Import various `src` changes needed to allow apps to start within a NativeAOT environment. * Enable NativeAOT builds by uncommenting the `$(SkiaPublishAot)` MSBuild property within `SamplesApp.Skia.netcoremobile.csproj`. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/
…droid Context: #21256 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time, we've decided to introduce a new stage to build and run these unit tests within a NativeAOT environment. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `DeviceTargetHelper.cs`: the current Android+NativeAOT support is built atop Linux support, to the extent that `OperatingSystem.IsLinux()` is true! Extend the platform detection logic so that the app can startup, avoiding an assertion: I NativeAotFromAndroid: App failed to initialize: Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Assert.IsTrue failed. /data/user/0/uno.platform.samplesapp.skia/files does not contain Uno Platform I NativeAotFromAndroid: at Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowAssertFailed(String, String) + 0x6e I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertContainsIdProps|32_2(StorageFolder, App.<>c__DisplayClass32_0&) + 0x16a I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xb4 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Finally, enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the `$(PublishAot)` property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL linker errors. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so Note: Do *not* make Release-config apps [Debuggable][1] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][2]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://developer.android.com/guide/topics/manifest/application-element#debug [2]: dotnet/java-interop@90ac202
…droid Context: #21256 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time, we've decided to introduce a new stage to build and run these unit tests within a NativeAOT environment. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `DeviceTargetHelper.cs`: the current Android+NativeAOT support is built atop Linux support, to the extent that `OperatingSystem.IsLinux()` is true! Extend the platform detection logic so that the app can startup, avoiding an assertion: I NativeAotFromAndroid: App failed to initialize: Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Assert.IsTrue failed. /data/user/0/uno.platform.samplesapp.skia/files does not contain Uno Platform I NativeAotFromAndroid: at Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowAssertFailed(String, String) + 0x6e I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertContainsIdProps|32_2(StorageFolder, App.<>c__DisplayClass32_0&) + 0x16a I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xb4 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Finally, enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the `$(PublishAot)` property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so Note: Do *not* make Release-config apps [Debuggable][1] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][2]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://developer.android.com/guide/topics/manifest/application-element#debug [2]: dotnet/java-interop@90ac202
…droid Context: #21256 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time, we've decided to introduce a new stage to build and run these unit tests within a NativeAOT environment. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `DeviceTargetHelper.cs`: the current Android+NativeAOT support is built atop Linux support, to the extent that `OperatingSystem.IsLinux()` is true! Extend the platform detection logic so that the app can startup, avoiding an assertion: I NativeAotFromAndroid: App failed to initialize: Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Assert.IsTrue failed. /data/user/0/uno.platform.samplesapp.skia/files does not contain Uno Platform I NativeAotFromAndroid: at Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowAssertFailed(String, String) + 0x6e I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertContainsIdProps|32_2(StorageFolder, App.<>c__DisplayClass32_0&) + 0x16a I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xb4 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Finally, enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the `$(PublishAot)` property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so Note: Do *not* make Release-config apps [Debuggable][1] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][2]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://developer.android.com/guide/topics/manifest/application-element#debug [2]: dotnet/java-interop@90ac202
…droid Context: #21256 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time, we've decided to introduce a new stage to build and run these unit tests within a NativeAOT environment. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `DeviceTargetHelper.cs`: the current Android+NativeAOT support is built atop Linux support, to the extent that `OperatingSystem.IsLinux()` is true! Extend the platform detection logic so that the app can startup, avoiding an assertion: I NativeAotFromAndroid: App failed to initialize: Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Assert.IsTrue failed. /data/user/0/uno.platform.samplesapp.skia/files does not contain Uno Platform I NativeAotFromAndroid: at Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowAssertFailed(String, String) + 0x6e I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertContainsIdProps|32_2(StorageFolder, App.<>c__DisplayClass32_0&) + 0x16a I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xb4 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Finally, enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the `$(PublishAot)` property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so Note: Do *not* make Release-config apps [Debuggable][1] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][2]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://developer.android.com/guide/topics/manifest/application-element#debug [2]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time, we've decided to introduce a new stage to build and run these unit tests within an Android+NativeAOT environment. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. Finally, .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Note: Do *not* make Release-config apps [Debuggable][2] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][3]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. Finally, .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Note: Do *not* make Release-config apps [Debuggable][2] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][3]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. Finally, .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Note: Do *not* make Release-config apps [Debuggable][2] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][3]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. Finally, .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Note: Do *not* make Release-config apps [Debuggable][2] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][3]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. Finally, .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Note: Do *not* make Release-config apps [Debuggable][2] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][3]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. Finally, .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Note: Do *not* make Release-config apps [Debuggable][2] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][3]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. Finally, .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Note: Do *not* make Release-config apps [Debuggable][2] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][3]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. Finally, .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Note: Do *not* make Release-config apps [Debuggable][2] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][3]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. Finally, .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Note: Do *not* make Release-config apps [Debuggable][2] under .NET 10 Preview 7 or earlier; you will run into [dotnet/java-interop@90ac202e][3]. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Update `UnitTestsControl.cs` to provide better error messages when tests fail in certain scenarios. Previously, many (many!) tests would fail: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 The problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist* (it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`). Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… Exclude tests which don't pass under NativeAOT. These fall into two major categories: 1. Failures that don't make sense, failing due to the above two mentioned exceptions. 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Update `UnitTestsControl.cs` to provide better error messages when tests fail in certain scenarios. Previously, many (many!) tests would fail: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 The problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist* (it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`). Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… Exclude tests which don't pass under NativeAOT. These fall into two major categories: 1. Failures that don't make sense, failing due to the above two mentioned exceptions. 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Update `UnitTestsControl.cs` to provide better error messages when tests fail in certain scenarios. Previously, many (many!) tests would fail: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 The problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist* (it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`). Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… Exclude tests which don't pass under NativeAOT. These fall into two major categories: 1. Failures that don't make sense, failing due to the above two mentioned exceptions. These are ignored via: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Update `UnitTestsControl.cs` to provide better error messages when tests fail in certain scenarios. Previously, many (many!) tests would fail: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 The problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist* (it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`). Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… Exclude tests which don't pass under NativeAOT. These fall into two major categories: 1. Failures that don't make sense, failing due to the above two mentioned exceptions. These are ignored via: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Update `UnitTestsControl.cs` to provide better error messages when tests fail in certain scenarios. Previously, many (many!) tests would fail: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 The problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist* (it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`). Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… Exclude tests which don't pass under NativeAOT. These fall into two major categories: 1. Failures that don't make sense, failing due to the above two mentioned exceptions. These are ignored via: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Exclude tests which don't pass under NativeAOT. These fall into two major categories: 1. Failures that don't make sense, failing due to `TargetParameterCountException` or `InvalidOperationException` described below. These are ignored via: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] Update `UnitTestsControl.cs` to try to work around NativeAOT "weirdness" and provide better error messages when tests fail in certain scenarios. Previously, many (many!) tests would fail with one of: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 A problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist*; it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`. Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… An intermediate form of this commit would wrap the `TargetParameterCountException` in an `InvalidOperationException`, resulting in messages such as: System.InvalidOperationException: Exception thrown while invoking Uno.UI.Tests.Windows_Globalization.Given_NumeralSystemTranslator.When_NumeralSystemIsMtei(System.String, System.String) with arguments { System.Object[]{ 1 as System.String, ꯱ as System.String } }. ---> System.Reflection.TargetParameterCountException: Parameter count mismatch. Note that `When_NumeralSystemIsMtei(System.String, System.String)` takes two arguments, but it's given *one* argument with value `{{ System.Object[]{ 1 as System.String, ꯱ as System.String } }}`, i.e. *the values are there*, just "wrapped" in an extra array. Update `UnitTestsControl.InvokeTestMethod()` to always call `ExpandArgumentsWithDefaultValues()` as part of test method invocation, so that we have a centralized place to look for such "extra array wrapping". Update `ExpandArgumentsWithDefaultValues()` so that if it encounters an array for a parameter type which isn't an array, the array is expanded as additional arguments. Additionally, if a `TargetInvocationException` is thrown when the the method arguments count and parameters count match, throw an `AssertInconclusiveException`. Log various "weird" scenarios via `Console.WriteLine()` to make it easier to get a "complete" listing of such failing methods by using `adb logcat` output. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Exclude tests which don't pass under NativeAOT. These fall into two major categories: 1. Failures that don't make sense, failing due to `TargetParameterCountException` or `InvalidOperationException` described below. These are ignored via: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] Update `UnitTestsControl.cs` to try to work around NativeAOT "weirdness" and provide better error messages when tests fail in certain scenarios. Previously, many (many!) tests would fail with one of: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 A problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist*; it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`. Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… An intermediate form of this commit would wrap the `TargetParameterCountException` in an `InvalidOperationException`, resulting in messages such as: System.InvalidOperationException: Exception thrown while invoking Uno.UI.Tests.Windows_Globalization.Given_NumeralSystemTranslator.When_NumeralSystemIsMtei(System.String, System.String) with arguments { System.Object[]{ 1 as System.String, ꯱ as System.String } }. ---> System.Reflection.TargetParameterCountException: Parameter count mismatch. Note that `When_NumeralSystemIsMtei(System.String, System.String)` takes two arguments, but it's given *one* argument with value `{{ System.Object[]{ 1 as System.String, ꯱ as System.String } }}`, i.e. *the values are there*, just "wrapped" in an extra array. Update `UnitTestsControl.InvokeTestMethod()` to always call `ExpandArgumentsWithDefaultValues()` as part of test method invocation, so that we have a centralized place to look for such "extra array wrapping". Update `ExpandArgumentsWithDefaultValues()` so that if it encounters an array for a parameter type which isn't an array, the array is expanded as additional arguments. Additionally, if a `TargetInvocationException` is thrown when the the method arguments count and parameters count match, throw an `AssertInconclusiveException`. Log various "weird" scenarios via `Console.WriteLine()` to make it easier to get a "complete" listing of such failing methods by using `adb logcat` output. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Exclude tests which don't pass under NativeAOT. These fall into three major categories: 1. Failures that don't make sense, likely due to unknown bugs within the NativeAOT toolchain itself, failing due to `TargetParameterCountException` or `InvalidOperationException` described below. Some of these are worked around (see below), while others are ignored via e.g.: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] 3. Other limitations within the NativeAOT environment. For example, Android+NativeAOT does not yet have a GC bridge, meaning every `Java.Lang.Object` subclass instance is *never* collected by the GC unless explicitly `.Dispose()`d Update `UnitTestsControl.cs` to try to work around some NativeAOT "weirdness" and provide better error messages when tests fail in certain scenarios. Previously, many tests would fail with one of: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 A problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist*; it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`. Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… An intermediate form of this commit would wrap the `TargetParameterCountException` in an `InvalidOperationException`, resulting in messages such as: System.InvalidOperationException: Exception thrown while invoking Uno.UI.Tests.Windows_Globalization.Given_NumeralSystemTranslator.When_NumeralSystemIsMtei(System.String, System.String) with arguments { System.Object[]{ 1 as System.String, ꯱ as System.String } }. ---> System.Reflection.TargetParameterCountException: Parameter count mismatch. Note that `When_NumeralSystemIsMtei(System.String, System.String)` takes two arguments, but it's given *one* argument with value `{{ System.Object[]{ 1 as System.String, ꯱ as System.String } }}`, i.e. *the values are there*, just "wrapped" in an extra array. Update `UnitTestsControl.InvokeTestMethod()` to always call `ExpandArgumentsWithDefaultValues()` as part of test method invocation, so that we have a centralized place to look for such "extra array wrapping". Update `ExpandArgumentsWithDefaultValues()` so that if it encounters an array for a parameter type which isn't an array, the array is expanded as additional arguments. Log various "weird" scenarios via `Console.WriteLine()` to make it easier to get a "complete" listing of such failing methods by using `adb logcat` output. TODO? the migration to AwesomeAssertions in 80c0705 results in some "bizarre" failure messages, e.g. Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Expected value to be less than or equal to 81 because TextBox/SingleTextBox;Microsoft.UI.Xaml.VisualStateManager;Microsoft.UI.Xaml.Controls.Grid;…;ElementStub/HorizontalScrollBar;… which is *truncated* at *4000* characters. *Something* is wonky there. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Exclude tests which don't pass under NativeAOT. These fall into three major categories: 1. Failures that don't make sense, likely due to unknown bugs within the NativeAOT toolchain itself, failing due to `TargetParameterCountException` or `InvalidOperationException` described below. Some of these are worked around (see below), while others are ignored via e.g.: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] 3. Other limitations within the NativeAOT environment. For example, Android+NativeAOT does not yet have a GC bridge, meaning every `Java.Lang.Object` subclass instance is *never* collected by the GC unless explicitly `.Dispose()`d Update `UnitTestsControl.cs` to try to work around some NativeAOT "weirdness" and provide better error messages when tests fail in certain scenarios. Previously, many tests would fail with one of: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 A problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist*; it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`. Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… An intermediate form of this commit would wrap the `TargetParameterCountException` in an `InvalidOperationException`, resulting in messages such as: System.InvalidOperationException: Exception thrown while invoking Uno.UI.Tests.Windows_Globalization.Given_NumeralSystemTranslator.When_NumeralSystemIsMtei(System.String, System.String) with arguments { System.Object[]{ 1 as System.String, ꯱ as System.String } }. ---> System.Reflection.TargetParameterCountException: Parameter count mismatch. Note that `When_NumeralSystemIsMtei(System.String, System.String)` takes two arguments, but it's given *one* argument with value `{{ System.Object[]{ 1 as System.String, ꯱ as System.String } }}`, i.e. *the values are there*, just "wrapped" in an extra array. Update `UnitTestsControl.InvokeTestMethod()` to always call `ExpandArgumentsWithDefaultValues()` as part of test method invocation, so that we have a centralized place to look for such "extra array wrapping". Update `ExpandArgumentsWithDefaultValues()` so that if it encounters an array for a parameter type which isn't an array, the array is expanded as additional arguments. Log various "weird" scenarios via `Console.WriteLine()` to make it easier to get a "complete" listing of such failing methods by using `adb logcat` output. TODO? the migration to AwesomeAssertions in 80c0705 results in some "bizarre" failure messages, e.g. Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Expected value to be less than or equal to 81 because TextBox/SingleTextBox;Microsoft.UI.Xaml.VisualStateManager;Microsoft.UI.Xaml.Controls.Grid;…;ElementStub/HorizontalScrollBar;… which is *truncated* at *4000* characters. *Something* is wonky there. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`, which fails: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Exclude tests which don't pass under NativeAOT. These fall into three major categories: 1. Failures that don't make sense, likely due to unknown bugs within the NativeAOT toolchain itself, failing due to `TargetParameterCountException` or `InvalidOperationException` described below. Some of these are worked around (see below), while others are ignored via e.g.: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] 3. Other limitations within the NativeAOT environment. For example, Android+NativeAOT does not yet have a GC bridge, meaning every `Java.Lang.Object` subclass instance is *never* collected by the GC unless explicitly `.Dispose()`d Update `UnitTestsControl.cs` to try to work around some NativeAOT "weirdness" and provide better error messages when tests fail in certain scenarios. Previously, many tests would fail with one of: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 or: System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 A problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist*; it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`. Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… An intermediate form of this commit would wrap the `TargetParameterCountException` in an `InvalidOperationException`, resulting in messages such as: System.InvalidOperationException: Exception thrown while invoking Uno.UI.Tests.Windows_Globalization.Given_NumeralSystemTranslator.When_NumeralSystemIsMtei(System.String, System.String) with arguments { System.Object[]{ 1 as System.String, ꯱ as System.String } }. ---> System.Reflection.TargetParameterCountException: Parameter count mismatch. Note that `When_NumeralSystemIsMtei(System.String, System.String)` takes two arguments, but it's given *one* argument with value `{{ System.Object[]{ 1 as System.String, ꯱ as System.String } }}`, i.e. *the values are there*, just "wrapped" in an extra array. Update `UnitTestsControl.InvokeTestMethod()` to always call `ExpandArgumentsWithDefaultValues()` as part of test method invocation, so that we have a centralized place to look for such "extra array wrapping". Update `ExpandArgumentsWithDefaultValues()` so that if it encounters an array for a parameter type which isn't an array, the array is expanded as additional arguments. Log various "weird" scenarios via `Console.WriteLine()` to make it easier to get a "complete" listing of such failing methods by using `adb logcat` output. TODO? the migration to AwesomeAssertions in 80c0705 results in some "bizarre" failure messages, e.g. Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Expected value to be less than or equal to 81 because TextBox/SingleTextBox;Microsoft.UI.Xaml.VisualStateManager;Microsoft.UI.Xaml.Controls.Grid;…;ElementStub/HorizontalScrollBar;… which is *truncated* at *4000* characters. *Something* is wonky there. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`, which fails: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Exclude tests which don't pass under NativeAOT. These fall into three major categories: 1. Failures that don't make sense, likely due to unknown bugs within the NativeAOT toolchain itself, failing due to `TargetParameterCountException` or `InvalidOperationException` described below. Some of these are worked around (see below), while others are ignored via e.g.: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] 3. Other limitations within the NativeAOT environment. For example, Android+NativeAOT does not yet have a GC bridge, meaning every `Java.Lang.Object` subclass instance is *never* collected by the GC unless explicitly `.Dispose()`d Update `UnitTestsControl.cs` to try to work around some NativeAOT "weirdness" and provide better error messages when tests fail in certain scenarios. Previously, many tests would fail with one of: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 or: System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 A problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist*; it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`. Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… An intermediate form of this commit would wrap the `TargetParameterCountException` in an `InvalidOperationException`, resulting in messages such as: System.InvalidOperationException: Exception thrown while invoking Uno.UI.Tests.Windows_Globalization.Given_NumeralSystemTranslator.When_NumeralSystemIsMtei(System.String, System.String) with arguments { System.Object[]{ 1 as System.String, ꯱ as System.String } }. ---> System.Reflection.TargetParameterCountException: Parameter count mismatch. Note that `When_NumeralSystemIsMtei(System.String, System.String)` takes two arguments, but it's given *one* argument with value `{{ System.Object[]{ 1 as System.String, ꯱ as System.String } }}`, i.e. *the values are there*, just "wrapped" in an extra array. Update `UnitTestsControl.InvokeTestMethod()` to always call `ExpandArgumentsWithDefaultValues()` as part of test method invocation, so that we have a centralized place to look for such "extra array wrapping". Update `ExpandArgumentsWithDefaultValues()` so that if it encounters an array for a parameter type which isn't an array, the array is expanded as additional arguments. Log various "weird" scenarios via `Console.WriteLine()` to make it easier to get a "complete" listing of such failing methods by using `adb logcat` output. TODO? the migration to AwesomeAssertions in 80c0705 results in some "bizarre" failure messages, e.g. Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Expected value to be less than or equal to 81 because TextBox/SingleTextBox;Microsoft.UI.Xaml.VisualStateManager;Microsoft.UI.Xaml.Controls.Grid;…;ElementStub/HorizontalScrollBar;… which is *truncated* at *4000* characters. *Something* is wonky there. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`, which fails: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Exclude tests which don't pass under NativeAOT. These fall into three major categories: 1. Failures that don't make sense, likely due to unknown bugs within the NativeAOT toolchain itself, failing due to `TargetParameterCountException` or `InvalidOperationException` described below. Some of these are worked around (see below), while others are ignored via e.g.: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] 3. Other limitations within the NativeAOT environment. For example, Android+NativeAOT does not yet have a GC bridge, meaning every `Java.Lang.Object` subclass instance is *never* collected by the GC unless explicitly `.Dispose()`d Update `UnitTestsControl.cs` to try to work around some NativeAOT "weirdness" and provide better error messages when tests fail in certain scenarios. Previously, many tests would fail with one of: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 or: System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 A problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist*; it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`. Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… An intermediate form of this commit would wrap the `TargetParameterCountException` in an `InvalidOperationException`, resulting in messages such as: System.InvalidOperationException: Exception thrown while invoking Uno.UI.Tests.Windows_Globalization.Given_NumeralSystemTranslator.When_NumeralSystemIsMtei(System.String, System.String) with arguments { System.Object[]{ 1 as System.String, ꯱ as System.String } }. ---> System.Reflection.TargetParameterCountException: Parameter count mismatch. Note that `When_NumeralSystemIsMtei(System.String, System.String)` takes two arguments, but it's given *one* argument with value `{{ System.Object[]{ 1 as System.String, ꯱ as System.String } }}`, i.e. *the values are there*, just "wrapped" in an extra array. Update `UnitTestsControl.InvokeTestMethod()` to always call `ExpandArgumentsWithDefaultValues()` as part of test method invocation, so that we have a centralized place to look for such "extra array wrapping". Update `ExpandArgumentsWithDefaultValues()` so that if it encounters an array for a parameter type which isn't an array, the array is expanded as additional arguments. Log various "weird" scenarios via `Console.WriteLine()` to make it easier to get a "complete" listing of such failing methods by using `adb logcat` output. TODO? the migration to AwesomeAssertions in 80c0705 results in some "bizarre" failure messages, e.g. Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Expected value to be less than or equal to 81 because TextBox/SingleTextBox;Microsoft.UI.Xaml.VisualStateManager;Microsoft.UI.Xaml.Controls.Grid;…;ElementStub/HorizontalScrollBar;… which is *truncated* at *4000* characters. *Something* is wonky there. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`, which fails: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Exclude tests which don't pass under NativeAOT. These fall into three major categories: 1. Failures that don't make sense, likely due to unknown bugs within the NativeAOT toolchain itself, failing due to `TargetParameterCountException` or `InvalidOperationException` described below. Some of these are worked around (see below), while others are ignored via e.g.: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] 3. Other limitations within the NativeAOT environment. For example, Android+NativeAOT does not yet have a GC bridge, meaning every `Java.Lang.Object` subclass instance is *never* collected by the GC unless explicitly `.Dispose()`d Update `UnitTestsControl.cs` to try to work around some NativeAOT "weirdness" and provide better error messages when tests fail in certain scenarios. Previously, many tests would fail with one of: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 or: System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 A problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist*; it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`. Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… An intermediate form of this commit would wrap the `TargetParameterCountException` in an `InvalidOperationException`, resulting in messages such as: System.InvalidOperationException: Exception thrown while invoking Uno.UI.Tests.Windows_Globalization.Given_NumeralSystemTranslator.When_NumeralSystemIsMtei(System.String, System.String) with arguments { System.Object[]{ 1 as System.String, ꯱ as System.String } }. ---> System.Reflection.TargetParameterCountException: Parameter count mismatch. Note that `When_NumeralSystemIsMtei(System.String, System.String)` takes two arguments, but it's given *one* argument with value `{{ System.Object[]{ 1 as System.String, ꯱ as System.String } }}`, i.e. *the values are there*, just "wrapped" in an extra array. Update `UnitTestsControl.InvokeTestMethod()` to always call `ExpandArgumentsWithDefaultValues()` as part of test method invocation, so that we have a centralized place to look for such "extra array wrapping". Update `ExpandArgumentsWithDefaultValues()` so that if it encounters an array for a parameter type which isn't an array, the array is expanded as additional arguments. Log various "weird" scenarios via `Console.WriteLine()` to make it easier to get a "complete" listing of such failing methods by using `adb logcat` output. TODO? the migration to AwesomeAssertions in 80c0705 results in some "bizarre" failure messages, e.g. Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Expected value to be less than or equal to 81 because TextBox/SingleTextBox;Microsoft.UI.Xaml.VisualStateManager;Microsoft.UI.Xaml.Controls.Grid;…;ElementStub/HorizontalScrollBar;… which is *truncated* at *4000* characters. *Something* is wonky there. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
…droid Context: #21256 / 52a6f3e Context: dotnet/android#10461 Context: dotnet/android#10457 Context: dotnet/android#10463 Context: AwesomeAssertions/AwesomeAssertions#290 #21256 added support for building with .NET 10, and one of the new features in .NET 10 is that Android has (very!) preliminary preview support for [NativeAOT][0]. As building `SamplesApp.Skia.netcoremobile.csproj` with NativeAOT takes a significant amount of time and disk space, we've decided to introduce a new `Tests - Android+NativeAOT Skia` stage to build and run these unit tests within an Android+NativeAOT environment. To help reduce disk usage, after building the `.apk` we delete the `obj` directory. Update `android-run-skia-runtime-tests.sh` to always create the `$(build.sourcesdirectory)/build/uitests-failure-results` path before existing with an error, as failure to do so means that the `PublishBuildArtifacts@1` YAML task fails: ##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /agent/_work/1/s/build/uitests-failure-results which in turn means subsequent `DownloadBuildArtifacts@0` / **Download previous test runs failed tests** steps *also* always fail: ##[error]Artifact uitests-android-nativeaot-failure-results not found for build 174635. Please ensure you have published artifacts in any previous phases of the current build. Update `ApplicationData.GetRoamingFolder()` to explicitly create `Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)`. (Apparently this isn't created by default under NativeAOT?) This avoids a startup assertion: I NativeAotFromAndroid: App failed to initialize: System.IO.DirectoryNotFoundException: IO_PathNotFound_Path, /data/user/0/uno.platform.samplesapp.skia/files/.config/b63c4306-f361-42d0-bc1d-5be385a95c78.txt I NativeAotFromAndroid: at System.IO.FileSystem.DeleteFile(String) + 0xe7 I NativeAotFromAndroid: at SamplesApp.App.<AssertApplicationData>g__AssertCanCreateFile|32_3(StorageFolder) + 0x10c I NativeAotFromAndroid: at SamplesApp.App.AssertApplicationData() + 0xa5 I NativeAotFromAndroid: at SamplesApp.App..ctor() + 0x2a3 I NativeAotFromAndroid: at SamplesApp.Droid.Application.<>c.<.ctor>b__0_0() + 0x18 I NativeAotFromAndroid: at Microsoft.UI.Xaml.NativeApplication.<OnActivityStarted>b__7_0() + 0x12 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.<Run>g__CreateApp|2_10(ApplicationInitializationCallbackParams _) + 0xf I NativeAotFromAndroid: at Microsoft.UI.Xaml.Application.StartPartial(ApplicationInitializationCallback callback) + 0xb5 I NativeAotFromAndroid: at Uno.UI.Runtime.Skia.Android.AndroidHost.Run() + 0x306 Enable NativeAOT builds by updating `SamplesApp.Skia.netcoremobile.csproj` to set the [`$(PublishAot)`][1] property to the `$(SkiaPublishAot)` MSBuild property. This allows us to build a single project for NativeAOT -- `SamplesApp.Skia.netcoremobile.csproj` -- *without* trying to build every referenced project for NativeAOT, which is what happens if you instead try `dotnet publish -p:PublishAot=true …`, which fails: % dotnet build -c Release -p:PublishAot=true src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj -bl … …/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(121,5): error NETSDK1207: Ahead-of-time compilation is not supported for the target framework. % dotnet publish src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj \ -c Release -r android-x64 -f net10.0-android -p:UnoTargetFrameworkOverride=net10.0-android -p:SkiaPublishAot=true -bl # succeeds… after 15 minutes… This also requires updating `$(NoWarn)` to ignore the hundreds of IL trimmer warnings. We're just trying to see where things stand for now. Additionally, we need to publish with `-r android-x64` in order to avoid the build error: …/Microsoft.NETCore.Native.Publish.targets(92,5): error MSB3030: Could not copy the file "bin/Release/net10.0-android/native/SamplesApp.so" because it was not found. Because it's `bin/Release/net10.0-android/android-{arm64,x64}/native/SamplesApp.so`! Oddly, using `-r android-x64` still results in *both* ABIs being included, which appears to be a unoplatform/uno "bug": % unzip -l src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/uno.platform.samplesapp.skia-Signed.apk | grep SamplesApp.so 763563120 08-28-2025 19:47 lib/x86_64/libSamplesApp.so 757982224 08-28-2025 19:48 lib/arm64-v8a/libSamplesApp.so The need for `-r android-x64` may be related to dotnet/android#10457. .NET Crypto support isn't propertly initialized in Android+NativeAOT apps in .NET 10 RC1; see dotnet/android#10463. This may be fixed in dotnet/android#10461, but in the meantime we can manually call `AndroidCryptoNative_InitLibraryOnLoad()` so that methods such as `SHA1.Create()` won't throw. Exclude tests which don't pass under NativeAOT. These fall into three major categories: 1. Failures that don't make sense, likely due to unknown bugs within the NativeAOT toolchain itself, failing due to `TargetParameterCountException` or `InvalidOperationException` described below. Some of these are worked around (see below), while others are ignored via e.g.: [Ignore("DataRowAttribute.GetData() wraps data in an extra array under NativeAOT; not yet understood why.")] 2. Failures which are due to `AwesomeAssertions` using `MethodInfo.MakeGenericMethod()`; see AwesomeAssertions/AwesomeAssertions#290: Unhandled exception. System.NotSupportedException: 'AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.HandleImpl[System.Int32](AwesomeAssertions.Equivalency.Steps.EnumerableEquivalencyValidator,System.Object[],System.Collections.Generic.IEnumerable`1[System.Int32])' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility at System.Reflection.Runtime.MethodInfos.RuntimeNamedMethodInfo`1.GetUncachedMethodInvoker(RuntimeTypeInfo[], MemberInfo) + 0x2a at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x3f at AwesomeAssertions.Equivalency.Steps.GenericEnumerableEquivalencyStep.Handle(Comparands, IEquivalencyValidationContext, IValidateChildNodeEquivalency) + 0x21a at AwesomeAssertions.Equivalency.EquivalencyValidator.TryToProveNodesAreEquivalent(Comparands, IEquivalencyValidationContext) + 0x129 at AwesomeAssertions.Equivalency.EquivalencyValidator.AssertEquality(Comparands, EquivalencyValidationContext) + 0x43 at AwesomeAssertions.Collections.GenericCollectionAssertions`3.BeEquivalentTo[TExpectation](IEnumerable`1, Func`2, String, Object[]) + 0x1f9 Basically, the `.BeBeEquivalentTo()` extension method cannot currently work in NativeAOT environments. These are ignored via: [Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: AwesomeAssertions/AwesomeAssertions#290")] 3. Other limitations within the NativeAOT environment. For example, Android+NativeAOT does not yet have a GC bridge, meaning every `Java.Lang.Object` subclass instance is *never* collected by the GC unless explicitly `.Dispose()`d Update `UnitTestsControl.cs` to try to work around some NativeAOT "weirdness" and provide better error messages when tests fail in certain scenarios. Previously, many tests would fail with one of: System.Reflection.TargetParameterCountException: Arg_ParmCnt at System.Reflection.DynamicInvokeInfo.ThrowForArgCountMismatch() + 0x83 at System.Reflection.DynamicInvokeInfo.Invoke(Object, IntPtr, Object[], BinderBundle, Boolean) + 0x136 at Internal.Reflection.Execution.MethodInvokers.InstanceMethodInvoker.Invoke(Object, Object[], BinderBundle, Boolean) + 0x4f at Internal.Reflection.Core.Execution.MethodBaseInvoker.Invoke(Object, Object[], Binder, BindingFlags, CultureInfo) + 0x48 at System.Reflection.Runtime.MethodInfos.RuntimeMethodInfo.Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) + 0x70 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x4b9 or: System.InvalidOperationException: Missing parameter does not have default value at Uno.UI.Samples.Tests.UnitTestsControl.ExpandArgumentsWithDefaultValues(Object[] methodArguments, ParameterInfo[] methodParameters) + 0x138 at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_4.<<ExecuteTestsForInstance>b__12>d.MoveNext() + 0x92 --- End of stack trace from previous location --- at Uno.UI.Samples.Tests.UnitTestsControl.<>c__DisplayClass67_2.<<ExecuteTestsForInstance>g__InvokeTestMethod|5>d.MoveNext() + 0x549 A problem is that the reported test that was failing would be reported as e.g. `When_Add_Remove(System.Object[])`, which is a test method which *does not exist*; it's actually `When_Add_Remove(object, int, LeakTestStyles, RuntimeTestPlatforms)`. Additionally, which parameter doesn't have a default value? Or how does the parameter count not match? Or… An intermediate form of this commit would wrap the `TargetParameterCountException` in an `InvalidOperationException`, resulting in messages such as: System.InvalidOperationException: Exception thrown while invoking Uno.UI.Tests.Windows_Globalization.Given_NumeralSystemTranslator.When_NumeralSystemIsMtei(System.String, System.String) with arguments { System.Object[]{ 1 as System.String, ꯱ as System.String } }. ---> System.Reflection.TargetParameterCountException: Parameter count mismatch. Note that `When_NumeralSystemIsMtei(System.String, System.String)` takes two arguments, but it's given *one* argument with value `{{ System.Object[]{ 1 as System.String, ꯱ as System.String } }}`, i.e. *the values are there*, just "wrapped" in an extra array. Update `UnitTestsControl.InvokeTestMethod()` to always call `ExpandArgumentsWithDefaultValues()` as part of test method invocation, so that we have a centralized place to look for such "extra array wrapping". Update `ExpandArgumentsWithDefaultValues()` so that if it encounters an array for a parameter type which isn't an array, the array is expanded as additional arguments. Log various "weird" scenarios via `Console.WriteLine()` to make it easier to get a "complete" listing of such failing methods by using `adb logcat` output. TODO? the migration to AwesomeAssertions in 80c0705 results in some "bizarre" failure messages, e.g. Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: Expected value to be less than or equal to 81 because TextBox/SingleTextBox;Microsoft.UI.Xaml.VisualStateManager;Microsoft.UI.Xaml.Controls.Grid;…;ElementStub/HorizontalScrollBar;… which is *truncated* at *4000* characters. *Something* is wonky there. [0]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ [1]: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#publish-native-aot-using-the-cli [2]: https://developer.android.com/guide/topics/manifest/application-element#debug [3]: dotnet/java-interop@90ac202
Context: #19934
Context: #21140
Context: dotnet/sdk#48949
#19934 was the first attempt to build unoplatform/uno with .NET 10. It built (mostly), but it had lots of unit test failures (over 3700) that were not understood at the time.
#21140 was an attempt to cleanup & simplify #19934. It partially succeeded, but required additional reconsideration for a cleaner and more understandable merge.
(Later, PR #21183 helped explain many of the unit test failures that PR #19934 observed: Xamarin.UITest doesn't work reliably under .NET 9! See microsoft/appcenter#2646 and microsoft/appcenter#327!)
Some of the contents of #19934 and #21140 have been split out into separately merged PRs such as #21230 (CS0246 fixes) and #21199 (remove
[Export]in some scenarios).Squash existing "known good" and related changes:
doc updates
Bumping target framework versions,
Use uno.check 1.32.0-dev.45, which knows about .NET 10 Preview 7.
$(TreatWarningsAsErrors)=true + NuGet warnings. For example:$(TreatWarningsAsErrors)=true + CS8604 warnings due to nullability changes, particularly in iOS.$(TreatWarningsAsErrors)=true + IL2* warnings, some of which @jonpryor was able to fix in a reasonable timeframe, and some of which was thrown into$(NoWarn)to deal with later.Remove hardcoded
$(TargetFramework)=net8.0 fromUno.UI.RemoteControl.TestProcessor.csproj, so that it builds, and remove other uses ofnet8.0from everywhere other thansrc/SolutionTemplate.Provide
%(PackageReference.Version)for packages that were producing NU1015 errors, specificallyUno.Fonts.OpenSans.Remove
@(PackageReference)values which produced NU1510 warnings such as:Improve
dotnet-install.ymluse, as some CI environments don't have aunoplatform/unocheckout, and thus cannot copy files such asbuild/ci/net10/global.json.Improve
local-android-uitest-run.shfor local macOS use: Export and use$ANDROID_AVD_HOME, so that we have a "known" location for whare Emulator images are created. (Not sure what's wrong with my environment, but they are not reliably created or loaded from$HOME/.android/avd.)Also update so that it doesn't require running the script from the
build/test-scriptsdirectory. You can now run it from topdir:Provision OpenJDK-17, as .NET 9 now requires it.
Use Xcode 16.4, as .NET 10 iOS now requires it.
TODO, for future commits to this PR:
Xamarin.AndroidX package version bumps from chore: bump Xamarin.AndroidX Package Versions #21205. We felt that these shouldn't be separately merged, as some of version bumps are quite significant and should instead only be used with .NET 10.
A new understanding of
src/SolutionTemplate: the intent, as @jonpryor currently understands it, is that tests withinsrc/SolutionTemplateare "frozen in time";$(TargetFrameworks)should not be updated, etc.Which means that when we drop support for an older version of .NET, we should in turn remove the old tests.
GitHub Issue: closes #
PR Type:
What is the current behavior? 🤔
What is the new behavior? 🚀
PR Checklist ✅
Please check if your PR fulfills the following requirements:
Screenshots Compare Test Runresults.Other information ℹ️