Skip to content
Open
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
4 changes: 4 additions & 0 deletions open_wearable/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false
32 changes: 22 additions & 10 deletions open_wearable/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -190,25 +190,37 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
appBannerController.showBanner(
(id) {
final colorScheme = Theme.of(context).colorScheme;
final bool isError = event is WearableErrorEvent;
final severity =
event is WearableErrorEvent ? event.severity : null;
final bool isError = severity == DeviceErrorLevel.error ||
severity == DeviceErrorLevel.fatal;
final bool isWarning = severity == DeviceErrorLevel.warning;
final bool isTimeSync = event is WearableTimeSynchronizedEvent;
const timeSyncBackground = Color(0xFFEDE4FF);
const timeSyncForeground = Color(0xFF5A2EA6);
const warningBackground = Color(0xFFFFF3CD);
const warningForeground = Color(0xFF6B4E00);
final backgroundColor = isError
? colorScheme.errorContainer
: isTimeSync
? timeSyncBackground
: colorScheme.primaryContainer;
: isWarning
? warningBackground
: isTimeSync
? timeSyncBackground
: colorScheme.primaryContainer;
final textColor = isError
? colorScheme.onErrorContainer
: isTimeSync
? timeSyncForeground
: colorScheme.onPrimaryContainer;
: isWarning
? warningForeground
: isTimeSync
? timeSyncForeground
: colorScheme.onPrimaryContainer;
final icon = isError
? Icons.error_outline_rounded
: isTimeSync
? Icons.schedule_rounded
: Icons.info_outline_rounded;
: isWarning
? Icons.warning_amber_rounded
: isTimeSync
? Icons.schedule_rounded
: Icons.info_outline_rounded;
final textStyle = Theme.of(context).textTheme.bodyMedium?.copyWith(
color: textColor,
fontWeight: FontWeight.w600,
Expand Down
39 changes: 37 additions & 2 deletions open_wearable/lib/view_models/wearables_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:open_wearable/models/device_name_formatter.dart';
import 'package:open_wearable/models/wearable_display_group.dart';
import 'package:open_wearable/models/wearable_status_cache.dart';
import 'package:open_wearable/view_models/sensor_configuration_provider.dart';

import 'package:open_earable_flutter/src/models/error/sensor_error.dart';
import '../models/logger.dart';

/// Event emitted when a newer firmware version is available for a wearable.
Expand Down Expand Up @@ -75,9 +75,12 @@ class WearableTimeSynchronizedEvent extends WearableEvent {
/// Emitted when wearable-side operations fail and should surface in UI.
class WearableErrorEvent extends WearableEvent {
final String errorMessage;
final DeviceErrorLevel severity;

WearableErrorEvent({
required super.wearable,
required this.errorMessage,
this.severity = DeviceErrorLevel.error,
String? description,
}) : super(
description: description ??
Expand Down Expand Up @@ -156,6 +159,7 @@ class WearablesProvider with ChangeNotifier {
_wearableEventController.stream;

final Map<Wearable, StreamSubscription> _capabilitySubscriptions = {};
final Map<Wearable, StreamSubscription> _errorSubscriptions = {};

// MARK: Internal helpers

Expand All @@ -179,12 +183,14 @@ class WearablesProvider with ChangeNotifier {
void _emitWearableError({
required Wearable wearable,
required String errorMessage,
DeviceErrorLevel severity = DeviceErrorLevel.error,
String? description,
}) {
_emitWearableEvent(
WearableErrorEvent(
wearable: wearable,
errorMessage: errorMessage,
severity: severity,
description: description,
),
);
Expand Down Expand Up @@ -282,7 +288,7 @@ class WearablesProvider with ChangeNotifier {
),
);
}

_handleWearableErrors(wearable);
// Disconnect listener (sync)
wearable.addDisconnectListener(() {
removeWearable(wearable);
Expand Down Expand Up @@ -506,6 +512,7 @@ class WearablesProvider with ChangeNotifier {
_wearables.remove(wearable);
_sensorConfigurationProviders.remove(wearable)?.dispose();
_capabilitySubscriptions.remove(wearable)?.cancel();
_errorSubscriptions.remove(wearable)?.cancel();
if (!_disposed) {
notifyListeners();
}
Expand Down Expand Up @@ -552,6 +559,10 @@ class WearablesProvider with ChangeNotifier {
unawaited(sub.cancel());
}
_capabilitySubscriptions.clear();
for (final sub in _errorSubscriptions.values) {
unawaited(sub.cancel());
}
_errorSubscriptions.clear();

for (final provider in _sensorConfigurationProviders.values) {
provider.dispose();
Expand All @@ -564,4 +575,28 @@ class WearablesProvider with ChangeNotifier {
unawaited(_wearableEventController.close());
super.dispose();
}

void _handleWearableErrors(Wearable wearable) {
_errorSubscriptions[wearable]?.cancel();
_errorSubscriptions[wearable] = wearable.onError.listen((error) {
if (error is SensorError) {
_emitWearableEvent(
WearableErrorEvent(
wearable: wearable,
errorMessage: error.formattedMessage,
severity: error.level,
description: error.formattedMessage,
),
);
} else {
_emitWearableEvent(
WearableErrorEvent(
wearable: wearable,
errorMessage: error.toString(),
description: error.toString(),
),
);
}
});
}
}
17 changes: 8 additions & 9 deletions open_wearable/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
url: "https://pub.dev"
source: hosted
version: "1.17.0"
version: "1.18.0"
mime:
dependency: transitive
description:
Expand Down Expand Up @@ -563,11 +563,10 @@ packages:
open_earable_flutter:
dependency: "direct main"
description:
name: open_earable_flutter
sha256: "078c8a64ad05265b5b7afae991830549e08729fecacfd255dc4a8e038f8ad12b"
url: "https://pub.dev"
source: hosted
version: "2.3.5"
path: "E:/teco/bluetooth_error/open_earable_flutter"
relative: false
source: path
version: "2.3.6"
open_file:
dependency: "direct main"
description:
Expand Down Expand Up @@ -945,10 +944,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
url: "https://pub.dev"
source: hosted
version: "0.7.10"
version: "0.7.11"
tuple:
dependency: transitive
description:
Expand Down
3 changes: 2 additions & 1 deletion open_wearable/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8
open_file: ^3.3.2
open_earable_flutter: ^2.3.5
open_earable_flutter:
path: E:/teco/bluetooth_error/open_earable_flutter
universal_ble: ^0.21.1
flutter_platform_widgets: ^9.0.0
provider: ^6.1.2
Expand Down