fix: lifecycle
This commit is contained in:
@ -66,15 +66,21 @@ class _BootloaderRecoveryUpdatePageState
|
||||
unawaited(_firmwareProgressSubscription?.cancel());
|
||||
unawaited(() async {
|
||||
await service?.dispose();
|
||||
await _disconnectBootloaderIfStillConnected(bluetooth: bluetooth);
|
||||
await _disconnectBootloaderIfStillConnected(
|
||||
bluetooth: bluetooth,
|
||||
allowRefRead: false,
|
||||
);
|
||||
}());
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _disconnectBootloaderIfStillConnected({
|
||||
BluetoothController? bluetooth,
|
||||
bool allowRefRead = true,
|
||||
}) async {
|
||||
bluetooth ??= ref.read(bluetoothProvider).valueOrNull;
|
||||
if (bluetooth == null && allowRefRead) {
|
||||
bluetooth = ref.read(bluetoothProvider).valueOrNull;
|
||||
}
|
||||
if (bluetooth == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -66,6 +66,7 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
|
||||
bool _isPairingCheckRunning = false;
|
||||
ProviderSubscription<AsyncValue<(ConnectionStatus, String?)>>?
|
||||
_connectionStatusSubscription;
|
||||
BluetoothController? _bluetooth;
|
||||
|
||||
ShifterService? _shifterService;
|
||||
StreamSubscription<CentralStatus>? _statusSubscription;
|
||||
@ -146,7 +147,10 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
|
||||
'Disposing device details page for ${widget.deviceAddress}; '
|
||||
'dfuState=${_dfuProgress.state}, isFirmwareUpdateBusy=$_isFirmwareUpdateBusy',
|
||||
);
|
||||
unawaited(_disconnectOnClose());
|
||||
final bluetooth = _bluetooth;
|
||||
unawaited(
|
||||
_disconnectOnClose(bluetooth: bluetooth, allowRefRead: false),
|
||||
);
|
||||
_connectionStatusSubscription?.close();
|
||||
_statusSubscription?.cancel();
|
||||
_shifterService?.dispose();
|
||||
@ -155,7 +159,10 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _disconnectOnClose() async {
|
||||
Future<void> _disconnectOnClose({
|
||||
BluetoothController? bluetooth,
|
||||
bool allowRefRead = true,
|
||||
}) async {
|
||||
if (_isFirmwareUpdateBusy) {
|
||||
_log.info('Skipping disconnect on close because firmware update is busy');
|
||||
return;
|
||||
@ -169,10 +176,16 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
|
||||
_hasRequestedDisconnect = true;
|
||||
_isExitingPage = true;
|
||||
|
||||
final bluetoothController = bluetooth ??
|
||||
_bluetooth ??
|
||||
(allowRefRead ? ref.read(bluetoothProvider).value : null);
|
||||
if (bluetoothController != null) {
|
||||
_bluetooth = bluetoothController;
|
||||
}
|
||||
|
||||
await _disposeFirmwareUpdateService();
|
||||
|
||||
final bluetooth = ref.read(bluetoothProvider).value;
|
||||
await bluetooth?.disconnect();
|
||||
await bluetoothController?.disconnect();
|
||||
await _stopStatusStreaming();
|
||||
}
|
||||
|
||||
@ -211,6 +224,9 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
|
||||
|
||||
if (_shifterService != null) {
|
||||
final bluetooth = ref.read(bluetoothProvider).value;
|
||||
if (bluetooth != null) {
|
||||
_bluetooth = bluetooth;
|
||||
}
|
||||
if (bluetooth == null || !isCurrentDeviceConnected(bluetooth)) {
|
||||
return;
|
||||
}
|
||||
@ -239,6 +255,7 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
|
||||
} else {
|
||||
bluetooth = await ref.read(bluetoothProvider.future);
|
||||
}
|
||||
_bluetooth = bluetooth;
|
||||
if (!isCurrentDeviceConnected(bluetooth)) {
|
||||
return;
|
||||
}
|
||||
@ -264,6 +281,9 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
|
||||
}
|
||||
|
||||
final bluetooth = ref.read(bluetoothProvider).value;
|
||||
if (bluetooth != null) {
|
||||
_bluetooth = bluetooth;
|
||||
}
|
||||
if (bluetooth == null || !isCurrentDeviceConnected(bluetooth)) {
|
||||
break;
|
||||
}
|
||||
@ -523,6 +543,7 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
|
||||
if (bluetooth == null) {
|
||||
return null;
|
||||
}
|
||||
_bluetooth = bluetooth;
|
||||
|
||||
final service = FirmwareUpdateService(
|
||||
transport: ShifterFirmwareUpdateTransport(
|
||||
@ -722,6 +743,7 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
|
||||
|
||||
try {
|
||||
final bluetooth = await ref.read(bluetoothProvider.future);
|
||||
_bluetooth = bluetooth;
|
||||
final result = await bluetooth.connectById(
|
||||
widget.deviceAddress,
|
||||
timeout: const Duration(seconds: 10),
|
||||
|
||||
@ -26,8 +26,10 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
|
||||
static const Duration _bootloaderScanTimeout = Duration(seconds: 10);
|
||||
|
||||
StreamSubscription<List<DiscoveredDevice>>? _scanSubscription;
|
||||
BluetoothController? _bluetooth;
|
||||
DiscoveredDevice? _dfuDevice;
|
||||
bool _isBootloaderScanStarting = false;
|
||||
bool _isDisposed = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -37,8 +39,8 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
final bluetooth = ref.read(bluetoothProvider).valueOrNull;
|
||||
unawaited(_scanSubscription?.cancel());
|
||||
_isDisposed = true;
|
||||
final bluetooth = _bluetooth;
|
||||
unawaited(_stopBootloaderScan(bluetooth));
|
||||
super.dispose();
|
||||
}
|
||||
@ -52,14 +54,19 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
|
||||
|
||||
try {
|
||||
final bluetooth = await ref.read(bluetoothProvider.future);
|
||||
if (!mounted) {
|
||||
if (!mounted || _isDisposed) {
|
||||
return;
|
||||
}
|
||||
_bluetooth = bluetooth;
|
||||
|
||||
final scanResult = await bluetooth.startScan(
|
||||
timeout: _bootloaderScanTimeout,
|
||||
scanMode: ScanMode.lowLatency,
|
||||
);
|
||||
if (!mounted || _isDisposed) {
|
||||
await bluetooth.stopScan();
|
||||
return;
|
||||
}
|
||||
if (scanResult.isErr()) {
|
||||
return;
|
||||
}
|
||||
@ -74,20 +81,22 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
|
||||
}
|
||||
|
||||
Future<void> _stopBootloaderScan([BluetoothController? bluetooth]) async {
|
||||
await _scanSubscription?.cancel();
|
||||
final subscription = _scanSubscription;
|
||||
_scanSubscription = null;
|
||||
await subscription?.cancel();
|
||||
|
||||
await bluetooth?.stopScan();
|
||||
}
|
||||
|
||||
void _updateBootloaderDevice(List<DiscoveredDevice> devices) {
|
||||
if (_isDisposed || !mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
final dfuDevice = devices.cast<DiscoveredDevice?>().firstWhere(
|
||||
(device) => device != null && _isBootloaderAdvertisement(device),
|
||||
orElse: () => null,
|
||||
);
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dfuDevice == null) {
|
||||
_clearBootloaderDevice();
|
||||
@ -104,7 +113,7 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
|
||||
}
|
||||
|
||||
void _clearBootloaderDevice() {
|
||||
if (!mounted || _dfuDevice == null) {
|
||||
if (_isDisposed || !mounted || _dfuDevice == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -139,12 +148,12 @@ class _DevicesTabPageState extends ConsumerState<DevicesTabPage> {
|
||||
builder: (_) => _BootloaderRecoverySetupPage(device: device),
|
||||
),
|
||||
);
|
||||
if (!mounted || firmware == null) {
|
||||
if (!mounted || _isDisposed || firmware == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
await _stopBootloaderScan();
|
||||
if (!mounted) {
|
||||
if (!mounted || _isDisposed) {
|
||||
return;
|
||||
}
|
||||
_clearBootloaderDevice();
|
||||
|
||||
Reference in New Issue
Block a user