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