Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebView might crash when repeatedly calling .connect before device has been scanned for #975

Closed
graphefruit opened this issue Jun 4, 2023 · 4 comments

Comments

@graphefruit
Copy link

Hey @peitschie,

Sorry for another ticket here!

ios 6.3.0
cordova-plugin-ble-central 1.7.0 "BLE"
ionic 6
angular 15.2.3

I've just encountered an issue on iOS:

When I run .connect and this triggers the .disconnect function and I reconnect again, the log goes crazy, and the app reloads.

That said, the fix was to add a timeout for 1-2 seconds, before triggering .connect again.
(.autoConnect cant be used, after all the discussions we had on #963)

ble.connect(
        deviceId,
        (data: PeripheralData) => {
          this.logger.log('AutoConnectScale - Scale device connected.');
      
        },
        async () => {
          this.logger.log('AutoConnectScale - Scale device disconnected.');
       

            // If this line is removed, the app cycles and reloads.
            await new Promise((resolve) => {
              setTimeout(async () => {
                resolve(undefined);
              }, 2000);
            });

       
        
            this.connectScale(
               ...
            );
          }
        }

The log which is thrown on iOS:

2023-06-04 19:26:17.066651+0200 Beanconqueror[1807:73106] connect
2023-06-04 19:26:17.067462+0200 Beanconqueror[1807:73106] Could not find peripheral F8B30B87-B6D4-53C3-92EC-EBFEB3D6788C.
2023-06-04 19:26:17.068752+0200 Beanconqueror[1807:73106] connect
2023-06-04 19:26:17.069386+0200 Beanconqueror[1807:73106] Could not find peripheral F8B30B87-B6D4-53C3-92EC-EBFEB3D6788C.
2023-06-04 19:26:17.071328+0200 Beanconqueror[1807:73106] connect
2023-06-04 19:26:17.072699+0200 Beanconqueror[1807:73106] Could not find peripheral F8B30B87-B6D4-53C3-92EC-EBFEB3D6788C.
2023-06-04 19:26:17.079072+0200 Beanconqueror[1807:73106] connect
2023-06-04 19:26:17.082581+0200 Beanconqueror[1807:73106] Could not find peripheral F8B30B87-B6D4-53C3-92EC-EBFEB3D6788C.
2023-06-04 19:26:17.087481+0200 Beanconqueror[1807:73106] connect
2023-06-04 19:26:17.091023+0200 Beanconqueror[1807:73106] Could not find peripheral F8B30B87-B6D4-53C3-92EC-EBFEB3D6788C.
2023-06-04 19:26:17.099299+0200 Beanconqueror[1807:73106] connect
2023-06-04 19:26:17.101547+0200 Beanconqueror[1807:73106] Could not find peripheral F8B30B87-B6D4-53C3-92EC-EBFEB3D6788C.
2023-06-04 19:26:17.121533+0200 Beanconqueror[1807:73106] connect
2023-06-04 19:26:17.122448+0200 Beanconqueror[1807:73106] Could not find peripheral F8B30B87-B6D4-53C3-92EC-EBFEB3D6788C.
2023-06-04 19:26:17.129561+0200 Beanconqueror[1807:73106] connect
2023-06-04 19:26:17.130399+0200 Beanconqueror[1807:73106] Could not find peripheral F8B30B87-B6D4-53C3-92EC-EBFEB3D6788C.
2023-06-04 19:26:17.134071+0200 Beanconqueror[1807:73106] connect
2023-06-04 19:26:17.134773+0200 Beanconqueror[1807:73106] Could not find peripheral F8B30B87-B6D4-53C3-92EC-EBFEB3D6788C.
2023-06-04 19:26:17.136218+0200 Beanconqueror[1807:73106] connect
2023-06-04 19:26:17.137164+0200 Beanconqueror[1807:73106] Could not find peripheral F8B30B87-B6D4-53C3-92EC-EBFEB3D6788C.

.... about 1000 times more

and ends with

2023-06-04 19:26:17.771791+0200 Beanconqueror[1807:73106] [Process] 0x110000de0 - [PID=1810] WebProcessProxy::didClose: (web process 0 crash)
2023-06-04 19:26:17.781537+0200 Beanconqueror[1807:73106] [Process] 0x110000de0 - [PID=1810] WebProcessProxy::processDidTerminateOrFailedToLaunch: reason=Crash
2023-06-04 19:26:17.791474+0200 Beanconqueror[1807:73106] [ProcessSuspension] 0x10f0964c0 - ProcessAssertion: Failed to acquire RBS Background assertion 'XPCConnectionTerminationWatchdog' for process because PID 0 is invalid
2023-06-04 19:26:17.792634+0200 Beanconqueror[1807:73370] [ProcessSuspension] 0x10f0964c0 - ProcessAssertion::acquireSync Failed to acquire RBS assertion 'XPCConnectionTerminationWatchdog' for process with PID=0, error: (null)
2023-06-04 19:26:17.915547+0200 Beanconqueror[1807:73106] [Process] 0x12a83b618 - [pageProxyID=7, webPageID=8, PID=1810] WebPageProxy::processDidTerminate: (pid 1810), reason=Crash
2023-06-04 19:26:18.124643+0200 Beanconqueror[1807:73106] [Loading] 0x12a83b618 - [pageProxyID=7, webPageID=8, PID=1810] WebPageProxy::dispatchProcessDidTerminate: reason=Crash
2023-06-04 19:26:18.301610+0200 Beanconqueror[1807:73106] [Process] 0x10f06c640 - GPUProcessProxy::gpuProcessExited: reason=IdleExit
2023-06-04 19:26:18.301887+0200 Beanconqueror[1807:73106] [Process] 0x110001dc0 - [PID=1825] WebProcessProxy::gpuProcessExited: reason=IdleExit
2023-06-04 19:26:18.311604+0200 Beanconqueror[1807:73370] [assertion] Error acquiring assertion: <Error Domain=RBSServiceErrorDomain Code=1 "target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit" UserInfo={NSLocalizedFailureReason=target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit}>
2023-06-04 19:26:18.311755+0200 Beanconqueror[1807:73370] [ProcessSuspension] 0x10f096700 - ProcessAssertion::acquireSync Failed to acquire RBS assertion 'GPUProcess Foreground Assertion' for process with PID=1812, error: Error Domain=RBSServiceErrorDomain Code=1 "target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit" UserInfo={NSLocalizedFailureReason=target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit}
2023-06-04 19:26:18.316774+0200 Beanconqueror[1807:73370] [assertion] Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=2 "Specified target process does not exist" UserInfo={NSLocalizedFailureReason=Specified target process does not exist}>
2023-06-04 19:26:18.316949+0200 Beanconqueror[1807:73370] [ProcessSuspension] 0x10f0967c0 - ProcessAssertion::acquireSync Failed to acquire RBS assertion 'GPUProcess Background Assertion' for process with PID=1812, error: Error Domain=RBSAssertionErrorDomain Code=2 "Specified target process does not exist" UserInfo={NSLocalizedFailureReason=Specified target process does not exist}

Maybe! This issue is aswell on Android, but after I do some other magic here, I didn't test it right now tbh.

Hope this information helps you to track down :)
Best regards
Lars

@peitschie
Copy link
Collaborator

Howdy @graphefruit

No problems at all 🙂 ... always happy to have feedback/issues raised.

Based on what you're seeing there, I can't really think of anything obvious the plugin could do differently here. The webview is crashing, which means it's the javascript side running into problems. My assumption is some kind of memory exhaustion or call-stack limit caused by the repeated hammering of the connect method.

This issue only happens if you connect straight after app launch without any prior scans. Based on #963 (comment), most of my applications tend to use option 2, so they scan THEN connect. This avoids the tight-loop you're seeing here, because I won't try to connect until the peripheral has been seen, avoiding the Could not find peripheral error.

Android will not have this quirk as the Android stack allows us to create the proxy without a scan packet (though that leads to another issue where the first connect often fails...).

For what you're doing above, I'd suggest throttling the reconnect attempts if no prior connect has been made since application launch. E.g.,

function connect() {
  let hasConnectedOnce = false
  ble.connect(
    (data) => (hasConnectedOnce = true),
    (err) => {
      const reconnectPauseMs = hasConnectedOnce ? 1000 : 30000;
      setTimeout(connect, reconnectPauseMs);
    }
  );
}

But, you'll still have the problem that you must scan before a connect will work on iOS.

Happy for other ideas on how this problem could be mitigated thought.

@peitschie peitschie changed the title iOS - App crashes when .connect triggers .disconnect and you reconnect WebView might crash when repeatedly calling .connect before device has been scanned for Jun 4, 2023
@graphefruit
Copy link
Author

Hey @peitschie ,
thanks for your feedback.
If I remember it rightly this issue was not given with Version 1.6.3 where I already did the .connect thing and reconnecting when disconnect is triggered, but now with 1.7.0.
I'll do tomorrow some more tests.

Any how, the good thing is that the "quickfix" is a timeout added, but I'm very confused, when the .disconnect is triggered and you .connect again, its going into a loop which is triggered in milliseconds

@peitschie
Copy link
Collaborator

Interesting.

There are no changes between 1.6.3 and 1.7.0 that should impact this, so I don't really have a good explanation for why it worked before but not now. Is this plugin the only thing that's changed recently?

but I'm very confused, when the .disconnect is triggered and you .connect again, its going into a loop which is triggered in milliseconds

The tight loop here is because the peripheral has never been seen by the plugin, so it returns immediately. On iOS, it's impossible to connect without first scanning for the peripheral (unless you have BLUETOOTH_RESTORE_STATE set to true).

@peitschie
Copy link
Collaborator

I'm closing this issue out as the key issue here is that connect is always being called within the disconnected callback despite the reported error not being recoverable.

The suggested workaround has been detailed in #975 (comment), but there's no generic fix that seems useful here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants