Commit 72d5402754132eddf0e8718e86f1b718efab0c16

Authored by 权海
1 parent 0af28457

feat(ui):增加日志系统

@@ -400,6 +400,8 @@ protocol HealthKitRawDataHostApi { @@ -400,6 +400,8 @@ protocol HealthKitRawDataHostApi {
400 func shareNativeAppleHealthObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void) 400 func shareNativeAppleHealthObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void)
401 /// 让原生分享出来flutter的记录文件 401 /// 让原生分享出来flutter的记录文件
402 func shareFlutterObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void) 402 func shareFlutterObserverRecord(completion: @escaping (Result<Bool, Error>) -> Void)
  403 + /// 让原生分享出来上传记录
  404 + func shareUploadTaskRecord(completion: @escaping (Result<Bool, Error>) -> Void)
403 } 405 }
404 406
405 /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. 407 /// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
@@ -680,5 +682,21 @@ class HealthKitRawDataHostApiSetup { @@ -680,5 +682,21 @@ class HealthKitRawDataHostApiSetup {
680 } else { 682 } else {
681 shareFlutterObserverRecordChannel.setMessageHandler(nil) 683 shareFlutterObserverRecordChannel.setMessageHandler(nil)
682 } 684 }
  685 + /// 让原生分享出来上传记录
  686 + let shareUploadTaskRecordChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareUploadTaskRecord\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
  687 + if let api = api {
  688 + shareUploadTaskRecordChannel.setMessageHandler { _, reply in
  689 + api.shareUploadTaskRecord { result in
  690 + switch result {
  691 + case .success(let res):
  692 + reply(wrapResult(res))
  693 + case .failure(let error):
  694 + reply(wrapError(error))
  695 + }
  696 + }
  697 + }
  698 + } else {
  699 + shareUploadTaskRecordChannel.setMessageHandler(nil)
  700 + }
683 } 701 }
684 } 702 }
@@ -24,6 +24,7 @@ enum DeveloperOptionsAction { @@ -24,6 +24,7 @@ enum DeveloperOptionsAction {
24 shareHealthRawUploadLog, 24 shareHealthRawUploadLog,
25 shareNativeAppleHealthObserverRecord, 25 shareNativeAppleHealthObserverRecord,
26 shareFlutterObserverRecord, 26 shareFlutterObserverRecord,
  27 + shareUploadTaskRecord,
27 clearHealthRawDataDatabaseAndUploadLog, 28 clearHealthRawDataDatabaseAndUploadLog,
28 } 29 }
29 30
@@ -68,6 +69,10 @@ class DeveloperOptionsController extends GetxController { @@ -68,6 +69,10 @@ class DeveloperOptionsController extends GetxController {
68 action: DeveloperOptionsAction.shareFlutterObserverRecord, 69 action: DeveloperOptionsAction.shareFlutterObserverRecord,
69 ), 70 ),
70 DeveloperOptionsItem( 71 DeveloperOptionsItem(
  72 + title: '分享上传Task日志',
  73 + action: DeveloperOptionsAction.shareUploadTaskRecord,
  74 + ),
  75 + DeveloperOptionsItem(
71 title: '清除本地数据库、上传日志', 76 title: '清除本地数据库、上传日志',
72 action: DeveloperOptionsAction.clearHealthRawDataDatabaseAndUploadLog, 77 action: DeveloperOptionsAction.clearHealthRawDataDatabaseAndUploadLog,
73 ), 78 ),
@@ -99,6 +104,9 @@ class DeveloperOptionsController extends GetxController { @@ -99,6 +104,9 @@ class DeveloperOptionsController extends GetxController {
99 case DeveloperOptionsAction.shareFlutterObserverRecord: 104 case DeveloperOptionsAction.shareFlutterObserverRecord:
100 await shareFlutterObserverRecord(); 105 await shareFlutterObserverRecord();
101 break; 106 break;
  107 + case DeveloperOptionsAction.shareUploadTaskRecord:
  108 + await shareUploadTaskRecord();
  109 + break;
102 case DeveloperOptionsAction.clearHealthRawDataDatabaseAndUploadLog: 110 case DeveloperOptionsAction.clearHealthRawDataDatabaseAndUploadLog:
103 await clearHealthRawDataDatabaseAndUploadLog(); 111 await clearHealthRawDataDatabaseAndUploadLog();
104 break; 112 break;
@@ -153,6 +161,19 @@ class DeveloperOptionsController extends GetxController { @@ -153,6 +161,19 @@ class DeveloperOptionsController extends GetxController {
153 } 161 }
154 } 162 }
155 163
  164 + Future<void> shareUploadTaskRecord() async {
  165 + try {
  166 + await _healthRawDataCoreService.shareUploadTaskRecord();
  167 + } catch (error, stackTrace) {
  168 + AppLogger.e(
  169 + 'Share upload task record failed',
  170 + error,
  171 + stackTrace,
  172 + );
  173 + Get.snackbar('Share failed', error.toString());
  174 + }
  175 + }
  176 +
156 Future<void> clearHealthRawDataDatabaseAndUploadLog() async { 177 Future<void> clearHealthRawDataDatabaseAndUploadLog() async {
157 try { 178 try {
158 await _healthRawDataCoreService.clearLocalDatabaseAndUploadLog(); 179 await _healthRawDataCoreService.clearLocalDatabaseAndUploadLog();
@@ -172,6 +172,11 @@ class HealthRawDataCoreService { @@ -172,6 +172,11 @@ class HealthRawDataCoreService {
172 return _rawDataApi.shareFlutterObserverRecord(); 172 return _rawDataApi.shareFlutterObserverRecord();
173 } 173 }
174 174
  175 + Future<bool> shareUploadTaskRecord() async {
  176 + if (!_isDebug) return false;
  177 + return _rawDataApi.shareUploadTaskRecord();
  178 + }
  179 +
175 Future<HealthRawStressCalculationResult> startCoreCaculate({ 180 Future<HealthRawStressCalculationResult> startCoreCaculate({
176 int? endTime, 181 int? endTime,
177 int readChunkDays = defaultReadChunkDays, 182 int readChunkDays = defaultReadChunkDays,
@@ -38,7 +38,18 @@ Future<void> healthBackgroundMain() async { @@ -38,7 +38,18 @@ Future<void> healthBackgroundMain() async {
38 WidgetsFlutterBinding.ensureInitialized(); 38 WidgetsFlutterBinding.ensureInitialized();
39 const channel = MethodChannel('doublefeel_flutter_health_background_channel'); 39 const channel = MethodChannel('doublefeel_flutter_health_background_channel');
40 40
41 - await AppBootstrap.init(); 41 + await _healthBackgroundLog(channel, 'entry.start');
  42 + try {
  43 + await _healthBackgroundLog(channel, 'bootstrap.start');
  44 + await AppBootstrap.init();
  45 + await _healthBackgroundLog(channel, 'bootstrap.success');
  46 + } catch (error, stackTrace) {
  47 + await _healthBackgroundLog(
  48 + channel,
  49 + 'bootstrap.failed error=$error stack=$stackTrace',
  50 + );
  51 + rethrow;
  52 + }
42 53
43 channel.setMethodCallHandler((call) async { 54 channel.setMethodCallHandler((call) async {
44 switch (call.method) { 55 switch (call.method) {
@@ -53,6 +64,7 @@ Future<void> healthBackgroundMain() async { @@ -53,6 +64,7 @@ Future<void> healthBackgroundMain() async {
53 await channel.invokeMethod('healthBackgroundTaskReady', { 64 await channel.invokeMethod('healthBackgroundTaskReady', {
54 'timestamp': DateTime.now().millisecondsSinceEpoch ~/ 1000, 65 'timestamp': DateTime.now().millisecondsSinceEpoch ~/ 1000,
55 }); 66 });
  67 + await _healthBackgroundLog(channel, 'entry.readySent');
56 } 68 }
57 69
58 Future<void> _runPendingHealthTasks( 70 Future<void> _runPendingHealthTasks(
@@ -60,6 +72,10 @@ Future<void> _runPendingHealthTasks( @@ -60,6 +72,10 @@ Future<void> _runPendingHealthTasks(
60 Object? arguments, 72 Object? arguments,
61 ) async { 73 ) async {
62 final tasks = _backgroundHealthTasksFromArguments(arguments); 74 final tasks = _backgroundHealthTasksFromArguments(arguments);
  75 + await _healthBackgroundLog(
  76 + channel,
  77 + 'tasks.received count=${tasks.length} ids=${tasks.map((e) => e.taskId).join(',')}',
  78 + );
63 if (tasks.isEmpty) return; 79 if (tasks.isEmpty) return;
64 80
65 for (final task in tasks) { 81 for (final task in tasks) {
@@ -71,6 +87,10 @@ Future<void> _runPendingHealthTasks( @@ -71,6 +87,10 @@ Future<void> _runPendingHealthTasks(
71 final userPrefs = Get.find<UserPreferencesStorage>(); 87 final userPrefs = Get.find<UserPreferencesStorage>();
72 final userId = userPrefs.preferences.value.meUserInfo?.id ?? 0; 88 final userId = userPrefs.preferences.value.meUserInfo?.id ?? 0;
73 final token = userPrefs.accessToken; 89 final token = userPrefs.accessToken;
  90 + await _healthBackgroundLog(
  91 + channel,
  92 + 'login.check userId=$userId hasToken=${token.isNotEmpty}',
  93 + );
74 if (userId <= 0 || token.isEmpty) { 94 if (userId <= 0 || token.isEmpty) {
75 for (final task in tasks) { 95 for (final task in tasks) {
76 await channel.invokeMethod('healthBackgroundTaskFinished', { 96 await channel.invokeMethod('healthBackgroundTaskFinished', {
@@ -84,7 +104,9 @@ Future<void> _runPendingHealthTasks( @@ -84,7 +104,9 @@ Future<void> _runPendingHealthTasks(
84 } 104 }
85 105
86 try { 106 try {
  107 + await _healthBackgroundLog(channel, 'calculate.start');
87 await Get.find<HealthRawDataCoreService>().startCoreCaculate(); 108 await Get.find<HealthRawDataCoreService>().startCoreCaculate();
  109 + await _healthBackgroundLog(channel, 'calculate.success');
88 for (final task in tasks) { 110 for (final task in tasks) {
89 await channel.invokeMethod('healthBackgroundTaskFinished', { 111 await channel.invokeMethod('healthBackgroundTaskFinished', {
90 'taskId': task.taskId, 112 'taskId': task.taskId,
@@ -92,6 +114,7 @@ Future<void> _runPendingHealthTasks( @@ -92,6 +114,7 @@ Future<void> _runPendingHealthTasks(
92 }); 114 });
93 } 115 }
94 } catch (error) { 116 } catch (error) {
  117 + await _healthBackgroundLog(channel, 'calculate.failed error=$error');
95 for (final task in tasks) { 118 for (final task in tasks) {
96 await channel.invokeMethod('healthBackgroundTaskFinished', { 119 await channel.invokeMethod('healthBackgroundTaskFinished', {
97 'taskId': task.taskId, 120 'taskId': task.taskId,
@@ -103,6 +126,15 @@ Future<void> _runPendingHealthTasks( @@ -103,6 +126,15 @@ Future<void> _runPendingHealthTasks(
103 } 126 }
104 } 127 }
105 128
  129 +Future<void> _healthBackgroundLog(MethodChannel channel, String message) async {
  130 + try {
  131 + await channel.invokeMethod('healthBackgroundLog', {
  132 + 'message': message,
  133 + 'timestamp': DateTime.now().millisecondsSinceEpoch ~/ 1000,
  134 + });
  135 + } catch (_) {}
  136 +}
  137 +
106 List<_BackgroundHealthTask> _backgroundHealthTasksFromArguments( 138 List<_BackgroundHealthTask> _backgroundHealthTasksFromArguments(
107 Object? arguments, 139 Object? arguments,
108 ) { 140 ) {
@@ -821,4 +821,33 @@ class HealthKitRawDataHostApi { @@ -821,4 +821,33 @@ class HealthKitRawDataHostApi {
821 return (pigeonVar_replyList[0] as bool?)!; 821 return (pigeonVar_replyList[0] as bool?)!;
822 } 822 }
823 } 823 }
  824 +
  825 + /// 让原生分享出来上传记录
  826 + Future<bool> shareUploadTaskRecord() async {
  827 + final String pigeonVar_channelName = 'dev.flutter.pigeon.doublefeel_flutter.HealthKitRawDataHostApi.shareUploadTaskRecord$pigeonVar_messageChannelSuffix';
  828 + final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
  829 + pigeonVar_channelName,
  830 + pigeonChannelCodec,
  831 + binaryMessenger: pigeonVar_binaryMessenger,
  832 + );
  833 + final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
  834 + final List<Object?>? pigeonVar_replyList =
  835 + await pigeonVar_sendFuture as List<Object?>?;
  836 + if (pigeonVar_replyList == null) {
  837 + throw _createConnectionError(pigeonVar_channelName);
  838 + } else if (pigeonVar_replyList.length > 1) {
  839 + throw PlatformException(
  840 + code: pigeonVar_replyList[0]! as String,
  841 + message: pigeonVar_replyList[1] as String?,
  842 + details: pigeonVar_replyList[2],
  843 + );
  844 + } else if (pigeonVar_replyList[0] == null) {
  845 + throw PlatformException(
  846 + code: 'null-error',
  847 + message: 'Host platform returned null value for non-null return value.',
  848 + );
  849 + } else {
  850 + return (pigeonVar_replyList[0] as bool?)!;
  851 + }
  852 + }
824 } 853 }
@@ -162,4 +162,8 @@ abstract class HealthKitRawDataHostApi { @@ -162,4 +162,8 @@ abstract class HealthKitRawDataHostApi {
162 /// 让原生分享出来flutter的记录文件 162 /// 让原生分享出来flutter的记录文件
163 @async 163 @async
164 bool shareFlutterObserverRecord(); 164 bool shareFlutterObserverRecord();
  165 +
  166 + /// 让原生分享出来上传记录
  167 + @async
  168 + bool shareUploadTaskRecord();
165 } 169 }