osu-framework
osu-framework copied to clipboard
Bring Android framework to .NET 6
- [x] Requires https://github.com/ppy/osuTK/pull/75
Development requirement
Run dotnet workload install android
to install the necessary SDK components (may require sudo
).
Can be changed to dotnet workload restore
once there's no old projects (Xamarin) remaining.
The default Android SDK version changed from 29 to 31.
Xamarin toolchain in Visual Studio should be still required. I haven't tested if the managed components can be compiled without Xamarin installed.
The framework visual test works fine on my phone.
The constants are all correct on Windows. The video test failure shouldn't be my fault since I don't touch anything else.
This will require 2 rounds of deployment: the first one to deploy updated NativeLibs, the second one to update android framework.
The CI build accepting updated NativeLibs should not show warning XA4301
. I tested it with local folder as nuget source.
Or, we can separate the NativeLibs change to another PR to validate it.
Also, re: a267cf6 - it looks a bit weird to create an empty dir in a correct location just so RID fallback to linux doesn't happen. Is it viable to perhaps move binaries out of osu.Framework.Android
to the nativelibs project? Seems like that'd be a cleaner resolution.
If that happens I'd much agree to splitting to a separate PR.
Is it viable to perhaps move binaries out of
osu.Framework.Android
to the nativelibs project? Seems like that'd be a cleaner resolution.
Yes I've considered this option. The downside is to increase nuget restore size for desktop only development. Leaving for decision here.
Crashes when returning from activity pause (eg. press home and open the game again) with InvalidFramebufferOperationExt
. Only happens on debug build, release works fine.
Can repro on two devices, API 28 and 30. Are you able to reproduce?
2022-03-28 21:31:43.319 10374-10374/osu.Framework.Tests.Android E/AndroidRuntime: FATAL EXCEPTION: main
Process: osu.Framework.Tests.Android, PID: 10374
android.runtime.JavaProxyThrowable: osuTK.Graphics.GraphicsErrorException: InvalidFramebufferOperationExt
at osuTK.Graphics.ES30.ErrorHelper.CheckErrors()
at osuTK.Graphics.ES30.ErrorHelper.Dispose()
at osuTK.Graphics.ES30.GL.Clear(ClearBufferMask mask)
at osu.Framework.Graphics.OpenGL.GLWrapper.Clear(ClearInfo clearInfo)
at osu.Framework.Graphics.OpenGL.GLWrapper.Reset(Vector2 size)
at osu.Framework.Threading.DrawThread.OnInitialize()
at osu.Framework.Threading.GameThread.Initialize(Boolean withThrottling)
at osu.Framework.Platform.ThreadRunner.ensureCorrectExecutionMode()
at osu.Framework.Platform.ThreadRunner.Start()
at osu.Framework.Platform.GameHost.Resume()
at osu.Framework.Android.AndroidGameActivity.OnRestart()
at Android.App.Activity.n_OnRestart(IntPtr jnienv, IntPtr native__this)
at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V callback, IntPtr jnienv, IntPtr klazz)
at crc64eb0f9b4bca91a892.AndroidGameActivity.n_onRestart(Native Method)
at crc64eb0f9b4bca91a892.AndroidGameActivity.onRestart(AndroidGameActivity.java:61)
at android.app.Instrumentation.callActivityOnRestart(Instrumentation.java:1445)
at android.app.Activity.performRestart(Activity.java:8261)
at android.app.ActivityThread.performRestartActivity(ActivityThread.java:5305)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:243)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2328)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:255)
at android.app.ActivityThread.main(ActivityThread.java:8212)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:632)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1049)
No, it works fine on my phone, using framework visual tests in Debug. The device is Android 11.
Note: I didn't use the updated osuTK binary, but instead create a facade (mentioned in osuTK PR) to make it work. I don't think this can be a different though, but you can do a try for this method too.
Seems the crashes are caused by running/building ppy.osuTK.NS20
in debug configuration. So it doesn't crash with your method.
In my original testing, I changed both ppy.osuTK.NS20
and ppy.osuTK.Android
to use a local checkout (at your PR).
With only ppy.osuTK.Android
being a local checkout (and ppy.osuTK.NS20
using the same nuget package as master
), it doesn't crash in debug.
Crashes with your method if using local checkout of both osuTK.NS20
and osuTK.Android
(local checkout at master
)
But this doesn't seem like a blocker for this PR, as osuTK
is used in release configuration.
Going to block this until the osu!-side blocking issue is fixed. We typically keep osu! and osu!framework in sync and it's hard to say how long the blocked issue will take to be resolved (or even what the rollout timetable looks like for dotnet android).
I've pushed out an osuTK build to nuget including https://github.com/ppy/osuTK/pull/75, so packages can be updated after packages are indexed (needs 30 minutes or so).
After updating osuTK to net6 compiled version, the Realm issue disappears (tested with framework visual test), but another null pointer dereference appears when testing with full game, even before touching full game specific code. Aiming to identify it.
Edit: it's a stupid issue that I forgot to update common framework together with android framework. However, the Realms issue only reproduces for full game, not framework test. It's getting more and more complicated.
Now I've clarified the crash happens if any monoandroid reference exists. Identifying what to do at full game side.
Highlight the TBD here: should we (try to) move android native assets into NativeLibs?
probably best to leave as is in this pull and move them as a follow up even if it is decided to be the right direction.
Confirmed with debugger and decompiled code that InvocationPointer
is java_vm.
I've attempted to test this today and am not sure where to start, because:
-
I can no longer debug any of the android projects. The option just isn't there, because I can't deploy projects in debug onto android:
The above screenshot has a bit of Polish but hopefully you get the point - the run button is supposed to be listing off all available devices to deploy to. It doesn't anymore if I'm not on a release config. And if I try to debug a release build, then it just doesn't work anymore, the debugger does not attach.
-
On both my test devices, I am seeing native crashes in logcat when attempting to run visual testts.
Device 1 (Samsung SM-J710F, api level 24):
04-10 14:08:36.421 Samsung SM-J710F Error 31958 DEBUG pid: 31910, tid: 31910, name: k.Tests.Android >>> osu.Framework.Tests.Android <<<
04-10 14:08:36.421 Samsung SM-J710F Error 31958 DEBUG signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x3a127fd7
r0 3a127fcb r1 00000000 r2 00000000 r3 00000000
r4 ffa2ff8c r5 3a127fcb r6 00000000 r7 ffa2ffd0
r8 00000000 r9 f3bbce17 sl 00000043 fp 00000000
ip f3f78b20 sp ffa2feb8 lr f3e387c1 pc f3bbfe64 cpsr 600e0030
04-10 14:08:36.425 Samsung SM-J710F Error 31958 DEBUG backtrace:
#00 pc 000b0e64 /system/lib/libart.so (_ZN3art9ArtMethod23GetOatQuickMethodHeaderEj+19)
#01 pc 003297bd /system/lib/libart.so (_ZN3art12StackVisitor9WalkStackEb+116)
#02 pc 003348d7 /system/lib/libart.so (_ZNK3art6Thread16GetCurrentMethodEPjb+54)
#03 pc 00261975 /system/lib/libart.so (_ZN3art3JNI9FindClassEP7_JNIEnvPKc+1152)
#04 pc 0002ad0b /data/app/osu.Framework.Tests.Android-1/lib/arm/libmonodroid.so (java_interop_jnienv_find_class+24)
#05 pc 00003f14 <anonymous:eae25000>
Device 2 (OnePlus KB2003, api 30):
04-10 14:13:24.124 OnePlus KB2003 Error 23722 DEBUG pid: 28032, tid: 28032, name: k.Tests.Android >>> osu.Framework.Tests.Android <<<
04-10 14:13:24.124 OnePlus KB2003 Error 23722 DEBUG signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4
04-10 14:13:24.124 OnePlus KB2003 Error 23722 DEBUG Cause: null pointer dereference
x0 4060000000000030 x1 0000000000000000 x2 0000007fc0b93400 x3 0000000000000000
x4 00000000132d73c0 x5 0000000013a80ea8 x6 4200000400000000 x7 4200000400000000
x8 0000007fc0b8af60 x9 0000000000000000 x10 0000007fc0b8af60 x11 0000000040600000
x12 0000000000000000 x13 0000000000000038 x14 0000000040600000 x15 40600000320f3016
x16 0000000040600000 x17 fffffffffffffffe x18 00000070952b4000 x19 0000007fc0b93640
x20 0000000000000000 x21 0000007fc0b936b0 x22 0000007fc0b940f0 x23 0000007fc0b94050
x24 0000006d9dd05e40 x25 0000006d9dd06210 x26 0000000000000000 x27 0000000000000030
x28 0000007094646000 x29 0000007fc0b93590
lr 0000006d9e14de54 sp 0000007fc0b933c0 pc 0000006d9e14dc48 pst 0000000000001000
04-10 14:13:24.170 OnePlus KB2003 Error 23722 DEBUG backtrace:
#00 pc 0000000000584c48 /apex/com.android.art/lib64/libart.so (void art::StackVisitor::WalkStack<(art::StackVisitor::CountTransitions)1>(bool)+136) (BuildId: e841be9816817e37b70ebf4a461a916e)
#01 pc 00000000005b9fb8 /apex/com.android.art/lib64/libart.so (void art::Thread::VisitRoots<false>(art::RootVisitor*)+1320) (BuildId: e841be9816817e37b70ebf4a461a916e)
#02 pc 0000000000268090 /apex/com.android.art/lib64/libart.so (art::gc::collector::ConcurrentCopying::ThreadFlipVisitor::Run(art::Thread*)+308) (BuildId: e841be9816817e37b70ebf4a461a916e)
#03 pc 00000000005c4454 /apex/com.android.art/lib64/libart.so (art::ThreadList::FlipThreadRoots(art::Closure*, art::Closure*, art::gc::collector::GarbageCollector*, art::gc::GcPauseListener*)+1152) (BuildId: e841be9816817e37b70ebf4a461a916e)
#04 pc 0000000000254ff4 /apex/com.android.art/lib64/libart.so (art::gc::collector::ConcurrentCopying::FlipThreadRoots()+292) (BuildId: e841be9816817e37b70ebf4a461a916e)
#05 pc 00000000002536a0 /apex/com.android.art/lib64/libart.so (art::gc::collector::ConcurrentCopying::RunPhases()+1024) (BuildId: e841be9816817e37b70ebf4a461a916e)
#06 pc 000000000027700c /apex/com.android.art/lib64/libart.so (art::gc::collector::GarbageCollector::Run(art::gc::GcCause, bool)+300) (BuildId: e841be9816817e37b70ebf4a461a916e)
#07 pc 0000000000293e80 /apex/com.android.art/lib64/libart.so (art::gc::Heap::CollectGarbageInternal(art::gc::collector::GcType, art::gc::GcCause, bool)+4144) (BuildId: e841be9816817e37b70ebf4a461a916e)
#08 pc 0000000000004f08 /apex/com.android.art/lib64/libopenjdkjvm.so (JVM_GC+164) (BuildId: ef162aca91c49e678fee75b29fa972fb)
#09 pc 00000000000815fc /apex/com.android.art/javalib/arm64/boot.oat (art_jni_trampoline+124) (BuildId: aece9284df80b1815bdaf34e52f290399c49da97)
#10 pc 000000000009b620 /apex/com.android.art/javalib/arm64/boot.oat (java.lang.Runtime.gc+96) (BuildId: aece9284df80b1815bdaf34e52f290399c49da97)
#11 pc 0000000000133564 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: e841be9816817e37b70ebf4a461a916e)
#12 pc 00000000001a8a78 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200) (BuildId: e841be9816817e37b70ebf4a461a916e)
#13 pc 0000000000555598 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+468) (BuildId: e841be9816817e37b70ebf4a461a916e)
#14 pc 0000000000555738 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+92) (BuildId: e841be9816817e37b70ebf4a461a916e)
#15 pc 00000000003aba24 /apex/com.android.art/lib64/libart.so (art::JNI<false>::CallVoidMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+660) (BuildId: e841be9816817e37b70ebf4a461a916e)
#16 pc 00000000000283ac /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonodroid.so (_JNIEnv::CallVoidMethod(_jobject*, _jmethodID*, ...)+116) (BuildId: 6e521e11e0c16c91d944e41591484727b79a9f43)
#17 pc 0000000000026be0 /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonodroid.so (xamarin::android::internal::OSBridge::gc_cross_references(int, MonoGCBridgeSCC**, int, MonoGCBridgeXRef*)+224) (BuildId: 6e521e11e0c16c91d944e41591484727b79a9f43)
#18 pc 00000000000d8030 /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#19 pc 000000000011e0c8 /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#20 pc 000000000011aff0 /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#21 pc 000000000011abcc /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#22 pc 0000000000110074 /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#23 pc 00000000000e3568 /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#24 pc 00000000000a2950 /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#25 pc 00000000000a51e8 /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#26 pc 00000000001ecd04 /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#27 pc 00000000001eb12c /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#28 pc 00000000001e9e24 /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#29 pc 00000000002260a0 /data/app/~~QwSnIcJf7DGwRKt9OCBJBg==/osu.Framework.Tests.Android-ib8ldIfSgmF9U3iLixWhKA==/lib/arm64/libmonosgen-2.0.so (BuildId: 7310e0da105e448374721a35c0841ba1673fb87a)
#30 pc 0000000000005ba8 <anonymous:6d9600a000>
I thought maybe it was the video stuff from the most recent commits, but it doesn't appear to be, still happens if I build a revision before that.
Test game does work, surprisingly, but I would very much like to be able to run visual tests on a device. Going to hold off on testing the game-side pull for now.
My setup is windows + visual studio 2022 + dotnet 6.0.102 with the android workload enabled.
@bdach Since the workload is effectively preview, I'd suggest to update .NET SDK to latest first. I'm using SDK 6.0.201, and the version of Microsoft.Android.Sdk.Windows (located in C:\Program Files\dotnet\packs
) is 31.0.200-preview.14.106.
I've installed the Xamarin workload in Visual Studio, and the deployment just works like before. Maybe restarting Visual Studio/rebuilding or whatever can update the deployment action.
Is your crash happening on startup? As a remainder, fully uninstall previous versions and do full rebuild may cause difference.
Crash occurs immediately on startup yes. Uninstalled previous app versions from devices before.
Hopefully you can bring debugger working. Try to do dotnet build
and reopen VS or whatever. Since sample game is working, at least you should be able to step in until it crashes.
Video related issues shouldn't throw until you touch the video decoder tests.
You can also see if release build is working. The call stacks indicates something really bad. java_interop_jnienv_find_class
looks like misconfigured reflection, and the second one like crash from GC. Anyway, updating .NET SDK may resolve issue in mono itself.
I've jiggled everything I could think of (updated VS 2022, updated dotnet SDK, rebooted machine, cleaned solution), and looks like it helped for whatever reason, both issues are gone.
We may need to fast forward this a bit, as android builds started inexplicably failing yesterday and this pull seems to fix it.
Reminder: this requires deployment for Framework, Framework.Android and NativeLibs. After deploying NativeLibs, WarningAsError could be turned on for Android CI.
Just to confirm, there are no longer any issues with this across both osu and osu-framework projects, in either debug or release mode configs?
Confirmed following actions with latest commits of both PRs, in Debug and Release:
- Run framework test, play video and audio
- Login into production server
- Download a beatmap with video, play and run autoplay
If the SSL issue with downlevel OS found by @bdach is no longer present, I can't see any issue now.
Didn't find any issues last time I tested this.
Shall we look at getting this in after the next framework release?
With the interim android build fix merged I don't see any particular reason to hurry too much with these changes anymore. I don't have any more code/testing issues to point out at this juncture, so it all boils down as to when you get the time/space to figure out the tooling/deployment end issues (if any).
Unfortunately my android test device will no longer boot (suffered from a bulging battery but totally conked it now). Will test with emulator to make sure the tooling works I guess.
Using HttpClientHandler
or SocketsHttpHandler
was previously discussed. There were problems with both handlers on @bdach, @huoyaoyuan and my (Realme 6) test devices. Results were inconclusive and could change with different dotnet workload install android
versions. I've done the following testing to get a conclusive answer of which to use.
I've tested osu! with a local framework checkout with a matrix of devices and configurations. Main focus was testing the difference of HttpClientHandler
and SocketsHttpHandler
on Release
and Debug
build configurations. Additionally, Release
was tested with and without trimming.
HttpClientHandler
or SocketsHttpHandler
?
Changing HttpClientHandler
(the current default in this PR) to SocketsHttpHandler
(used on desktop net6.0):
diff --git a/osu.Framework/IO/Network/WebRequest.cs b/osu.Framework/IO/Network/WebRequest.cs
index 4fea6062b..f139ac6a7 100644
--- a/osu.Framework/IO/Network/WebRequest.cs
+++ b/osu.Framework/IO/Network/WebRequest.cs
@@ -154,7 +154,7 @@ private set
#if NET6_0_OR_GREATER
// SocketsHttpHandler causes crash in Android Debug, and seems to have compatibility issue on SSL
// Use platform HTTP handler which is invoked by HttpClientHandler for better compatibility and app size
- RuntimeInfo.IsMobile
+ RuntimeInfo.IsMobile && false
? new HttpClientHandler
{
Credentials = CredentialCache.DefaultCredentials,
Trimming
By default, Android will build with trimming enabled. To disable trimming, the following was added to both osu.Framework.Android.props
and osu.Android.props
:
<PropertyGroup>
<PublishTrimmed>false</PublishTrimmed>
</PropertyGroup>
The data
Realme 6 (API 30) | Release not trimmed | Release trimmed | Debug |
---|---|---|---|
HttpClientHandler | works fine | (!) login fails with MethodInfo nullref |
works fine |
SocketsHttpHandler | works fine | works fine | works fine |
Samsung A02s (API 30) | Release not trimmed | Release trimmed | Debug |
---|---|---|---|
HttpClientHandler | works fine | (!) login fails with MethodInfo nullref |
works fine |
SocketsHttpHandler | works fine | works fine | works fine |
LG Q6 (API 27) | Release not trimmed | Release trimmed | Debug |
---|---|---|---|
HttpClientHandler | works fine | (!) login fails with MethodInfo nullref |
works fine |
SocketsHttpHandler | (!) login fails with SSL error | (!) login fails with SSL error | (!) login fails with SSL error |
network.log
excerpts:
LG Q6, SocketsHttpHandler
, all configurations:
2022-07-08 21:11:22 [verbose]: Request to https://osu.ppy.sh/oauth/token failed with System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
2022-07-08 21:11:22 [verbose]: ---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
2022-07-08 21:11:22 [verbose]: ---> Interop+AndroidCrypto+SslException: Exception of type 'Interop+AndroidCrypto+SslException' was thrown.
2022-07-08 21:11:22 [verbose]: --- End of inner exception stack trace ---
2022-07-08 21:11:22 [verbose]: at System.Net.Security.SslStream.<ForceAuthenticationAsync>d__175`1[[System.Net.Security.AsyncReadWriteAdapter, System.Net.Security, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
2022-07-08 21:11:22 [verbose]: at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
2022-07-08 21:11:22 [verbose]: --- End of inner exception stack trace ---
2022-07-08 21:11:22 [verbose]: at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
2022-07-08 21:11:22 [verbose]: at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
2022-07-08 21:11:22 [verbose]: at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
2022-07-08 21:11:22 [verbose]: at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(HttpRequestMessage request)
2022-07-08 21:11:22 [verbose]: at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.<WaitWithCancellationAsync>d__1[[System.Net.Http.HttpConnection, System.Net.Http, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
2022-07-08 21:11:22 [verbose]: at System.Net.Http.HttpConnectionPool.GetHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
2022-07-08 21:11:22 [verbose]: at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
2022-07-08 21:11:22 [verbose]: at System.Net.Http.AuthenticationHelper.SendWithAuthAsync(HttpRequestMessage request, Uri authUri, Boolean async, ICredentials credentials, Boolean preAuthenticate, Boolean isProxyAuth, Boolean doRequestAuth, HttpConnectionPool pool, CancellationToken cancellationToken)
2022-07-08 21:11:22 [verbose]: at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
2022-07-08 21:11:22 [verbose]: at System.Net.Http.DecompressionHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
2022-07-08 21:11:22 [verbose]: at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
2022-07-08 21:11:22 [verbose]: at osu.Framework.IO.Network.WebRequest.internalPerform(CancellationToken cancellationToken).
2022-07-08 21:11:22 [verbose]: Login failed!
All devices, HttpClientHandler
, Release trimmed:
2022-07-08 19:26:36 [verbose]: Request to https://osu.ppy.sh/oauth/token failed with System.ArgumentNullException: ArgumentNull_Generic Arg_ParamName_Name, method
2022-07-08 19:26:36 [verbose]: at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure, Boolean allowClosed)
2022-07-08 19:26:36 [verbose]: at System.Delegate.CreateDelegate(Type type, MethodInfo method, Boolean throwOnBindFailure)
2022-07-08 19:26:36 [verbose]: at System.Delegate.CreateDelegate(Type type, MethodInfo method)
2022-07-08 19:26:36 [verbose]: at Java.Interop.JavaConvert.GetJniHandleConverterForType(Type )
2022-07-08 19:26:36 [verbose]: at Java.Interop.JavaConvert.GetJniHandleConverter(Type )
2022-07-08 19:26:36 [verbose]: at Java.Interop.JavaConvert.FromJniHandle[IList`1](IntPtr , JniHandleOwnership , Boolean& )
2022-07-08 19:26:36 [verbose]: at Java.Interop.JavaConvert.FromJniHandle[IList`1](IntPtr , JniHandleOwnership )
2022-07-08 19:26:36 [verbose]: at Android.Runtime.JavaDictionary`2[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Collections.Generic.IList`1[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Get(String )
2022-07-08 19:26:36 [verbose]: at Android.Runtime.JavaDictionary`2[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Collections.Generic.IList`1[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].get_Item(String )
2022-07-08 19:26:36 [verbose]: at Xamarin.Android.Net.AndroidMessageHandler.CopyHeaders(HttpURLConnection , HttpResponseMessage )
2022-07-08 19:26:36 [verbose]: at Xamarin.Android.Net.AndroidMessageHandler.DoProcessRequest(HttpRequestMessage , URL , HttpURLConnection , CancellationToken , RequestRedirectionState )
2022-07-08 19:26:36 [verbose]: at Xamarin.Android.Net.AndroidMessageHandler.SendAsync(HttpRequestMessage , CancellationToken )
2022-07-08 19:26:36 [verbose]: at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage , HttpCompletionOption , CancellationTokenSource , Boolean , CancellationTokenSource , CancellationToken )
2022-07-08 19:26:36 [verbose]: at osu.Framework.IO.Network.WebRequest.internalPerform(CancellationToken cancellationToken).
2022-07-08 19:26:36 [verbose]: Login failed!
Building methodology
- o!f commit: b198d30726520bd3e3e1c257dc591c944ba098d7
- osu! commit: 10269b7613b3f913f1dcf9c9d5059ad6b7cbd614
- Latest
dotnet workload install android
- (If I'm reading this right, it is version
6.0.6
:Microsoft.AOT.win-x64.Cross.android-arm64.6.0.6.msi
)
- (If I'm reading this right, it is version
- Local checkout of o!f on
osu.Android.slnf
- Clean osu! and osu!framework solutions
- Build
osu.Framework.Android
with the specified configuration
- For
Debug
- Run osu! with the specified configuration
- (debug apks created with
Archive for Publish
would crash on startup)
- For
Release
- Right click on
osu.Android
and selectArchive for Publish
- Install .apks on tested device using
adb install
- Right click on
Testing methodology
- Open osu!
- Log in
- Download a single beatmap from my profile / beatmap listing
- Play it
- Check that the results loaded / beatmap successfuly finished
- Put the game to background
- Repeat for the next version in the test matrix
For my own sanity, I played a different song each time :)
For the LG Q6, I only did steps 1.-3., phone was too laggy to play properly.
Conclusion
SocketsHttpHandler
is used on desktop platforms, and works fine on modern Android versions (Android 11), but has problems with SSL on older version (Android 8.1). HttpClientHandler
does not work with trimming enabled. Trimming is not currently enables on desktop (as far as I'm aware).
Going forward, trimming should be disabled in Android .props
. HttpClientHandler
should be kept for best compatibility. If using SocketsHttpHandler
is beneficial, it could be used, but on modern Android versions only.
Concerns about SocketsHttpHandler
increasing file size were brought up, but the file sizes don't really differ much. (Except debug, probably why the app crashed -- missing libraries.)
Closing question
Does (not) using SocketsHttpHandler
have any effect on (future) use of websockets? (I've seen talk of using websockets for chat.)
I can login with the default trimming option in Release. I didn't build framework in Release though.
The trimming issue looks like https://github.com/ppy/osu/pull/17462/commits/9b50fa346ff2868e160e2f8f9cd669593a180f1f , which is already resolved newer SDK.
@Susko3 can you confirm your android SDK version at dotnet\packs\Microsoft.Android.Runtime.32.android-arm64
? Mine is 32.0.415
. Can you run dotnet workload update
to ensure you are at latest version?
If you decompile the assembly at 32.0.xxx\runtimes\android-arm64\lib\net6.0\Mono.Android.dll
, can you see the trimmer annotation on the method?
Or, does it work if you redo the workaround in that commit? I reverted it because it was fixed in SDK.
I was on 31.0.200-preview.14.106
. No amount of dotnet workload update
and install
would get me to version 32. Probably because I was using dotnet
version 6.0.203
. Downloading the newer version (6.0.301
) now (will take some time, crappy internet).
Can confirm that the aforementioned method does not have the trimmer annotation.
This is really fucking stupid. Is there some way to block or show a warning/error to people (like me) who are using older versions.
Using global.json
in the root of the repo works (errors on build). Using global.json
in osu.Framework.Android
folder does not work. iOS seems to be using global.json
in the subfolder.
Specifying the exact SDK version in the .csproj is hit or miss, sometimes giving warnings, sometimes building fine:
diff --git a/osu.Framework.Android/osu.Framework.Android.csproj b/osu.Framework.Android/osu.Framework.Android.csproj
index 819f5306f..d6a6063fe 100644
--- a/osu.Framework.Android/osu.Framework.Android.csproj
+++ b/osu.Framework.Android/osu.Framework.Android.csproj
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk/6.0.301">
<PropertyGroup Label="Project">
<TargetFramework>net6.0-android</TargetFramework>
<SupportedOSPlatformVersion>21.0</SupportedOSPlatformVersion>
(I've done this testing with 6.0.203
installed only, I didn't have 6.0.301
installed.)