Skip to content

Commit 92676ea

Browse files
committed
chore: build & run SamplesApp.Skia.netcoremobile with NativeAOT on Android
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
1 parent ce7b4c4 commit 92676ea

File tree

30 files changed

+483
-20
lines changed

30 files changed

+483
-20
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
parameters:
2+
vmLinuxPool: ''
3+
UNO_UWP_BUILD: ''
4+
XAML_FLAVOR_BUILD: ''
5+
6+
jobs:
7+
- job: Skia_Android_NativeAOT_Tests_Build
8+
displayName: 'Build Skia Android+NativeAOT Samples App'
9+
timeoutInMinutes: 60
10+
cancelTimeoutInMinutes: 1
11+
12+
pool: ${{ parameters.vmLinuxPool }}
13+
14+
variables:
15+
CombinedConfiguration: Release|Any CPU
16+
CI_Build: true
17+
18+
UNO_UWP_BUILD: ${{ parameters.UNO_UWP_BUILD }}
19+
XAML_FLAVOR_BUILD: ${{ parameters.XAML_FLAVOR_BUILD }}
20+
21+
steps:
22+
- checkout: self
23+
clean: true
24+
25+
- template: ../templates/gitversion.yml
26+
- template: ../templates/dotnet-mobile-install-linux.yml
27+
parameters:
28+
UnoCheckParameters: '--tfm net10.0-android'
29+
30+
- powershell: 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:ApplicationId=uno.platform.samplesapp.skia.nativeaot -p:SkiaPublishAot=true /bl:$(build.artifactstagingdirectory)/logs/build-skia-android-nativeaot.binlog
31+
displayName: Build Android+NativeAOT Skia Head
32+
33+
- script: >
34+
rm -Rf src/SamplesApp/SamplesApp.Skia.netcoremobile/obj
35+
workingDirectory: $(Build.SourcesDirectory)
36+
displayName: Delete obj folder to free up disk space
37+
38+
- task: CopyFiles@2
39+
displayName: 'Copy Generated Android APK'
40+
inputs:
41+
SourceFolder: $(build.sourcesdirectory)/src/SamplesApp/SamplesApp.Skia.netcoremobile/bin/Release/net10.0-android/android-x64/publish/
42+
Contents: 'uno.platform.samplesapp.skia.nativeaot-Signed.apk'
43+
TargetFolder: $(build.artifactstagingdirectory)/android-nativeaot
44+
CleanTargetFolder: false
45+
OverWrite: false
46+
flattenFolders: false
47+
48+
- task: PublishPipelineArtifact@1
49+
displayName: 'Publish Android+NativeAOT Binaries'
50+
retryCountOnTaskFailure: 3
51+
inputs:
52+
targetPath: $(build.artifactstagingdirectory)/android-nativeaot
53+
ArtifactName: uitests-android-nativeaot-skia-build
54+
55+
- task: PublishBuildArtifacts@1
56+
retryCountOnTaskFailure: 3
57+
condition: always()
58+
inputs:
59+
PathtoPublish: $(build.artifactstagingdirectory)/logs
60+
ArtifactName: skia-samples-app-binlog
61+
ArtifactType: Container
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
parameters:
2+
vmLinuxPool: ''
3+
UNO_UWP_BUILD: ''
4+
XAML_FLAVOR_BUILD: ''
5+
6+
jobs:
7+
##
8+
## Android+NativeAOT Skia
9+
##
10+
11+
- job: Android_NativeAOT_Tests
12+
displayName: ' ' ## Name is concatenated with the matrix group name
13+
timeoutInMinutes: 45
14+
dependsOn: Skia_Android_NativeAOT_Tests_Build
15+
pool: ${{ parameters.vmLinuxPool }}
16+
17+
variables:
18+
CI_Build: true
19+
SourceLinkEnabled: false
20+
NUGET_PACKAGES: $(Agent.WorkFolder)/.nuget
21+
22+
strategy:
23+
matrix:
24+
25+
'Runtime Tests 0':
26+
ANDROID_SIMULATOR_APILEVEL: 34
27+
UITEST_TEST_MODE_NAME: RuntimeTests
28+
UNO_UITEST_BUCKET_ID: RuntimeTests
29+
UITEST_RUNTIME_TEST_GROUP: 0
30+
UITEST_RUNTIME_TEST_GROUP_COUNT: 5
31+
SAMPLEAPP_ARTIFACT_NAME: uitests-android-nativeaot-skia-build
32+
TARGETPLATFORM_NAME: net10
33+
UITEST_TEST_TIMEOUT: '2600s'
34+
35+
'Runtime Tests 1':
36+
ANDROID_SIMULATOR_APILEVEL: 34
37+
UITEST_TEST_MODE_NAME: RuntimeTests
38+
UNO_UITEST_BUCKET_ID: RuntimeTests
39+
UITEST_RUNTIME_TEST_GROUP: 1
40+
UITEST_RUNTIME_TEST_GROUP_COUNT: 5
41+
SAMPLEAPP_ARTIFACT_NAME: uitests-android-nativeaot-skia-build
42+
TARGETPLATFORM_NAME: net10
43+
UITEST_TEST_TIMEOUT: '2600s'
44+
45+
'Runtime Tests 2':
46+
ANDROID_SIMULATOR_APILEVEL: 34
47+
UITEST_TEST_MODE_NAME: RuntimeTests
48+
UNO_UITEST_BUCKET_ID: RuntimeTests
49+
UITEST_RUNTIME_TEST_GROUP: 2
50+
UITEST_RUNTIME_TEST_GROUP_COUNT: 5
51+
SAMPLEAPP_ARTIFACT_NAME: uitests-android-nativeaot-skia-build
52+
TARGETPLATFORM_NAME: net10
53+
UITEST_TEST_TIMEOUT: '2600s'
54+
55+
'Runtime Tests 3':
56+
ANDROID_SIMULATOR_APILEVEL: 34
57+
UITEST_TEST_MODE_NAME: RuntimeTests
58+
UNO_UITEST_BUCKET_ID: RuntimeTests
59+
UITEST_RUNTIME_TEST_GROUP: 3
60+
UITEST_RUNTIME_TEST_GROUP_COUNT: 5
61+
SAMPLEAPP_ARTIFACT_NAME: uitests-android-nativeaot-skia-build
62+
TARGETPLATFORM_NAME: net10
63+
UITEST_TEST_TIMEOUT: '2600s'
64+
65+
'Runtime Tests 4':
66+
ANDROID_SIMULATOR_APILEVEL: 34
67+
UITEST_TEST_MODE_NAME: RuntimeTests
68+
UNO_UITEST_BUCKET_ID: RuntimeTests
69+
UITEST_RUNTIME_TEST_GROUP: 4
70+
UITEST_RUNTIME_TEST_GROUP_COUNT: 5
71+
SAMPLEAPP_ARTIFACT_NAME: uitests-android-nativeaot-skia-build
72+
TARGETPLATFORM_NAME: net10
73+
UITEST_TEST_TIMEOUT: '2600s'
74+
75+
steps:
76+
- checkout: self
77+
clean: true
78+
79+
- bash: |
80+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
81+
sudo udevadm control --reload-rules
82+
sudo udevadm trigger --name-match=kvm
83+
displayName: 'Enable KVM'
84+
85+
- task: DownloadPipelineArtifact@2
86+
displayName: Downloading $(SAMPLEAPP_ARTIFACT_NAME)
87+
inputs:
88+
artifact: $(SAMPLEAPP_ARTIFACT_NAME)
89+
path: '$(build.sourcesdirectory)/build/$(SAMPLEAPP_ARTIFACT_NAME)/android'
90+
91+
- task: DownloadBuildArtifacts@0
92+
condition: gt(variables['System.JobAttempt'], 1)
93+
continueOnError: true
94+
displayName: Download previous test runs failed tests
95+
inputs:
96+
artifactName: uitests-android-nativeaot-failure-results
97+
downloadPath: '$(build.sourcesdirectory)/build'
98+
99+
- template: ../templates/dotnet-install.yml
100+
101+
- bash: |
102+
chmod +x $(build.sourcesdirectory)/build/test-scripts/android-run-skia-runtime-tests.sh
103+
UNO_UITEST_APP_ID=uno.platform.samplesapp.skia.nativeaot \
104+
$(build.sourcesdirectory)/build/test-scripts/android-run-skia-runtime-tests.sh
105+
106+
displayName: Run Android+NativeAOT Skia Tests
107+
108+
- task: PublishTestResults@2
109+
condition: always()
110+
inputs:
111+
testRunTitle: 'Android+NativeAOT Skia Runtime Tests $(UITEST_RUNTIME_TEST_GROUP)'
112+
testResultsFormat: 'NUnit'
113+
testResultsFiles: '$(build.sourcesdirectory)/build/*TestResult*.xml'
114+
failTaskOnFailedTests: true
115+
116+
- task: PublishBuildArtifacts@1
117+
condition: always()
118+
retryCountOnTaskFailure: 3
119+
inputs:
120+
PathtoPublish: $(build.artifactstagingdirectory)
121+
ArtifactName: android-nativeaot-skia-results
122+
ArtifactType: Container
123+
124+
- task: PublishBuildArtifacts@1
125+
condition: always()
126+
displayName: Publish Failed Tests Results
127+
retryCountOnTaskFailure: 3
128+
inputs:
129+
PathtoPublish: $(build.sourcesdirectory)/build/uitests-failure-results
130+
ArtifactName: uitests-android-nativeaot-failure-results
131+
ArtifactType: Container

build/ci/tests/.azure-devops-tests-skia-stages.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,23 @@ stages:
7575
UNO_UWP_BUILD: '${{ parameters.UNO_UWP_BUILD }}'
7676
XAML_FLAVOR_BUILD: '${{ parameters.XAML_FLAVOR_BUILD }}'
7777

78+
- stage: runtime_tests_skia_android_nativeaot
79+
displayName: Tests - Android+NativeAOT Skia
80+
dependsOn:
81+
- Setup
82+
83+
jobs:
84+
- template: .azure-devops-tests-android-nativeaot-skia-build.yml
85+
parameters:
86+
vmLinuxPool: '${{ parameters.vmLinuxPool }}'
87+
UNO_UWP_BUILD: '${{ parameters.UNO_UWP_BUILD }}'
88+
XAML_FLAVOR_BUILD: '${{ parameters.XAML_FLAVOR_BUILD }}'
89+
- template: .azure-devops-tests-android-nativeaot-skia.yml
90+
parameters:
91+
vmLinuxPool: '${{ parameters.vmLinuxPool }}'
92+
UNO_UWP_BUILD: '${{ parameters.UNO_UWP_BUILD }}'
93+
XAML_FLAVOR_BUILD: '${{ parameters.XAML_FLAVOR_BUILD }}'
94+
7895
- stage: runtime_tests_skia_ios
7996
displayName: Tests - iOS Skia
8097
dependsOn:

build/test-scripts/android-run-skia-runtime-tests.sh

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,19 +157,21 @@ while [[ ! $($ANDROID_HOME/platform-tools/adb shell test -e "$UITEST_RUNTIME_AUT
157157
fi
158158
done
159159

160-
$ANDROID_HOME/platform-tools/adb pull $UITEST_RUNTIME_AUTOSTART_RESULT_DEVICE_PATH $UITEST_RUNTIME_AUTOSTART_RESULT_FILENAME
160+
$ANDROID_HOME/platform-tools/adb pull $UITEST_RUNTIME_AUTOSTART_RESULT_DEVICE_PATH $UITEST_RUNTIME_AUTOSTART_RESULT_FILENAME || echo "ERROR: could not adb pull $UITEST_RUNTIME_AUTOSTART_RESULT_DEVICE_PATH"
161+
162+
## Dump the emulator's system log
163+
$ANDROID_HOME/platform-tools/adb shell logcat -d > $LOGS_PATH/android-device-log-$UNO_UITEST_BUCKET_ID-$UITEST_RUNTIME_TEST_GROUP-$UITEST_TEST_MODE_NAME.txt
164+
165+
# create $BUILD_SOURCESDIRECTORY/build/uitests-failure-results before exiting, so that `PublishBuildArtifacts@1` doesn't error out just because the tests crashed.
166+
mkdir -p $(dirname ${UNO_TESTS_FAILED_LIST})
161167

162168
if [ ! -f "$UITEST_RUNTIME_AUTOSTART_RESULT_FILENAME" ]; then
163169
echo "ERROR: The test results file $UITEST_RUNTIME_AUTOSTART_RESULT_FILENAME does not exist (did nunit crash ?)"
164170
exit 1
165171
fi
166172

167-
## Dump the emulator's system log
168-
$ANDROID_HOME/platform-tools/adb shell logcat -d > $LOGS_PATH/android-device-log-$UNO_UITEST_BUCKET_ID-$UITEST_RUNTIME_TEST_GROUP-$UITEST_TEST_MODE_NAME.txt
169-
170173
## Export the failed tests list for reuse in a pipeline retry
171174
pushd $BUILD_SOURCESDIRECTORY/src/Uno.NUnitTransformTool
172-
mkdir -p $(dirname ${UNO_TESTS_FAILED_LIST})
173175

174176
echo "Running NUnitTransformTool"
175177

src/Directory.Build.props

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
<RestoreEnablePackagePruning>true</RestoreEnablePackagePruning>
5656

5757
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
58+
59+
<DefineConstants Condition=" '$(UseMonoRuntime)' == 'false' ">$(DefineConstants);RUNTIME_CORECLR</DefineConstants>
60+
<DefineConstants Condition=" '$(SkiaPublishAot)' == 'true' ">$(DefineConstants);RUNTIME_NATIVE_AOT</DefineConstants>
5861
</PropertyGroup>
5962

6063
<PropertyGroup>

src/SamplesApp/SamplesApp.Skia.netcoremobile/Android/Main.Android.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ public override void OnCreate()
116116
// TODO: remove once the Android+CoreCLR runtime properly inits crypto, possibly .NET 10 RC2?
117117
Java.Lang.JavaSystem.LoadLibrary("System.Security.Cryptography.Native.Android");
118118
#endif // RUNTIME_CORECLR
119+
#if RUNTIME_NATIVE_AOT
120+
// TODO: remove once the Android+NativeAOT runtime properly inits crypto
121+
// Likely once https://github.com/dotnet/android/pull/10461 is merged, possibly .NET 10 RC2?
122+
JniEnvironment.References.GetJavaVM(out var invocationPointer);
123+
NativeMethods.AndroidCryptoNative_InitLibraryOnLoad(javaVM: invocationPointer, reserved: IntPtr.Zero);
124+
#endif // RUNTIME_NATIVE_AOT
119125

120126
// Initialize Android-specific extensions.
121127
// These would be generally registered automatically by App.xaml generator,
@@ -126,4 +132,12 @@ public override void OnCreate()
126132
ApiExtensibility.Register(typeof(IApplicationViewSpanningRects), o => new FoldableApplicationViewSpanningRects(o));
127133
}
128134
}
135+
136+
#if RUNTIME_NATIVE_AOT
137+
internal static partial class NativeMethods
138+
{
139+
[DllImport("System.Security.Cryptography.Native.Android", CallingConvention = CallingConvention.Cdecl)]
140+
internal static extern void AndroidCryptoNative_InitLibraryOnLoad(IntPtr javaVM, IntPtr reserved);
141+
}
142+
#endif // RUNTIME_NATIVE_AOT
129143
}

src/SamplesApp/SamplesApp.Skia.netcoremobile/SamplesApp.Skia.netcoremobile.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
-->
3333
<NoWarn>$(NoWarn);NU1703;SYSLIB1045</NoWarn>
3434

35+
<!-- Ignore linker warnings for now -->
36+
<NoWarn>$(NoWarn);IL2026;IL2057;IL2062;IL2065;IL2067;IL2068;IL2070;IL2072;IL2075;IL2077;IL2080;IL2104;IL2111;IL2122;IL3000;IL3002;IL3050;IL3053</NoWarn>
37+
3538
<!--
3639
aab is the default packaging format in net6 API 31.
3740
We need an APK for deployment on simulators.
@@ -53,6 +56,8 @@
5356

5457
<!-- Required when not building inside VS to avoid dependency issues -->
5558
<PreBuildUnoUITasks Condition="'$(BuildingInsideVisualStudio)'==''">true</PreBuildUnoUITasks>
59+
60+
<PublishAot Condition=" '$(SkiaPublishAot)' != '' ">$(SkiaPublishAot)</PublishAot>
5661
</PropertyGroup>
5762

5863
<ItemGroup>
@@ -291,6 +296,7 @@
291296

292297
<ItemGroup>
293298
<TrimmerRootDescriptor Include="LinkerConfig.xml" />
299+
<TrimmerRootAssembly Include="SamplesApp.Skia" RootMode="All" />
294300
</ItemGroup>
295301

296302
<ItemGroup>

src/SamplesApp/SamplesApp.UITests/Windows_UI_Xaml_Input/Nested_Sequence_Tests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ internal class Nested_Sequence_Tests : SampleControlUITestBase
3535
#if IS_RUNTIME_UI_TESTS
3636
[Uno.UI.RuntimeTests.RequiresFullWindow]
3737
#endif
38+
#if RUNTIME_NATIVE_AOT
39+
[Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: https://github.com/AwesomeAssertions/AwesomeAssertions/issues/290")]
40+
#endif // RUNTIME_NATIVE_AOT
3841
public async Task When_PressOnNestedAndReleaseOnContainer_Touch()
3942
{
4043
await RunAsync(_sample);
@@ -67,6 +70,9 @@ public async Task When_PressOnNestedAndReleaseOnContainer_Touch()
6770
[Ignore("Inputs simulated by selenium are directly appreaing at the start location and wrongly inserting an exit.")]
6871
//[ActivePlatforms(Platform.Browser)]
6972
#endif
73+
#if RUNTIME_NATIVE_AOT
74+
[Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: https://github.com/AwesomeAssertions/AwesomeAssertions/issues/290")]
75+
#endif // RUNTIME_NATIVE_AOT
7076
#if IS_RUNTIME_UI_TESTS
7177
[Uno.UI.RuntimeTests.RequiresFullWindow]
7278
#endif
@@ -101,6 +107,9 @@ public async Task When_PressOnNestedAndReleaseOnContainer_Mouse()
101107
#if !__SKIA__
102108
[Ignore("Does not work due to the 'implicit capture'")]
103109
#endif
110+
#if RUNTIME_NATIVE_AOT
111+
[Ignore(".BeEquivalentTo() unsupported under NativeAOT; see: https://github.com/AwesomeAssertions/AwesomeAssertions/issues/290")]
112+
#endif // RUNTIME_NATIVE_AOT
104113
[InjectedPointer(PointerDeviceType.Touch)]
105114
public async Task When_PressOnContainerAndReleaseOnNested_Touch()
106115
{

0 commit comments

Comments
 (0)