|
@@ -24,6 +24,11 @@ import '../health_sleep_calculator.dart'; |
|
@@ -24,6 +24,11 @@ import '../health_sleep_calculator.dart'; |
|
24
|
class AppleHealthRawDataCoreService {
|
24
|
class AppleHealthRawDataCoreService {
|
|
25
|
static const int defaultLookbackDays = 183;
|
25
|
static const int defaultLookbackDays = 183;
|
|
26
|
static const int defaultReadChunkDays = 7;
|
26
|
static const int defaultReadChunkDays = 7;
|
|
|
|
27
|
+ static String _executionEngineType = 'main';
|
|
|
|
28
|
+
|
|
|
|
29
|
+ static void setExecutionEngineType(String value) {
|
|
|
|
30
|
+ _executionEngineType = value;
|
|
|
|
31
|
+ }
|
|
27
|
|
32
|
|
|
28
|
AppleHealthRawDataCoreService({
|
33
|
AppleHealthRawDataCoreService({
|
|
29
|
HealthKitHostApi? healthApi,
|
34
|
HealthKitHostApi? healthApi,
|
|
@@ -107,6 +112,11 @@ class AppleHealthRawDataCoreService { |
|
@@ -107,6 +112,11 @@ class AppleHealthRawDataCoreService { |
|
107
|
_healthDataUpdatedController.stream;
|
112
|
_healthDataUpdatedController.stream;
|
|
108
|
|
113
|
|
|
109
|
Future<bool> onHealthDataUpdated({List<int>? dataTypes}) async {
|
114
|
Future<bool> onHealthDataUpdated({List<int>? dataTypes}) async {
|
|
|
|
115
|
+ await _saveLocalNotificationDebugEvent(<String, Object?>{
|
|
|
|
116
|
+ 'event': 'flutterHealthDataReceived',
|
|
|
|
117
|
+ 'identifier': 'flutter.health_data.received',
|
|
|
|
118
|
+ 'data_types': dataTypes ?? const <int>[],
|
|
|
|
119
|
+ });
|
|
110
|
await _saveNativeCallFlutterChange(dataTypes);
|
120
|
await _saveNativeCallFlutterChange(dataTypes);
|
|
111
|
if (_healthDataUpdatedCalculation != null) {
|
121
|
if (_healthDataUpdatedCalculation != null) {
|
|
112
|
_pendingHealthDataUpdatedTypes = _mergeHealthDataTypes(
|
122
|
_pendingHealthDataUpdatedTypes = _mergeHealthDataTypes(
|
|
@@ -282,6 +292,11 @@ class AppleHealthRawDataCoreService { |
|
@@ -282,6 +292,11 @@ class AppleHealthRawDataCoreService { |
|
282
|
}
|
292
|
}
|
|
283
|
|
293
|
|
|
284
|
final userId = _userId;
|
294
|
final userId = _userId;
|
|
|
|
295
|
+ await _saveLocalNotificationDebugEvent(<String, Object?>{
|
|
|
|
296
|
+ 'event': 'flutterCalculationStarted',
|
|
|
|
297
|
+ 'identifier': 'flutter.calculation.started',
|
|
|
|
298
|
+ 'user_id': userId,
|
|
|
|
299
|
+ });
|
|
285
|
final hasAuthorization = await _hasHealthReadAuthorization();
|
300
|
final hasAuthorization = await _hasHealthReadAuthorization();
|
|
286
|
if (!hasAuthorization) {
|
301
|
if (!hasAuthorization) {
|
|
287
|
return HealthRawStressCalculationResult(
|
302
|
return HealthRawStressCalculationResult(
|
|
@@ -392,6 +407,21 @@ class AppleHealthRawDataCoreService { |
|
@@ -392,6 +407,21 @@ class AppleHealthRawDataCoreService { |
|
392
|
),
|
407
|
),
|
|
393
|
);
|
408
|
);
|
|
394
|
await _localStore.upsertResult(newResult);
|
409
|
await _localStore.upsertResult(newResult);
|
|
|
|
410
|
+ await _saveLocalNotificationDebugEvent(<String, Object?>{
|
|
|
|
411
|
+ 'event': 'flutterCalculationResultStored',
|
|
|
|
412
|
+ 'identifier': 'flutter.calculation.result_stored',
|
|
|
|
413
|
+ 'user_id': userId,
|
|
|
|
414
|
+ 'hrv_count': newResult.hrvStressPoints.length,
|
|
|
|
415
|
+ 'realtime_count': newResult.realtimeStressPoints.length,
|
|
|
|
416
|
+ 'latest_hrv': _latestHrvStressPointPayload(newResult.hrvStressPoints),
|
|
|
|
417
|
+ 'latest_realtime':
|
|
|
|
418
|
+ _latestRealtimeStressPointPayload(newResult.realtimeStressPoints),
|
|
|
|
419
|
+ });
|
|
|
|
420
|
+ await _sendLocalNotificationsAfterCalculation(
|
|
|
|
421
|
+ result: newResult,
|
|
|
|
422
|
+ hasExistingHrv: latestHrvRawEndTime != null,
|
|
|
|
423
|
+ hasExistingSleep: latestSleepResultTime != null,
|
|
|
|
424
|
+ );
|
|
395
|
_scheduleResultUpload('upload hrv results', _uploadHrvResults);
|
425
|
_scheduleResultUpload('upload hrv results', _uploadHrvResults);
|
|
396
|
_scheduleResultUpload(
|
426
|
_scheduleResultUpload(
|
|
397
|
'upload realtime stress results',
|
427
|
'upload realtime stress results',
|
|
@@ -417,7 +447,10 @@ class AppleHealthRawDataCoreService { |
|
@@ -417,7 +447,10 @@ class AppleHealthRawDataCoreService { |
|
417
|
sleepResults: sleepResults,
|
447
|
sleepResults: sleepResults,
|
|
418
|
);
|
448
|
);
|
|
419
|
await _sendLocalNotificationsAfterCalculation(
|
449
|
await _sendLocalNotificationsAfterCalculation(
|
|
420
|
- result: storedResult,
|
450
|
+ result: storedResult.copyWith(
|
|
|
|
451
|
+ hrvStressPoints: const <HealthRawHrvStressPoint>[],
|
|
|
|
452
|
+ realtimeStressPoints: const <HealthRawRealtimeStressPoint>[],
|
|
|
|
453
|
+ ),
|
|
421
|
hasExistingHrv: latestHrvRawEndTime != null,
|
454
|
hasExistingHrv: latestHrvRawEndTime != null,
|
|
422
|
hasExistingSleep: latestSleepResultTime != null,
|
455
|
hasExistingSleep: latestSleepResultTime != null,
|
|
423
|
);
|
456
|
);
|
|
@@ -425,6 +458,15 @@ class AppleHealthRawDataCoreService { |
|
@@ -425,6 +458,15 @@ class AppleHealthRawDataCoreService { |
|
425
|
_logInfo(
|
458
|
_logInfo(
|
|
426
|
'calculateEndAt=${_formatDateTimeMilliseconds(calculateFinishedAt)}',
|
459
|
'calculateEndAt=${_formatDateTimeMilliseconds(calculateFinishedAt)}',
|
|
427
|
);
|
460
|
);
|
|
|
|
461
|
+ await _saveLocalNotificationDebugEvent(<String, Object?>{
|
|
|
|
462
|
+ 'event': 'flutterCalculationFinished',
|
|
|
|
463
|
+ 'identifier': 'flutter.calculation.finished',
|
|
|
|
464
|
+ 'user_id': userId,
|
|
|
|
465
|
+ 'hrv_count': storedResult.hrvStressPoints.length,
|
|
|
|
466
|
+ 'realtime_count': storedResult.realtimeStressPoints.length,
|
|
|
|
467
|
+ 'daily_stress_count': storedResult.dailyStressPoints.length,
|
|
|
|
468
|
+ 'sleep_count': storedResult.sleepResults.length,
|
|
|
|
469
|
+ });
|
|
428
|
return storedResult;
|
470
|
return storedResult;
|
|
429
|
}
|
471
|
}
|
|
430
|
|
472
|
|
|
@@ -436,6 +478,7 @@ class AppleHealthRawDataCoreService { |
|
@@ -436,6 +478,7 @@ class AppleHealthRawDataCoreService { |
|
436
|
await _saveLocalNotificationDebugEvent(
|
478
|
await _saveLocalNotificationDebugEvent(
|
|
437
|
<String, Object?>{
|
479
|
<String, Object?>{
|
|
438
|
'event': 'flutterNotificationCalculationFinished',
|
480
|
'event': 'flutterNotificationCalculationFinished',
|
|
|
|
481
|
+ 'identifier': 'flutter.notification.calculation_finished',
|
|
439
|
'user_id': result.userId,
|
482
|
'user_id': result.userId,
|
|
440
|
'has_existing_hrv': hasExistingHrv,
|
483
|
'has_existing_hrv': hasExistingHrv,
|
|
441
|
'has_existing_sleep': hasExistingSleep,
|
484
|
'has_existing_sleep': hasExistingSleep,
|
|
@@ -452,6 +495,7 @@ class AppleHealthRawDataCoreService { |
|
@@ -452,6 +495,7 @@ class AppleHealthRawDataCoreService { |
|
452
|
await _saveLocalNotificationDebugEvent(
|
495
|
await _saveLocalNotificationDebugEvent(
|
|
453
|
<String, Object?>{
|
496
|
<String, Object?>{
|
|
454
|
'event': 'flutterNotificationRecordRead',
|
497
|
'event': 'flutterNotificationRecordRead',
|
|
|
|
498
|
+ 'identifier': 'flutter.notification.record_read',
|
|
455
|
'user_id': result.userId,
|
499
|
'user_id': result.userId,
|
|
456
|
'record': _localNotificationRecordPayload(record),
|
500
|
'record': _localNotificationRecordPayload(record),
|
|
457
|
},
|
501
|
},
|
|
@@ -463,6 +507,7 @@ class AppleHealthRawDataCoreService { |
|
@@ -463,6 +507,7 @@ class AppleHealthRawDataCoreService { |
|
463
|
await _saveLocalNotificationDebugEvent(
|
507
|
await _saveLocalNotificationDebugEvent(
|
|
464
|
<String, Object?>{
|
508
|
<String, Object?>{
|
|
465
|
'event': 'flutterNotificationLatestDataTimeChecked',
|
509
|
'event': 'flutterNotificationLatestDataTimeChecked',
|
|
|
|
510
|
+ 'identifier': 'flutter.notification.latest_data_checked',
|
|
466
|
'user_id': result.userId,
|
511
|
'user_id': result.userId,
|
|
467
|
'record': _localNotificationRecordPayload(record),
|
512
|
'record': _localNotificationRecordPayload(record),
|
|
468
|
'latest_data_time': candidateData.latestDataTimePayload,
|
513
|
'latest_data_time': candidateData.latestDataTimePayload,
|
|
@@ -475,6 +520,7 @@ class AppleHealthRawDataCoreService { |
|
@@ -475,6 +520,7 @@ class AppleHealthRawDataCoreService { |
|
475
|
await _saveLocalNotificationDebugEvent(
|
520
|
await _saveLocalNotificationDebugEvent(
|
|
476
|
<String, Object?>{
|
521
|
<String, Object?>{
|
|
477
|
'event': 'flutterNotificationNotBuilt',
|
522
|
'event': 'flutterNotificationNotBuilt',
|
|
|
|
523
|
+ 'identifier': 'flutter.notification.not_built',
|
|
478
|
'reason': 'empty_calculation_result',
|
524
|
'reason': 'empty_calculation_result',
|
|
479
|
'user_id': result.userId,
|
525
|
'user_id': result.userId,
|
|
480
|
},
|
526
|
},
|
|
@@ -522,6 +568,7 @@ class AppleHealthRawDataCoreService { |
|
@@ -522,6 +568,7 @@ class AppleHealthRawDataCoreService { |
|
522
|
await _saveLocalNotificationDebugEvent(
|
568
|
await _saveLocalNotificationDebugEvent(
|
|
523
|
<String, Object?>{
|
569
|
<String, Object?>{
|
|
524
|
'event': 'flutterNotificationBuildDecisions',
|
570
|
'event': 'flutterNotificationBuildDecisions',
|
|
|
|
571
|
+ 'identifier': 'flutter.notification.selection_result',
|
|
525
|
'user_id': candidateResult.userId,
|
572
|
'user_id': candidateResult.userId,
|
|
526
|
'decisions': _localNotificationDecisionPayloads(
|
573
|
'decisions': _localNotificationDecisionPayloads(
|
|
527
|
result: notificationResult,
|
574
|
result: notificationResult,
|
|
@@ -542,6 +589,7 @@ class AppleHealthRawDataCoreService { |
|
@@ -542,6 +589,7 @@ class AppleHealthRawDataCoreService { |
|
542
|
await _saveLocalNotificationDebugEvent(
|
589
|
await _saveLocalNotificationDebugEvent(
|
|
543
|
<String, Object?>{
|
590
|
<String, Object?>{
|
|
544
|
'event': 'flutterNotificationBuildFinished',
|
591
|
'event': 'flutterNotificationBuildFinished',
|
|
|
|
592
|
+ 'identifier': 'flutter.notification.selection_finished',
|
|
545
|
'user_id': candidateResult.userId,
|
593
|
'user_id': candidateResult.userId,
|
|
546
|
'notification_count': notifications.length,
|
594
|
'notification_count': notifications.length,
|
|
547
|
'notifications': notifications.map(_localNotificationPayload).toList(),
|
595
|
'notifications': notifications.map(_localNotificationPayload).toList(),
|
|
@@ -551,6 +599,7 @@ class AppleHealthRawDataCoreService { |
|
@@ -551,6 +599,7 @@ class AppleHealthRawDataCoreService { |
|
551
|
await _saveLocalNotificationDebugEvent(
|
599
|
await _saveLocalNotificationDebugEvent(
|
|
552
|
<String, Object?>{
|
600
|
<String, Object?>{
|
|
553
|
'event': 'flutterNotificationNotSent',
|
601
|
'event': 'flutterNotificationNotSent',
|
|
|
|
602
|
+ 'identifier': 'flutter.notification.not_triggered',
|
|
554
|
'reason': 'no_built_notifications',
|
603
|
'reason': 'no_built_notifications',
|
|
555
|
'user_id': candidateResult.userId,
|
604
|
'user_id': candidateResult.userId,
|
|
556
|
},
|
605
|
},
|
|
@@ -563,6 +612,7 @@ class AppleHealthRawDataCoreService { |
|
@@ -563,6 +612,7 @@ class AppleHealthRawDataCoreService { |
|
563
|
await _saveLocalNotificationDebugEvent(
|
612
|
await _saveLocalNotificationDebugEvent(
|
|
564
|
<String, Object?>{
|
613
|
<String, Object?>{
|
|
565
|
'event': 'flutterNotificationSendStart',
|
614
|
'event': 'flutterNotificationSendStart',
|
|
|
|
615
|
+ 'identifier': 'flutter.notification.triggered',
|
|
566
|
'user_id': candidateResult.userId,
|
616
|
'user_id': candidateResult.userId,
|
|
567
|
'notification': _localNotificationPayload(notification),
|
617
|
'notification': _localNotificationPayload(notification),
|
|
568
|
},
|
618
|
},
|
|
@@ -574,6 +624,7 @@ class AppleHealthRawDataCoreService { |
|
@@ -574,6 +624,7 @@ class AppleHealthRawDataCoreService { |
|
574
|
await _saveLocalNotificationDebugEvent(
|
624
|
await _saveLocalNotificationDebugEvent(
|
|
575
|
<String, Object?>{
|
625
|
<String, Object?>{
|
|
576
|
'event': 'flutterNotificationSendFinished',
|
626
|
'event': 'flutterNotificationSendFinished',
|
|
|
|
627
|
+ 'identifier': 'flutter.notification.trigger_finished',
|
|
577
|
'user_id': candidateResult.userId,
|
628
|
'user_id': candidateResult.userId,
|
|
578
|
'sent': sent,
|
629
|
'sent': sent,
|
|
579
|
'reason': sent ? null : 'native_or_dispatcher_returned_false',
|
630
|
'reason': sent ? null : 'native_or_dispatcher_returned_false',
|
|
@@ -1325,6 +1376,11 @@ class AppleHealthRawDataCoreService { |
|
@@ -1325,6 +1376,11 @@ class AppleHealthRawDataCoreService { |
|
1325
|
if (!_uploadResultsAfterCalculation) {
|
1376
|
if (!_uploadResultsAfterCalculation) {
|
|
1326
|
return;
|
1377
|
return;
|
|
1327
|
}
|
1378
|
}
|
|
|
|
1379
|
+ unawaited(_saveLocalNotificationDebugEvent(<String, Object?>{
|
|
|
|
1380
|
+ 'event': 'flutterCalculationResultUploadTriggered',
|
|
|
|
1381
|
+ 'identifier': 'flutter.calculation_result_upload.triggered',
|
|
|
|
1382
|
+ 'upload_action': action,
|
|
|
|
1383
|
+ }));
|
|
1328
|
unawaited(
|
1384
|
unawaited(
|
|
1329
|
(() async {
|
1385
|
(() async {
|
|
1330
|
try {
|
1386
|
try {
|
|
@@ -1505,14 +1561,21 @@ class AppleHealthRawDataCoreService { |
|
@@ -1505,14 +1561,21 @@ class AppleHealthRawDataCoreService { |
|
1505
|
|
1561
|
|
|
1506
|
Future<void> _saveLocalNotificationDebugEvent(
|
1562
|
Future<void> _saveLocalNotificationDebugEvent(
|
|
1507
|
Map<String, Object?> event,
|
1563
|
Map<String, Object?> event,
|
|
1508
|
- ) async {
|
|
|
|
1509
|
- try {
|
|
|
|
1510
|
- await _localNotificationDebugStore.append(event);
|
|
|
|
1511
|
- await _saveNativeLocalNotificationDebugEvent(event);
|
|
|
|
1512
|
- } catch (error, stackTrace) {
|
|
|
|
1513
|
- _logError(
|
|
|
|
1514
|
- 'save local notification debug event failed', error, stackTrace);
|
|
|
|
1515
|
- }
|
1564
|
+ ) {
|
|
|
|
1565
|
+ final pipelineEvent = <String, Object?>{
|
|
|
|
1566
|
+ ...event,
|
|
|
|
1567
|
+ 'engine_type': _executionEngineType,
|
|
|
|
1568
|
+ };
|
|
|
|
1569
|
+ unawaited(() async {
|
|
|
|
1570
|
+ try {
|
|
|
|
1571
|
+ await _saveNativeLocalNotificationDebugEvent(pipelineEvent).timeout(
|
|
|
|
1572
|
+ const Duration(seconds: 1),
|
|
|
|
1573
|
+ );
|
|
|
|
1574
|
+ } catch (error, stackTrace) {
|
|
|
|
1575
|
+ _logError('save health pipeline event failed', error, stackTrace);
|
|
|
|
1576
|
+ }
|
|
|
|
1577
|
+ }());
|
|
|
|
1578
|
+ return Future<void>.value();
|
|
1516
|
}
|
1579
|
}
|
|
1517
|
|
1580
|
|
|
1518
|
Future<bool> _saveNativeLocalNotificationDebugEvent(
|
1581
|
Future<bool> _saveNativeLocalNotificationDebugEvent(
|