Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions app/lib/pages/conversations/widgets/capture.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:omi/backend/schema/bt_device/bt_device.dart';
import 'package:omi/pages/capture/widgets/widgets.dart';
import 'package:omi/providers/capture_provider.dart';
import 'package:omi/providers/connectivity_provider.dart';
import 'package:omi/providers/device_provider.dart';
import 'package:omi/providers/onboarding_provider.dart';
import 'package:omi/services/services.dart';
import 'package:omi/utils/audio/wav_bytes.dart';
import 'package:provider/provider.dart';

Expand All @@ -28,23 +23,9 @@ class LiteCaptureWidgetState extends State<LiteCaptureWidget> with AutomaticKeep
@override
void initState() {
WavBytesUtil.clearTempWavFiles();
SchedulerBinding.instance.addPostFrameCallback((_) async {
if (context.read<DeviceProvider>().connectedDevice != null) {
context.read<OnboardingProvider>().stopScanDevices();
}
});

super.initState();
}

Future<BleAudioCodec> _getAudioCodec(String deviceId) async {
var connection = await ServiceManager.instance().device.ensureConnection(deviceId);
if (connection == null) {
return BleAudioCodec.pcm8;
}
return connection.getAudioCodec();
}

@override
Widget build(BuildContext context) {
super.build(context);
Expand Down
1 change: 0 additions & 1 deletion app/lib/pages/onboarding/find_device/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ class _FindDevicesPageState extends State<FindDevicesPage> {

@override
dispose() {
_provider?.stopScanDevices();
_provider = null;

super.dispose();
Expand Down
19 changes: 11 additions & 8 deletions app/lib/pages/onboarding/welcome/page.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:omi/providers/onboarding_provider.dart';
import 'package:omi/utils/analytics/intercom.dart';
import 'package:omi/utils/platform/platform_service.dart';
import 'package:omi/widgets/dialog.dart';
import 'package:gradient_borders/box_borders/gradient_box_border.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';

Expand Down Expand Up @@ -174,15 +171,19 @@ class _WelcomePageState extends State<WelcomePage> with TickerProviderStateMixin
AnimatedContainer(
duration: const Duration(milliseconds: 800),
curve: Curves.easeInOut,
height: _isExpandingTop ? MediaQuery.of(context).size.height : MediaQuery.of(context).size.height * _expansionAnimation.value,
height: _isExpandingTop
? MediaQuery.of(context).size.height
: MediaQuery.of(context).size.height * _expansionAnimation.value,
child: Container(
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: ResizeImage(
const AssetImage('assets/images/onboarding-bg-5-1.jpg'),
width: (MediaQuery.of(context).size.width * MediaQuery.of(context).devicePixelRatio).round(),
height: (MediaQuery.of(context).size.height * MediaQuery.of(context).devicePixelRatio).round(),
width:
(MediaQuery.of(context).size.width * MediaQuery.of(context).devicePixelRatio).round(),
height: (MediaQuery.of(context).size.height * MediaQuery.of(context).devicePixelRatio)
.round(),
),
fit: BoxFit.cover,
),
Expand Down Expand Up @@ -268,8 +269,10 @@ class _WelcomePageState extends State<WelcomePage> with TickerProviderStateMixin
image: DecorationImage(
image: ResizeImage(
const AssetImage('assets/images/onboarding-bg-5-2.jpg'),
width: (MediaQuery.of(context).size.width * MediaQuery.of(context).devicePixelRatio).round(),
height: (MediaQuery.of(context).size.height * MediaQuery.of(context).devicePixelRatio).round(),
width: (MediaQuery.of(context).size.width * MediaQuery.of(context).devicePixelRatio)
.round(),
height: (MediaQuery.of(context).size.height * MediaQuery.of(context).devicePixelRatio)
.round(),
),
fit: BoxFit.cover,
),
Expand Down
1 change: 0 additions & 1 deletion app/lib/pages/settings/device_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ class _DeviceSettingsState extends State<DeviceSettings> {
provider.setIsConnected(false);
provider.setConnectedDevice(null);
provider.updateConnectingStatus(false);
context.read<OnboardingProvider>().stopScanDevices();
Navigator.of(context).pop();
Navigator.of(context).pop();
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
Expand Down
35 changes: 15 additions & 20 deletions app/lib/providers/device_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import 'package:omi/services/services.dart';
import 'package:omi/utils/analytics/mixpanel.dart';
import 'package:omi/utils/device.dart';
import 'package:omi/utils/logger.dart';
import 'package:omi/widgets/confirmation_dialog.dart';
import 'package:omi/utils/platform/platform_manager.dart';
import 'package:omi/widgets/confirmation_dialog.dart';

class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption {
CaptureProvider? captureProvider;
Expand All @@ -29,7 +29,7 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
bool _hasLowBatteryAlerted = false;
Timer? _reconnectionTimer;
DateTime? _reconnectAt;
final int _connectionCheckSeconds = 7;
final int _connectionCheckSeconds = 10;

bool _havingNewFirmware = false;
bool get havingNewFirmware => _havingNewFirmware && pairedDevice != null && isConnected;
Expand Down Expand Up @@ -141,12 +141,8 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption

Future periodicConnect(String printer) async {
_reconnectionTimer?.cancel();
_reconnectionTimer = Timer.periodic(Duration(seconds: _connectionCheckSeconds), (t) async {
scan(t) async {
debugPrint("Period connect seconds: $_connectionCheckSeconds, triggered timer at ${DateTime.now()}");
if (SharedPreferencesUtil().btDevice.id.isEmpty) {
t.cancel();
return;
}
if (_reconnectAt != null && _reconnectAt!.isAfter(DateTime.now())) {
return;
}
Expand All @@ -159,27 +155,26 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
} else {
t.cancel();
}
});
}

_reconnectionTimer = Timer.periodic(Duration(seconds: _connectionCheckSeconds), scan);
scan(_reconnectionTimer);
}

Future<BtDevice?> _scanAndConnectDevice({bool autoConnect = true, bool timeout = false}) async {
Future<BtDevice?> _scanConnectDevice() async {
var device = await _getConnectedDevice();
if (device != null) {
return device;
}

int timeoutCounter = 0;
while (true) {
if (timeout && timeoutCounter >= 10) return null;
await ServiceManager.instance().device.discover(desirableDeviceId: SharedPreferencesUtil().btDevice.id);
if (connectedDevice != null) {
return connectedDevice;
}
await ServiceManager.instance().device.discover(desirableDeviceId: SharedPreferencesUtil().btDevice.id);

// If the device is not found, wait for a bit before retrying.
await Future.delayed(const Duration(seconds: 2));
timeoutCounter += 2;
// Waiting for the device connected (if any)
await Future.delayed(const Duration(seconds: 2));
if (connectedDevice != null) {
return connectedDevice;
}
return null;
}

Future scanAndConnectToDevice() async {
Expand All @@ -198,7 +193,7 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
}

// else
var device = await _scanAndConnectDevice();
var device = await _scanConnectDevice();
Logger.debug('inside scanAndConnectToDevice $device in device_provider');
if (device != null) {
var cDevice = await _getConnectedDevice();
Expand Down
48 changes: 17 additions & 31 deletions app/lib/providers/onboarding_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ class OnboardingProvider extends BaseProvider with MessageNotifierMixin implemen
String? connectingToDeviceId;
List<BtDevice> deviceList = [];
late Timer _didNotMakeItTimer;
Timer? _findDevicesTimer;
bool enableInstructions = false;
Map<String, BtDevice> foundDevicesMap = {};

Expand Down Expand Up @@ -403,31 +402,29 @@ class OnboardingProvider extends BaseProvider with MessageNotifierMixin implemen
VoidCallback? goNext,
}) async {
try {
if (isClicked) return; // if any item is clicked, don't do anything
isClicked = true; // Prevent further clicks
connectingToDeviceId = device.id; // Mark this device as being connected to
if (isClicked) return;
isClicked = true;

connectingToDeviceId = device.id;
notifyListeners();
var c = await ServiceManager.instance().device.ensureConnection(device.id, force: true);
await ServiceManager.instance().device.ensureConnection(device.id, force: true);
debugPrint('Connected to device: ${device.name}');
deviceId = device.id;
// device = await device.getDeviceInfo(c);
await SharedPreferencesUtil().btDeviceSet(device);
deviceName = device.name;
var cDevice = await _getConnectedDevice(deviceId);
if (cDevice != null) {
deviceProvider!.setConnectedDevice(cDevice);
// SharedPreferencesUtil().btDevice = cDevice;
SharedPreferencesUtil().deviceName = cDevice.name;
deviceProvider!.setIsConnected(true);
}
await deviceProvider?.scanAndConnectToDevice();
var connectedDevice = deviceProvider!.connectedDevice;
batteryPercentage = deviceProvider!.batteryLevel;
isConnected = true;
isClicked = false; // Allow clicks again after finishing the operation
isClicked = false;
connectingToDeviceId = null; // Reset the connecting device
notifyListeners();
stopScanDevices();
await Future.delayed(const Duration(seconds: 2));
SharedPreferencesUtil().btDevice = connectedDevice!;
SharedPreferencesUtil().deviceName = connectedDevice.name;
Expand Down Expand Up @@ -459,8 +456,13 @@ class OnboardingProvider extends BaseProvider with MessageNotifierMixin implemen
notifyListeners();
}

void stopScanDevices() {
_findDevicesTimer?.cancel();
// TODO: thinh, use connection directly
Future<BtDevice?> _getConnectedDevice(String deviceId) async {
if (deviceId.isEmpty) {
return null;
}
var connection = await ServiceManager.instance().device.ensureConnection(deviceId);
return connection?.device;
}

Future<void> scanDevices({
Expand All @@ -470,6 +472,7 @@ class OnboardingProvider extends BaseProvider with MessageNotifierMixin implemen
// it means the device has been unpaired
deviceAlreadyUnpaired();
}

// check if bluetooth is enabled on both platforms
if (!hasBluetoothPermission) {
await askForBluetoothPermissions();
Expand All @@ -484,30 +487,11 @@ class OnboardingProvider extends BaseProvider with MessageNotifierMixin implemen
});

ServiceManager.instance().device.subscribe(this, this);

_findDevicesTimer?.cancel();
_findDevicesTimer = Timer.periodic(const Duration(seconds: 4), (t) async {
if (deviceProvider?.isConnected ?? false) {
t.cancel();
return;
}

ServiceManager.instance().device.discover();
});
}

// TODO: thinh, use connection directly
Future<BtDevice?> _getConnectedDevice(String deviceId) async {
if (deviceId.isEmpty) {
return null;
}
var connection = await ServiceManager.instance().device.ensureConnection(deviceId);
return connection?.device;
await deviceProvider?.periodicConnect("Come from Onboarding");
}

@override
void dispose() {
_findDevicesTimer?.cancel();
_didNotMakeItTimer.cancel();
ServiceManager.instance().device.unsubscribe(this);
super.dispose();
Expand All @@ -528,11 +512,13 @@ class OnboardingProvider extends BaseProvider with MessageNotifierMixin implemen
// If it's a new device, add it to the map. If it already exists, this will just update the entry.
updatedDevicesMap[device.id] = device;
}

// Remove devices that are no longer found
foundDevicesMap.keys.where((id) => !updatedDevicesMap.containsKey(id)).toList().forEach(foundDevicesMap.remove);

// Merge the new devices into the current map to maintain order
foundDevicesMap.addAll(updatedDevicesMap);

// Convert the values of the map back to a list
List<BtDevice> orderedDevices = foundDevicesMap.values.toList();
if (orderedDevices.isNotEmpty) {
Expand Down
4 changes: 2 additions & 2 deletions app/lib/services/devices.dart
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ class DeviceService implements IDeviceService {

// connected
var pongAt = _connection?.pongAt;
var shouldPing = (pongAt == null || pongAt.isBefore(DateTime.now().subtract(const Duration(seconds: 5))));
var shouldPing = (pongAt == null || pongAt.isBefore(DateTime.now().subtract(const Duration(seconds: 10))));
if (shouldPing) {
var ok = await _connection?.ping() ?? false;
if (!ok) {
Expand All @@ -227,7 +227,7 @@ class DeviceService implements IDeviceService {
// Force
if (deviceId == _connection?.device.id && _connection?.status == DeviceConnectionState.connected) {
var pongAt = _connection?.pongAt;
var shouldPing = (pongAt == null || pongAt.isBefore(DateTime.now().subtract(const Duration(seconds: 5))));
var shouldPing = (pongAt == null || pongAt.isBefore(DateTime.now().subtract(const Duration(seconds: 10))));
if (shouldPing) {
var ok = await _connection?.ping() ?? false;
if (!ok) {
Expand Down
2 changes: 1 addition & 1 deletion app/lib/services/devices/device_connection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ abstract class DeviceConnection {

Future<bool> ping() async {
try {
int rssi = await bleDevice.readRssi();
int rssi = await bleDevice.readRssi(timeout: 10);
device.rssi = rssi;
_pongAt = DateTime.now();
return true;
Expand Down