MirrorNetworking / Mirror

#1 Open Source Unity Networking Library
https://mirror-networking.com
MIT License
5.17k stars 767 forks source link

NullReferenceException on NetworkWritter.WriteBlittable[T] #2511

Closed hernancasta closed 3 years ago

hernancasta commented 3 years ago

Describe the bug Android Platform: NullReferenceException on NetworkWritter.WriteBlittable[T]

To Reproduce Steps to reproduce the behavior:

  1. Open the scene Mirror -> Examples -> Basic -> Scenes -> Example
  2. Switch to Android Platform
  3. Build and Run in Android Device
  4. Play the Scene in the Editor.
  5. Click on Host (Server + Client)
  6. In the android device fill the Server IP Address and click Client.
  7. The android device raises a NullReference exception and does not connect.

Expected behavior Connect to the server.

Screenshots image

Desktop (please complete the following information):

Additional context

Was tested in Android Phone and also in Oculus Quest, same error. Also tried Api compatibility level .NET Standard 2.0 and .NET 4.X, and Allow 'unsafe' code build.

The exception is the following (logged with Android LogCat)

System.NullReferenceException: Object reference not set to an instance of an object
at Mirror.NetworkWriter.WriteBlittable[T] (T value) [0x0002d] in C:\SourceCode\test\TestMirrorAndroid\Assets\Mirror\Runtime\NetworkWriter.cs:205 
at Mirror.NetworkWriterExtensions.WriteDouble (Mirror.NetworkWriter writer, System.Double value) [0x00000] in C:\SourceCode\test\TestMirrorAndroid\Assets\Mirror\Runtime\NetworkWriter.cs:275 
at Mirror.GeneratedNetworkCode._Write_Mirror.NetworkPingMessage (Mirror.NetworkWriter writer, Mirror.NetworkPingMessage value) [0x00000] in <8a21cd7c96354b98b347092db11381e5>:0 
at (wrapper delegate-invoke) System.Action`2[Mirror.NetworkWriter,Mirror.NetworkPingMessage].invoke_void_T1_T2(Mirror.NetworkWriter,Mirror.NetworkPingMessage)
at Mirror.NetworkWriter.Write[T] (T value) [0x00033] in C:\SourceCode\test\TestMirrorAndroid\Assets\Mirror\Runtime\NetworkWriter.cs:242 
at Mirror.MessagePacker.Pack[T] (T message, Mirror.NetworkWriter writer) [0x00010] in C:\SourceCode\
andrelevi commented 3 years ago

I'm getting the same error on my Oculus Quest 1/2 builds, right when blitting the double for Mirror.NetworkPingMessage. To debug, I tried removing all NetworkBehaviours from the scene, in case some other serialization code was corrupting the network writer, and I still got this error at writing the Mirror.NetworkPingMessage. I don't get in this in the Editor, only on my Android Oculus Quest builds.

I ended up having to use the previous stable version 26.2.2 on the AssetStore that doesn't use the new optimized Read/WriteBittable changes in 28.1.3.

SoftwareGuy commented 3 years ago

Alright - I'll check this out and see if I can replicate it, I have an Android 7.0 device and a Android 8.0 device that should be helpful during testing.

I'll test this on 2019.4.x LTS, as it may be specific to 2020.x versions of Unity.

I'm currently on holidays but I will investigate further and do testing on mobile for Android (both ARMv7 and ARM64). Please be patient during this time, don't ask for ETAs.

vladbasin commented 3 years ago

Same issue after testing on real Android device (Google Pixel 3).

SoftwareGuy commented 3 years ago

Can't compile for ARM64 with Mono, so I'm going to have to test on both backends - Mono and IL2CPP.

SoftwareGuy commented 3 years ago

Replication results so far:

Elephone S8 (Android 7.1.1) Mono: Does not connect. Mirror throws a lot of errors seen in adb logcat. IL2CPP: Connects fine. No NullReferenceExceptions.

This looks like it's a Mono-specific thing. Why that is I don't know, unless something's not quite right.

SoftwareGuy commented 3 years ago

Should be noted I am using Mirror version 30.2.1.

miwarnec commented 3 years ago

Looks like a mono bug. If anyone could look into it, please do. I have neither android nor oculus. You could add a Debug.Log to check which part is null. That would help.

miwarnec commented 3 years ago

Note that this works on all other platforms. If anyone could report this to unity and share the case number, please do :)

vladbasin commented 3 years ago

It still fails on my Google Pixel 3a (Android 10). Even with IL2CPP. No matter if I start Client or Host from NetworkManager HUD.

2020-12-29 22:27:05.663 3003-3219/com.DefaultCompany.bittenunity E/AndroidRuntime: FATAL EXCEPTION: UnityMain
    Process: com.DefaultCompany.bittenunity, PID: 3003
    java.lang.Error: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    Version '2020.1.17f1 (9957aee8edc2)', Build type 'Development', Scripting Backend 'il2cpp', CPU 'armeabi-v7a'
    Build fingerprint: 'google/sargo/sargo:10/QQ3A.200705.002/6506677:user/release-keys'
    Revision: 'MP1.0'
    ABI: 'arm'
    Timestamp: 2020-12-30 03:27:05+0800
    pid: 3003, tid: 3219, name: UnityMain  >>> com.DefaultCompany.bittenunity <<<
    uid: 10560
    signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr 0xb6dae812
        r0  b6dae802  r1  24e14eb7  r2  c321d28c  r3  ba50c000
        r4  b6d46ac8  r5  b6dae800  r6  00000002  r7  c32f95d4
        r8  3f09be17  r9  2763f218  r10 00000001  r11 c183d3a8
        ip  c32f7984  sp  c183d388  lr  c1c49d5c  pc  c1ddba78

    backtrace:
          #00 pc 00598a78  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #01 pc 0153de00  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #02 pc 008c4cd4  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #03 pc 0115f690  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #04 pc 012dc924  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #05 pc 00f949ec  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #06 pc 012ce0ac  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #07 pc 012cca60  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #08 pc 0153c2ac  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #09 pc 00d18d70  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #10 pc 0094250c  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #11 pc 00942530  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #12 pc 00942530  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #13 pc 01567b58  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #14 pc 01566174  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #15 pc 002ec26c  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #16 pc 00409cec  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libil2cpp.so (BuildId: 87234dbe12c41aa831d91c1522e13b9cdbb45a6e)
          #17 pc 00469745  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libunity.so (scripting_method_invoke(ScriptingMethodPtr, ScriptingObjectPtr, ScriptingArguments&, ScriptingExceptionPtr*, bool)+92) (BuildId: 14163392fc28af38afce63e5aeb2bf1d6694eda6)
2020-12-29 22:27:05.664 3003-3219/com.DefaultCompany.bittenunity E/AndroidRuntime:       #18 pc 00475423  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libunity.so (ScriptingInvocation::Invoke(ScriptingExceptionPtr*, bool)+94) (BuildId: 14163392fc28af38afce63e5aeb2bf1d6694eda6)
          #19 pc 0047ce8b  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libunity.so (MonoBehaviour::CallUpdateMethod(int)+158) (BuildId: 14163392fc28af38afce63e5aeb2bf1d6694eda6)
          #20 pc 001f5051  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libunity.so (void BaseBehaviourManager::CommonUpdate<LateBehaviourManager>()+116) (BuildId: 14163392fc28af38afce63e5aeb2bf1d6694eda6)
          #21 pc 001f4fc9  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libunity.so (LateBehaviourManager::Update()+16) (BuildId: 14163392fc28af38afce63e5aeb2bf1d6694eda6)
          #22 pc 002ba8b9  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libunity.so (InitPlayerLoopCallbacks()::PreLateUpdateScriptRunBehaviourLateUpdateRegistrator::Forward()+44) (BuildId: 14163392fc28af38afce63e5aeb2bf1d6694eda6)
          #23 pc 002b4c35  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libunity.so (ExecutePlayerLoop(NativePlayerLoopSystem*)+52) (BuildId: 14163392fc28af38afce63e5aeb2bf1d6694eda6)
          #24 pc 002b4c69  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libunity.so (ExecutePlayerLoop(NativePlayerLoopSystem*)+104) (BuildId: 14163392fc28af38afce63e5aeb2bf1d6694eda6)
          #25 pc 002b4e19  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libunity.so (PlayerLoop()+264) (BuildId: 14163392fc28af38afce63e5aeb2bf1d6694eda6)
          #26 pc 004d5431  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libunity.so (UnityPlayerLoop()+496) (BuildId: 14163392fc28af38afce63e5aeb2bf1d6694eda6)
          #27 pc 004f86e9  /data/app/com.DefaultCompany.bittenunity-dforDQPcH-JTr5QEF4PYoA==/lib/arm/libunity.so (nativeRender(_JNIEnv*, _jobject*)+40) (BuildId: 14163392fc28af38afce63e5aeb2bf1d6694eda6)
          #28 pc 000dc519  /apex/com.android.runtime/lib/libart.so (art_quick_generic_jni_trampoline+40) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #29 pc 000d7bc5  /apex/com.android.runtime/lib/libart.so (art_quick_invoke_stub_internal+68) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #30 pc 0042f1ef  /apex/com.android.runtime/lib/libart.so (art_quick_invoke_stub+250) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #31 pc 000dffc1  /apex/com.android.runtime/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+176) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #32 pc 00210ea1  /apex/com.android.runtime/lib/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+280) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #33 pc 0020c86b  /apex/com.android.runtime/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+794) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #34 pc 0021841b  /apex/com.android.runtime/lib/libart.so (void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*)+13210) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #35 pc 000dd075  /apex/com.android.runtime/lib/libart.so (ExecuteSwitchImplAsm+4) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #36 pc 001ec7a9  /apex/com.android.runtime/lib/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.532636813752178127)+368) (BuildId: 195ca8f80218b4083b72bae65383df1e)
2020-12-29 22:27:05.666 3003-3219/com.DefaultCompany.bittenunity E/AndroidRuntime:       #37 pc 001f0f85  /apex/com.android.runtime/lib/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+156) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #38 pc 0020c851  /apex/com.android.runtime/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+768) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #39 pc 00215a73  /apex/com.android.runtime/lib/libart.so (void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*)+2546) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #40 pc 000dd075  /apex/com.android.runtime/lib/libart.so (ExecuteSwitchImplAsm+4) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #41 pc 001ec7a9  /apex/com.android.runtime/lib/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.532636813752178127)+368) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #42 pc 001f0f85  /apex/com.android.runtime/lib/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+156) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #43 pc 0020c851  /apex/com.android.runtime/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+768) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #44 pc 0021a091  /apex/com.android.runtime/lib/libart.so (void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*)+20496) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #45 pc 000dd075  /apex/com.android.runtime/lib/libart.so (ExecuteSwitchImplAsm+4) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #46 pc 001ec7a9  /apex/com.android.runtime/lib/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.532636813752178127)+368) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #47 pc 001f0ea1  /apex/com.android.runtime/lib/libart.so (art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*)+124) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #48 pc 00418bf1  /apex/com.android.runtime/lib/libart.so (artQuickToInterpreterBridge+804) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #49 pc 000dc5a1  /apex/com.android.runtime/lib/libart.so (art_quick_to_interpreter_bridge+32) (BuildId: 195ca8f80218b4083b72bae65383df1e)
          #50 pc 0201ab1b  /memfd:/jit-cache (deleted)

        at libil2cpp.0x598a78(Native Method)
        at libil2cpp.0x153de00(Native Method)
        at libil2cpp.0x8c4cd4(Native Method)
        at libil2cpp.0x115f690(Native Method)
        at libil2cpp.0x12dc924(Native Method)
        at libil2cpp.0xf949ec(Native Method)
        at libil2cpp.0x12ce0ac(Native Method)
        at libil2cpp.0x12cca60(Native Method)
        at libil2cpp.0x153c2ac(Native Method)
        at libil2cpp.0xd18d70(Native Method)
        at libil2cpp.0x94250c(Native Method)
        at libil2cpp.0x942530(Native Method)
        at libil2cpp.0x942530(Native Method)
        at libil2cpp.0x1567b58(Native Method)
        at libil2cpp.0x1566174(Native Method)
        at libil2cpp.0x2ec26c(Native Method)
        at libil2cpp.0x409cec(Native Method)
        at libunity.scripting_method_invoke(ScriptingMethodPtr, ScriptingObjectPtr, ScriptingArguments&, ScriptingExceptionPtr*, bool)(scripting_method_invoke:92)
        at libunity.ScriptingInvocation::Invoke(ScriptingExceptionPtr*, bool)(Invoke:94)
        at libunity.MonoBehaviour::CallUpdateMethod(int)(CallUpdateMethod:158)
        at libunity.void BaseBehaviourManager::CommonUpdate<LateBehaviourManager>()(CommonUpdate<LateBehaviourManager>:116)
        at libunity.LateBehaviourManager::Update()(Update:16)
2020-12-29 22:27:05.667 3003-3219/com.DefaultCompany.bittenunity E/AndroidRuntime:     at libunity.InitPlayerLoopCallbacks()::PreLateUpdateScriptRunBehaviourLateUpdateRegistrator::Forward()(InitPlayerLoopCallbacks:44)
        at libunity.ExecutePlayerLoop(NativePlayerLoopSystem*)(ExecutePlayerLoop:52)
        at libunity.ExecutePlayerLoop(NativePlayerLoopSystem*)(ExecutePlayerLoop:104)
        at libunity.PlayerLoop()(PlayerLoop:264)
        at libunity.UnityPlayerLoop()(UnityPlayerLoop:496)
        at libunity.nativeRender(_JNIEnv*, _jobject*)(nativeRender:40)
        at libart.art_quick_generic_jni_trampoline(art_quick_generic_jni_trampoline:40)
        at libart.art_quick_invoke_stub_internal(art_quick_invoke_stub_internal:68)
        at libart.art_quick_invoke_stub(art_quick_invoke_stub:250)
        at libart.art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)(Invoke:176)
2020-12-29 22:27:05.709 3003-3003/com.DefaultCompany.bittenunity I/Unity: onPause
2020-12-29 22:27:05.724 3003-3219/com.DefaultCompany.bittenunity I/Process: Sending signal. PID: 3003 SIG: 9

@SoftwareGuy do you have any idea why?

vladbasin commented 3 years ago

Observation after some debugging:

            fixed (byte* ptr = &buffer[Position])
            {
                // cast buffer to T* pointer, then assign value to the area
                *(T*)ptr = value;
            }

The exception of NullPointerReference happens during conversion to type T.

SoftwareGuy commented 3 years ago

Will add some debug scaffolding around the problematic function, hopefully I can cause it to stop spamming and just throw a single exception.

SoftwareGuy commented 3 years ago

Well that didn't work. Here's what we know, comments show the debugging flow:

        public unsafe void WriteBlittable<T>(T value) where T : unmanaged
        {
            // check if blittable for safety
#if UNITY_EDITOR
            if (!UnsafeUtility.IsBlittable(typeof(T)))
            {
                Debug.LogError(typeof(T) + " is not blittable!");
                return;
            }
#endif
            // Check for null type...
            if (typeof(T) == null)
            {
                Debug.LogError("Potential Mono Bug: typeof(T) == NULL. Blame Unity's Mono for this one.");
                return;
            }
            // --- PASSES --- //

            int size = sizeof(T);
            EnsureLength(position + size);

            fixed (byte* ptr = &buffer[Position])
            {
                if(ptr == null)
                {
                    Debug.LogError("ptr is NULL !!");
                    return;
                }
                // --- PASSES --- //

                if (typeof(T) == null)
                {
                    Debug.LogError("Potential Mono Bug: typeof(T) == NULL. Blame Unity's Mono for this one.");
                    return;
                }
                // --- PASSES --- //

                // cast buffer to T* pointer, then assign value to the area
                *(T*)ptr = value;
                // --- FAILURE --- //
            }
            Position += size;
        }

Should I just throw the project at Unity Tech and tell them about the NullPointerReference problem with Mono, hoping we get a fix within the next year?

SoftwareGuy commented 3 years ago

Okay, I dug deeper. And it only affects ARMv7 it seems, ARM64 works fine.

What we're getting is a SIGBUS BUS_ADRALN error. That means that it's a Address Alignment error and usually we're reading or writing through a pointer that's giving us bad data.

JesusLuvsYooh commented 3 years ago

Isn't ARMv7 deprecated and being removed from both Unity and Google player/Android?