Skip to content

Commit

Permalink
Bugfix/on disconnect is never triggered (#1148)
Browse files Browse the repository at this point in the history
* test: onDisconnect is not triggered when device disconnect itself

* fix: doFinally instead of doOnDispose

* 3.1.2-rc.0

* chore: prepare 3.1.2-rc.0

* chore: update yarn lock

---------

Co-authored-by: Dominik Czupryna <[email protected]>
Co-authored-by: Grzegorz Miszewski <[email protected]>
  • Loading branch information
3 people authored Nov 29, 2023
1 parent 2ce6e4a commit 241670f
Show file tree
Hide file tree
Showing 9 changed files with 347 additions and 203 deletions.
2 changes: 1 addition & 1 deletion android/src/main/java/com/bleplx/adapter/BleModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -1227,7 +1227,7 @@ private void safeConnectToDevice(final RxBleDevice device,
Observable<RxBleConnection> connect = device
.establishConnection(autoConnect)
.doOnSubscribe(disposable -> onConnectionStateChangedCallback.onEvent(ConnectionState.CONNECTING))
.doOnDispose(() -> {
.doFinally(() -> {
safeExecutor.error(BleErrorUtils.cancelled());
onDeviceDisconnected(device);
onConnectionStateChangedCallback.onEvent(ConnectionState.DISCONNECTED);
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ PODS:
- React-jsinspector (0.72.4)
- React-logger (0.72.4):
- glog
- react-native-ble-plx (3.1.1):
- react-native-ble-plx (3.1.2-rc.0):
- MultiplatformBleAdapter (= 0.2.0)
- RCT-Folly (= 2021.07.22.00)
- React-Core
Expand Down
2 changes: 1 addition & 1 deletion example/src/components/atoms/Button/Button.styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { AppText } from '../AppText/AppText'
export const Container = styled(TouchableOpacity)`
${({ theme }) => css`
background-color: ${theme.colors.mainRed};
margin: 10px;
margin: 5px 0px;
padding: 12px;
align-items: center;
border-radius: 100px;
Expand Down
8 changes: 8 additions & 0 deletions example/src/navigation/navigators/MainStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type MainStackParamList = {
DEVICE_DETAILS_SCREEN: undefined
DEVICE_NRF_TEST_SCREEN: undefined
DEVICE_CONNECT_DISCONNECT_TEST_SCREEN: undefined
DEVICE_ON_DISCONNECT_TEST_SCREEN: undefined
}

const MainStack = createNativeStackNavigator<MainStackParamList>()
Expand Down Expand Up @@ -45,6 +46,13 @@ export function MainStackComponent() {
headerTitle: 'Connect/disconnect'
}}
/>
<MainStack.Screen
name="DEVICE_ON_DISCONNECT_TEST_SCREEN"
component={screenComponents.DeviceOnDisconnectTestScreen}
options={{
headerTitle: 'On disconnect test'
}}
/>
</MainStack.Navigator>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export function DashboardScreen({ navigation }: DashboardScreenProps) {
label="Connect/disconnect test"
onPress={() => navigation.navigate('DEVICE_CONNECT_DISCONNECT_TEST_SCREEN')}
/>
<AppButton label="On disconnect test" onPress={() => navigation.navigate('DEVICE_ON_DISCONNECT_TEST_SCREEN')} />
<FlatList
style={{ flex: 1 }}
data={foundDevices}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import React, { useCallback, useEffect, useRef, useState } from 'react'
import type { NativeStackScreenProps } from '@react-navigation/native-stack'
import { BleError, Device, type Subscription, type DeviceId } from 'react-native-ble-plx'
import { ScrollView } from 'react-native'
import Toast from 'react-native-toast-message'
import { wait } from '../../../utils/wait'
import type { TestStateType } from '../../../types'
import { BLEService } from '../../../services'
import type { MainStackParamList } from '../../../navigation/navigators'
import { AppButton, AppTextInput, ScreenDefaultContainer, TestStateDisplay } from '../../../components/atoms'
import { deviceTimeService } from '../../../consts/nRFDeviceConsts'

type DeviceOnDisconnectTestScreenProps = NativeStackScreenProps<MainStackParamList, 'DEVICE_ON_DISCONNECT_TEST_SCREEN'>

export function DeviceOnDisconnectTestScreen(_props: DeviceOnDisconnectTestScreenProps) {
const [expectedDeviceName, setExpectedDeviceName] = useState('')
const [testScanDevicesState, setTestScanDevicesState] = useState<TestStateType>('WAITING')
const [deviceId, setDeviceId] = useState('')
const [currentTest, setCurrentTest] = useState<null | 'disconnectByDevice' | 'disconnectByPLX'>(null)
const onDisconnectRef = useRef<Subscription | null>(null)

const checkDeviceName = (device: Device) =>
device.name?.toLocaleLowerCase() === expectedDeviceName.toLocaleLowerCase()

const connectAndDiscover = async () => {
setTestScanDevicesState('IN_PROGRESS')
await BLEService.initializeBLE()
await BLEService.scanDevices(
async (device: Device) => {
if (checkDeviceName(device)) {
console.info(`connecting to ${device.id}`)
await startConnectToDevice(device)
await BLEService.discoverAllServicesAndCharacteristicsForDevice()
setTestScanDevicesState('DONE')
setDeviceId(device.id)
}
},
[deviceTimeService]
)
}

const startConnectToDevice = (device: Device) => BLEService.connectToDevice(device.id)

const setupOnDeviceDisconnected = useCallback(
(directDeviceId?: DeviceId) => {
if (!deviceId && !directDeviceId) {
console.error('Device not ready')
return
}
if (onDisconnectRef.current?.remove) {
onDisconnectRef.current.remove()
onDisconnectRef.current = null
}
onDisconnectRef.current = BLEService.onDeviceDisconnectedCustom(directDeviceId || deviceId, disconnectedListener)
console.info('on device disconnected ready')
},
[deviceId]
)

const disconnectedListener = (error: BleError | null, device: Device | null) => {
console.warn('Disconnect listener called')
if (error) {
console.error('onDeviceDisconnected error')
}
if (device) {
console.info('onDeviceDisconnected device')
}
setDeviceId('')
setCurrentTest(null)
}

// https://github.com/dotintent/react-native-ble-plx/issues/1126
const start1126Test = () => connectAndDiscover().then(() => setCurrentTest('disconnectByPLX'))

// https://github.com/dotintent/react-native-ble-plx/issues/1126
const start1126DeviceTest = () => connectAndDiscover().then(() => setCurrentTest('disconnectByDevice'))

const disconnectByPLX = useCallback(async () => {
try {
setupOnDeviceDisconnected()
await wait(1000)
console.info('expected warn: "Disconnect listener called"')
BLEService.disconnectDevice()
console.info('Finished')
} catch (error) {
console.error(error)
}
}, [setupOnDeviceDisconnected])

const disconnectByDevice = useCallback(async () => {
try {
setupOnDeviceDisconnected()
wait(1000)
Toast.show({
type: 'info',
text1: 'Disconnect device',
text2: 'and expect warn: "Disconnect listener called"'
})
console.info('Disconnect device and expect warn: "Disconnect listener called"')
} catch (error) {
console.error(error)
}
}, [setupOnDeviceDisconnected])

useEffect(() => {
if (!deviceId) {
return
}
if (currentTest === 'disconnectByPLX') {
disconnectByPLX()
}
if (currentTest === 'disconnectByDevice') {
disconnectByDevice()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [deviceId])

return (
<ScreenDefaultContainer>
<ScrollView showsVerticalScrollIndicator={false}>
<AppTextInput
placeholder="Device name to connect"
value={expectedDeviceName}
onChangeText={setExpectedDeviceName}
/>
<AppButton label="Connect and discover" onPress={connectAndDiscover} />
<AppButton label="Setup on device disconnected" onPress={() => setupOnDeviceDisconnected()} />
<TestStateDisplay label="Looking for device" state={testScanDevicesState} />
<AppButton label="Start 1126 test (trigger by ble-plx)" onPress={() => start1126Test()} />
<AppButton label="Start 1126 test (trigger by device)" onPress={() => start1126DeviceTest()} />
</ScrollView>
</ScreenDefaultContainer>
)
}
1 change: 1 addition & 0 deletions example/src/screens/MainStack/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './DashboardScreen/DashboardScreen'
export * from './DeviceDetailsScreen/DeviceDetailsScreen'
export * from './DevicenRFTestScreen/DevicenRFTestScreen'
export * from './DeviceConnectDisconnectTestScreen/DeviceConnectDisconnectTestScreen'
export * from './DeviceOnDisconnectTestScreen/DeviceOnDisconnectTestScreen'
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-ble-plx",
"version": "3.1.1",
"version": "3.1.2-rc.0",
"description": "React Native Bluetooth Low Energy library",
"main": "src/index",
"module": "src/index",
Expand Down Expand Up @@ -45,7 +45,7 @@
"test:ios": "cd test_project/ios && xcodebuild -workspace BlePlxExample.xcworkspace -scheme BlePlxExample -configuration Debug -sdk iphonesimulator ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO",
"test:expo": "cd test_project && npx expo prebuild",
"bootstrap": "yarn example && yarn install && yarn example pods",
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build",
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build plugin/build lib",
"build:plugin": "tsc --build plugin",
"clean:plugin": "expo-module clean plugin",
"test:plugin": "jest --config plugin/jest.config.js",
Expand Down
Loading

0 comments on commit 241670f

Please sign in to comment.