stripe / stripe-terminal-android

Stripe Terminal Android SDK
https://stripe.dev/stripe-terminal-android/
Other
94 stars 46 forks source link

"LOCAL_MOBILE_UNSUPPORTED_DEVICE | Localmobile reader not operating in secure process" error when discovering Tap to Pay (localmobile) readers #520

Open ivantespass opened 3 weeks ago

ivantespass commented 3 weeks ago

We are facing crashes targeting API Level 34 (on multiple devices, all of them are listed here https://docs.stripe.com/terminal/payments/setup-reader/tap-to-pay?platform=android#supported-devices) after update to v3.8 (it seems that reader is discovered and connected, then app crashes)

With v3.9 and v3.10 (with non-simulated readers) we are facing an error instead:

> 2024-10-29 10:42:16.487 19220-19823 DOTNET                  net.mycompany.myapp             I  LOG - Trace >> [STRIPE TERMINAL] Local Discovery timeout
> 2024-10-29 10:42:16.489 19220-19823 DOTNET                  net.mycompany.myapp             I  LOG - Trace >> [STRIPE TERMINAL] Discovery ErrorCode: LOCAL_MOBILE_UNSUPPORTED_DEVICE
> 2024-10-29 10:42:16.489 19220-19823 DOTNET                  net.mycompany.myapp             I  LOG - Trace >> [STRIPE TERMINAL] Discovery ErrorMessage: Localmobile reader not operating in secure process
> 2024-10-29 10:42:16.490 19220-19823 DOTNET                  net.mycompany.myapp             I  LOG - Error >> reader_discover_error
> 2024-10-29 10:42:16.490 19220-19823 DOTNET                  net.mycompany.myapp             I  LOG - Exception >> 
>                                                                                                       --- End of managed Com.Stripe.Stripeterminal.External.Models.TerminalException stack trace ---
>                                                                                                     com.stripe.stripeterminal.external.models.TerminalException: Localmobile reader not operating in secure process
> 2024-10-29 10:42:16.490 19220-19823 DOTNET                  net.mycompany.myapp             I     at com.stripe.stripeterminal.internal.common.adapter.CotsAdapter.checkAndThrowCotsError(CotsAdapter.kt:627)
>                                                                                                       at com.stripe.stripeterminal.internal.common.adapter.CotsAdapter.access$checkAndThrowCotsError(CotsAdapter.kt:83)
> 2024-10-29 10:42:16.490 19220-19823 DOTNET                  net.mycompany.myapp             I     at com.stripe.stripeterminal.internal.common.adapter.CotsAdapter$DiscoverReadersOperation.execute(CotsAdapter.kt:709)
>                                                                                                       at com.stripe.stripeterminal.internal.common.adapter.CotsAdapter$DiscoverReadersOperation.execute(CotsAdapter.kt:701)
> 2024-10-29 10:42:16.490 19220-19823 DOTNET                  net.mycompany.myapp             I     at com.stripe.stripeterminal.internal.common.adapter.CotsAdapter.discoverReaders(CotsAdapter.kt:514)
>                                                                                                       at com.stripe.stripeterminal.internal.common.adapter.ProxyAdapter.discoverReaders(ProxyAdapter.kt:259)
> 2024-10-29 10:42:16.490 19220-19823 DOTNET                  net.mycompany.myapp             I     at com.stripe.stripeterminal.internal.common.terminalsession.TerminalSession$DiscoverReadersOperation.executeIfNotCanceled(TerminalSession.kt:2439)
>                                                                                                       at com.stripe.stripeterminal.internal.common.terminalsession.TerminalSession$CancelableOperation.execute(TerminalSession.kt:1319)
> 2024-10-29 10:42:16.490 19220-19823 DOTNET                  net.mycompany.myapp             I     at com.stripe.stripeterminal.internal.common.terminalsession.TerminalSession$ExternalOperation.run$terminalsession_release(TerminalSession.kt:1274)
>                                                                                                       at com.stripe.stripeterminal.internal.common.terminalsession.TerminalSession.enqueueOperation$lambda$6(TerminalSession.kt:1089)
> 2024-10-29 10:42:16.490 19220-19823 DOTNET                  net.mycompany.myapp             I     at com.stripe.stripeterminal.internal.common.terminalsession.TerminalSession.$r8$lambda$6lM7341_XI6PEqXfOM-yc2U5tkQ(Unknown Source:0)
>                                                                                                       at com.stripe.stripeterminal.internal.common.terminalsession.TerminalSession$$ExternalSyntheticLambda0.run(Unknown Source:4)
> 2024-10-29 10:42:16.490 19220-19823 DOTNET                  net.mycompany.myapp             I     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:487)
>                                                                                                       at java.util.concurrent.FutureTask.run(FutureTask.java:264)
>                                                                                                       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
>                                                                                                       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
> 2024-10-29 10:42:16.490 19220-19823 DOTNET                  net.mycompany.myapp             I     at java.lang.Thread.run(Thread.java:1012)
> 2024-10-29 10:42:16.490 19220-19823 DOTNET                  net.mycompany.myapp             I  LOG - >> Errore discovering readers: Localmobile reader not operating in secure process

I clarify that we are using MAUI and Java Binding Project to wrap Stripe Terminal Android SDK: with v3.7.1 we don't get any error or exception and all works as excepted both in develop and release mode, both with simulated and non-simulated readers.

If it can be useful, error seems also related to a workaround used in MAUI to correctly define and declare :stripelocalmobile inner SDK process, in our autogenerated manifest:

[Service(Process = ":stripelocalmobile")] public class DummyService : Service { }

Above code snippet is inserted in our code to resolve this open issue (with v3.7.1 all works as excepted): https://github.com/dotnet/android/issues/8675

Is it possible that something changed related to that process management, between v3.7.1 and latest ones? Any ideas?

Originally posted by @ivantespass in https://github.com/stripe/stripe-terminal-android/issues/479#issuecomment-2443824246

chr-stripe commented 1 week ago

Hi @ivantespass, thanks for reaching out. The Tap to Pay on Android SDK runs mostly in a separate process for increased security when processing payment data. For that reason, we enforce that there are no other Android components also running in that process that are declared by the integrating application.

I suspect this is the issue your workaround is running into. Can you explain a bit more why this is needed? I reviewed the issue you mentioned (which is helpful, thanks!) but not entirely understanding what it's doing or why it's necessary.