stripe / stripe-terminal-android

Stripe Terminal Android SDK
Other
79 stars 43 forks source link

My Android device cannot reconnect to the card reader after running for a long time #443

Open 1970578978 opened 2 months ago

1970578978 commented 2 months ago

Summary

When the card reader connection is abnormal, my program will immediately try to reconnect to the card reader. This function has been working very well and can be reconnected every time the card reader is restarted every day. But as long as my Android device is powered on for a long time and connected to the card reader, it will no longer be able to connect to the card reader. I have caught the exception. Please help me find out the specific reason. Thanks

Code to reproduce

`

private void disconnectReadAndReconnect(){
    Callback callback = new Callback() {
        @Override
        public void onSuccess() {
            discoveryTask();
        }

        @Override
        public void onFailure(@NonNull TerminalException e) {
        }
    };
    Terminal.getInstance().disconnectReader(callback);          //
}
@Override
public void onUnexpectedReaderDisconnect(@NonNull Reader reader) {
    disconnectReadAndReconnect();
}

 public void discoveryTask(){
    if(viewModel.discoveryTask != null){
        return;
    }
    LogUtils.d("discoveryTask", "to discovery");
    final DiscoveryListener discoveryListener = new DiscoveryReadersListener(activityRef, viewModel);

    final Callback discoveryCallback = new Callback() {
        @Override
        public void onSuccess() {
            Log.e("discoveryCallback", "discoverySuccess");
            viewModel.discoveryTask = null;
        }

        @Override
        public void onFailure(@NotNull TerminalException e) {
            Log.e("discoveryCallback", "discoveryFailure");
            if(viewModel != null){
                viewModel.discoveryTask = null;
                discoveryTask();
            }
        }
    };

    final DiscoveryConfiguration config = new DiscoveryConfiguration(
            0, PublicStatic.ReaderMethod, false);
    if (viewModel.discoveryTask == null && Terminal.getInstance().getConnectedReader() == null) {
        viewModel.discoveryTask = Terminal
                .getInstance()
                .discoverReaders(config, discoveryListener, discoveryCallback);
    }

}

`

Android version

android 7.1

Impacted devices (Android devices or readers)

SDK version

implementation "com.stripe:stripeterminal:2.23.0"

Other information

com.stripe.stripeterminal.external.models.TerminalException: Unexpected failure
        at com.stripe.stripeterminal.internal.common.adapter.BbposAdapter.onUnexpectedFailure(BbposAdapter.kt:513)
        at com.stripe.stripeterminal.internal.common.adapter.BbposAdapter$register$13.accept(BbposAdapter.kt:420)
        at com.stripe.stripeterminal.internal.common.adapter.BbposAdapter$register$13.accept(BbposAdapter.kt:420)
        at io.reactivex.rxjava3.internal.observers.LambdaObserver.onNext(LambdaObserver.java:63)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:202)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:256)
        at io.reactivex.rxjava3.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:324)
        at io.reactivex.rxjava3.internal.schedulers.ExecutorScheduler$ExecutorWorker.runEager(ExecutorScheduler.java:289)
        at io.reactivex.rxjava3.internal.schedulers.ExecutorScheduler$ExecutorWorker.run(ExecutorScheduler.java:250)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)
Caused by: com.stripe.jvmcore.hardware.status.ReaderException: INVALID_FUNCTION_IN_CURRENT_CONNECTION_MODE: Cannot start USB again while USB is connecting
        at com.stripe.core.bbpos.hardware.BbposControllerListener.onError(BbposControllerListener.kt:150)
        at com.stripe.core.bbpos.hardware.BbposPaymentCollectionListener.onError(BbposPaymentCollectionListener.kt:519)
        at com.stripe.core.bbpos.hardware.DeviceListenerRegistryImpl$onError$1.invoke(DeviceListenerRegistryImpl.kt:227)
        at com.stripe.core.bbpos.hardware.DeviceListenerRegistryImpl$onError$1.invoke(DeviceListenerRegistryImpl.kt:227)
        at com.stripe.core.bbpos.hardware.DeviceListenerRegistryImpl.notifyAll(DeviceListenerRegistryImpl.kt:51)
        at com.stripe.core.bbpos.hardware.DeviceListenerRegistryImpl.onError(DeviceListenerRegistryImpl.kt:227)
        at com.stripe.core.bbpos.BbposDeviceListenerWrapperImpl.onError(BbposDeviceListenerWrapperImpl.kt:281)
        at com.stripe.bbpos.bbdevice.BBDeviceController.aaa000(SourceFile:855)
        at com.stripe.bbpos.bbdevice.BBDeviceController.$r8$lambda$dkbPx1gAaZ7RXwJAM3VC5uMi-Gk(SourceFile)
        at com.stripe.bbpos.bbdevice.BBDeviceController$$ExternalSyntheticLambda96.run(D8$$SyntheticClass)
        at android.os.Handler.handleCallback(Handler.java:755)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6121)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
1970578978 commented 2 months ago

Can anyone please help us looking into this issue? @gliu-stripe All the problems I encountered were solved by restarting the device. Why does the card reader restart every day? I'm thinking about whether it's necessary to add an automatic restart function to the device.

basitjawaid commented 2 months ago

facing the same issue with m2 Reader Android 11 device

ugochukwu-stripe commented 1 month ago

Hi folks, are you able to reproduce this issue with the latest SDK and example application? We fixed a similar issue in later sdks where there was a rogue listener to the reader on discovery that was triggering an unexpected disconnect event when it should not. Also regarding automatically reconnecting, have you tried the auto-reconnect feature the sdk supports ^1, available since 2.12^2 to help with reconnecting to the reader on reboot?

basitjawaid commented 1 month ago

@ugochukwu-stripe Hi Thanks for your response, I have checked two sdks where this issue still persists and we constantly face this bug after every few days.

SDK version

3.2.0 & 2.23.0

Android version

android 11

ugochukwu-stripe commented 1 month ago

@basitjawaid the fix for this went into the 3.3.0 release, so let us know if you still see this issue after upgrading to 3.3.0+

1970578978 commented 1 month ago

@ugochukwu-stripe Sorry, I can't test the 3.3 SDK yet, because we have a large number of Android 7.0 devices.

basitjawaid commented 1 month ago

@ugochukwu-stripe I have integrated the SDK 3.4.0 today, will share my experience here.

1970578978 commented 1 month ago

@ugochukwu-stripe I have integrated the SDK 3.4.0 today, will share my experience here.

Hello brother, do you still have this problem when using 3.4.0?

basitjawaid commented 1 month ago

@ugochukwu-stripe I have integrated the SDK 3.4.0 today, will share my experience here.

Hello brother, do you still have this problem when using 3.4.0?

we have around 30 devices and we are actually testing on all the devices right now, we'll get back to you if we encounter any disconnection issue

1970578978 commented 1 month ago

@ugochukwu-stripe I have integrated the SDK 3.4.0 today, will share my experience here.

Hello brother, do you still have this problem when using 3.4.0?

we have around 30 devices and we are actually testing on all the devices right now, we'll get back to you if we encounter any disconnection issue

ok,thx

ugochukwu-stripe commented 3 weeks ago

@basitjawaid checking in, are you still experiencing the disconnection issue with 3.4.0 ?

basitjawaid commented 3 weeks ago

@ugochukwu-stripe Hi We have installed our application in 8 to 10 devices (with updated SDK) and all these devices are on different locations for different clients, after the update we did not hear anything from them about disconnection, as soon as will hear anything about this issue again I will let you know here.

xiaoshen-stripe commented 2 weeks ago

Hi @1970578978 Do you have any plan to upgrade your fleet of Android 7.0 devices to take advantage of the fix that went into V3.3+?

Also related - we will no longer provide support for V2.0 once it reaches its end-of-life date scheduled for October this year.

1970578978 commented 2 weeks ago

Hi @1970578978 Do you have any plan to upgrade your fleet of Android 7.0 devices to take advantage of the fix that went into V3.3+?

Also related - we will no longer provide support for V2.0 once it reaches its end-of-life date scheduled for October this year.

没有这个计划

1970578978 commented 2 weeks ago

Hi @ugochukwu-stripe Hello, I seem to have found the reason why the card reader cannot connect. In some cases, after using connectUsbReader readerCallback runs neither success nor failure callbacks. disconnectReader also doesn't work properly. I don’t know the specific triggering mechanism yet, but it seems to happen randomly now. Have you fixed this issue in 3.4?

ugochukwu-stripe commented 1 week ago

Hi @1970578978 , can you share the serial of the reader and the logs from the sdk from when this issue occurred, the connect reader callbacks not firing seems to be a different problem from the one we caught and fixed, at the very least you should get an error from the SDK.

1970578978 commented 1 week ago

@ugochukwu-stripe hello I get it ` onUpdateDiscoveredReaders

: Calling process is: com.mini.chargerPos getMetadata info/warning (3, 0) class=BbposControllerListener message=onUsbConnected LocationId:tml_EFfyAJci4F0jHN class=BbposUsbAdapter message=disconnectUnsafe() class=BbposUsbAdapter message="DiscoverReaders was canceled by the user" kotlinx.coroutines.JobCancellationException: StandaloneCoroutine was cancelled; job=StandaloneCoroutine{Cancelling}@aab7e7a class=TransactionManager message=endTransaction class=ConnectAndUpdateStateMachine message="onStateChanged: DISCOVER -> CANCELLED: null" class=ConnectAndUpdateStateMachine message="onStateChanged: CANCELLED -> EMPTY: Transaction cancelled" discoverySuccess class=TerminalStatusManager message=connecting. class=PaymentCollectionCoordinatorWrapper message="Updating devicePaymentCapability to PaymentCollectionDeviceCapability(directlyControlsScreenInput=false, supportExtendedTransaction=false, checkForCardBehavior=DO_NOT_POLL, supportedInterface=[MAGSTRIPE, ICC, NFC], retryUponPinCancel=false, quickEmvAutoResponse=true, retryUponTerminate=true)" class=ConnectAndUpdateStateMachine message="onStateChanged: EMPTY -> CONNECT: Connect requested" class=BbposReaderConnectionController message=connectUsb class=BbposReaderConnectionController message="deviceName for reader has changed" oldDeviceName=/dev/bus/usb/001/029 newDeviceName=/dev/bus/usb/001/030 productName=STRM26232012070 class=BbposControllerListener message="onError INVALID_FUNCTION_IN_CURRENT_CONNECTION_MODE, Cannot start USB again while USB is connected" class=BbposControllerListener message="INVALID_FUNCTION_IN_CURRENT_CONNECTION_MODE, continue the flow and fire onUsbConnected()" class=BbposControllerListener message=onUsbConnected class=ConnectAndUpdateStateMachine message="onStateChanged: CONNECT -> READER_INFO: null" close class=BbposControllerListener message=onUsbDisconnected START u0 {act=android.hardware.usb.action.USB_DEVICE_ATTACHED flg=0x11000000 cmp=com.mini.chargerPos/com.stripe.stripeterminal.internal.common.usb.UsbEventReceiverActivity (has extras)} from uid 1000 handleWindowVisibility: no activity for token android.os.BinderProxy@2630846 Calling a method in the system process without a qualified user: android.app.ContextImpl.sendBroadcast:1045 android.content.ContextWrapper.sendBroadcast:448 com.stripe.stripeterminal.internal.common.usb.UsbEventReceiverActivity.onResume:31 android.app.Instrumentation.callActivityOnResume:1453 android.app.Activity.performResume:7957 ` STRM26232012070 After successfully executing the callback discoveryCallback, I immediately unplugged the USB of the card reader and then connected it again. The success and failure callbacks of ReaderCallback are not executed, and I am wondering if the quality of my USB cable is causing me to be unable to connect to the card reader
1970578978 commented 3 days ago

I get new error msg, can you help me?

[2024-05-30 00:40:09][info]Crash Time: 2024-05-29 18:40:03

java.lang.RuntimeException: android.os.DeadSystemException at android.hardware.usb.UsbManager.getDeviceList(UsbManager.java:415) at com.stripe.core.bbpos.hardware.BbposReaderConnectionController.resolveUsbReader(BbposReaderConnectionController.kt:104) at com.stripe.core.bbpos.hardware.BbposReaderConnectionController.connectUsb(BbposReaderConnectionController.kt:70) at com.stripe.core.bbpos.hardware.BbposReaderConnectionController.connect(BbposReaderConnectionController.kt:35) at com.stripe.core.bbpos.hardware.BbposReaderController.connect(Unknown Source:7) at com.stripe.stripeterminal.internal.common.connectandupdate.ConnectHandler.onEnter(ConnectAndUpdateStates.kt:128) at com.stripe.stripeterminal.internal.common.connectandupdate.ConnectHandler.onEnter(ConnectAndUpdateStates.kt:121) at com.stripe.core.statemachine.StateMachine.transitionTo(StateMachine.kt:87) at com.stripe.core.statemachine.StateMachine$StateHandler.transitionTo(StateMachine.kt:140) at com.stripe.stripeterminal.internal.common.connectandupdate.EmptyHandler.onConnectAndUpdateApplicationDataUpdate(ConnectAndUpdateStates.kt:80) at com.stripe.stripeterminal.internal.common.connectandupdate.ConnectAndUpdateStateHandler.onUpdate(ConnectAndUpdateStates.kt:258) at com.stripe.stripeterminal.internal.common.connectandupdate.ConnectAndUpdateStateHandler.onUpdate(ConnectAndUpdateStates.kt:247) at com.stripe.core.statemachine.StateMachine.updateData(StateMachine.kt:53) at com.stripe.stripeterminal.internal.common.connectandupdate.ConnectAndUpdateStateMachine.update(ConnectAndUpdateStateMachine.kt:83) at com.stripe.stripeterminal.internal.common.adapter.BbposAdapter.update(BbposAdapter.kt:504) at com.stripe.stripeterminal.internal.common.adapter.BbposUsbAdapter$ReconnectUsbReaderOperation$execute$1$1.emit(BbposUsbAdapter.kt:220) at com.stripe.stripeterminal.internal.common.adapter.BbposUsbAdapter$ReconnectUsbReaderOperation$execute$1$1.emit(BbposUsbAdapter.kt:212) at kotlinx.coroutines.flow.internal.SafeCollectorKt$emitFun$1.invoke(SafeCollector.kt:15) at kotlinx.coroutines.flow.internal.SafeCollectorKt$emitFun$1.invoke(SafeCollector.kt:15) at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:87) at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:66) at com.stripe.stripeterminal.internal.common.adapter.connection.UsbReaderReconnector$attemptToReconnect$5.invokeSuspend(UsbReaderReconnector.kt:167) at com.stripe.stripeterminal.internal.common.adapter.connection.UsbReaderReconnector$attemptToReconnect$5.invoke(Unknown Source:8) at com.stripe.stripeterminal.internal.common.adapter.connection.UsbReaderReconnector$attemptToReconnect$5.invoke(Unknown Source:2) at com.stripe.core.hardware.reactive.RxJavaHelper.awaitFirstWithBlock(RxJavaHelper.kt:19) at com.stripe.stripeterminal.internal.common.adapter.connection.UsbReaderReconnector.attemptToReconnect(UsbReaderReconnector.kt:166) at com.stripe.stripeterminal.internal.common.adapter.connection.UsbReaderReconnector.access$attemptToReconnect(UsbReaderReconnector.kt:31) at com.stripe.stripeterminal.internal.common.adapter.connection.UsbReaderReconnector$reconnect$1$1.invokeSuspend(UsbReaderReconnector.kt:70) at com.stripe.stripeterminal.internal.common.adapter.connection.UsbReaderReconnector$reconnect$1$1.invoke(Unknown Source:8) at com.stripe.stripeterminal.internal.common.adapter.connection.UsbReaderReconnector$reconnect$1$1.invoke(Unknown Source:4) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturnIgnoreTimeout(Undispatched.kt:89) at kotlinx.coroutines.TimeoutKt.setupTimeout(Timeout.kt:151) at kotlinx.coroutines.TimeoutKt.withTimeoutOrNull(Timeout.kt:107) at kotlinx.coroutines.TimeoutKt.withTimeoutOrNull-KLykuaI(Timeout.kt:139) at com.stripe.stripeterminal.internal.common.adapter.connection.UsbReaderReconnector$reconnect$1.invokeSuspend(UsbReaderReconnector.kt:64)