3e3045d4be006a22b9327eef82ad783d1cabc646
[mirrors/FD230.git] /
1 /*\r
2  * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.\r
3  * Description: AlarmClockTimer\r
4  * Create: 2021-09-22\r
5  */\r
6 \r
7 #include <ctime>\r
8 #include <sys/time.h>\r
9 #include <cstdio>\r
10 #include "wearable_log.h"\r
11 #include "securec.h"\r
12 #include "broadcast_service.h"\r
13 #include "broadcast_feature.h"\r
14 #include "service_id_define.h"\r
15 #include "samgr_lite.h"\r
16 #include "thread_adapter.h"\r
17 #include "graphic_service.h"\r
18 \r
19 #include "alarmclocktimerconfig/include/AlarmClockTimerConfig.h"\r
20 \r
21 #include "ConfigModelC.h"\r
22 #include "ConfigModel.h"\r
23 #include "heartrate/include/HeartModel.h"\r
24 #include "sleep/include/SleepModel.h"\r
25 #include "sleepmode/include/SleepModeModel.h"\r
26 // #include "safemodemanager/include/SafeModeManagerModel.h"\r
27 #ifdef SUPPORT_CAT1_SERVICE\r
28 #include "cat1_server_hal.h"\r
29 #endif\r
30 #include "custom_runtime.h"\r
31 #include "uiservice/include/ui_service.h"\r
32 #include "power_display_service.h"\r
33 #include <NativeAbility.h>\r
34 #include "AppViewIDs.h"\r
35 #include "player/include/PlayersView.h"\r
36 #include "record/include/RecordingPlayerView.h"\r
37 #include "custom_utils.h"\r
38 #include "alarm/include/AlarmClockModel.h"\r
39 #ifdef SUPPORT_CYWEE_SERVICE\r
40 #include "cywee_service.h"\r
41 #endif\r
42 \r
43 #ifdef SUPPORT_PPG_SERVICE\r
44 #include "ppg_service.h"\r
45 #endif\r
46 \r
47 #ifdef __cplusplus\r
48 extern "C"\r
49 {\r
50 #endif\r
51 \r
52     static AlarmCtrl g_alarmCtrA;\r
53     static AlarmCtrl g_alarmCtrB;\r
54     static osTimerId_t g_AlarmHandle = nullptr;\r
55 \r
56 #define SLEPPNOTIFY 20\r
57 \r
58     static int sleep_time = 0;\r
59     static int wake_up_time = 0;\r
60     static int sleep_notify_time = 0;\r
61     static int sleep_time_hour = 0;\r
62     static int sleep_time_min = 0;\r
63     static int wake_time_hour = 0;\r
64     static int wake_time_min = 0;\r
65     static int sedentary_switch = 0;\r
66     static int sedentary_interval = 1;\r
67     static int sedentary_time = 0;\r
68     static int sedentary_start_hour = 0;\r
69     static int sedentary_start_min = 0;\r
70     static int sedentary_stop_hour = 0;\r
71     static int sedentary_stop_min = 0;\r
72     static int drinkreminder_switch = 0;     /*喝水提醒开关:0 关闭 1开始 2间隔提醒*/\r
73     static int drinkreminder_start_time = 0; /*喝水提醒开始时间*/\r
74     static int drinkreminder_start_hour = 0; /*喝水提醒开始小时*/\r
75     static int drinkreminder_start_min = 0;  /*喝水提醒开始分钟*/\r
76     static int drinkreminder_end_time = 0;   /*喝水提醒结束时间*/\r
77     static int drinkreminder_end_hour = 0;   /*喝水提醒结束小时*/\r
78     static int drinkreminder_end_min = 0;    /*喝水提醒结束分钟*/\r
79     static int drinkreminder_freq = 0;       /*喝水提醒频率*/\r
80     static int drinkreminder_goal = 0;       /*喝水提醒目标ml*/\r
81     static int drinkremind_expectedTime = 0;\r
82     static int sleep_notify_time_min = 0;\r
83     static int sleep_notify_time_hour = 0;\r
84     static int time_sync_flag = 0;\r
85 \r
86     // #define SEDENTARY_TIME_RANGE (((curTime.tm_hour > sedentary_start_hour) || (curTime.tm_hour == sedentary_start_hour && curTime.tm_min >= sedentary_start_min)) && \\r
87 //                               ((curTime.tm_hour < sedentary_stop_hour) || (curTime.tm_hour == sedentary_stop_hour && curTime.tm_min < sedentary_stop_min)))\r
88 \r
89     // #define WAKE_TIME_RANGE (((wake_time_hour < sleep_time_hour) &&                                              \\r
90 //                           ((curTime.tm_hour > wake_time_hour) ||                                             \\r
91 //                            (curTime.tm_hour == wake_time_hour && curTime.tm_min >= wake_time_min)) &&        \\r
92 //                           ((curTime.tm_hour < sleep_time_hour) ||                                            \\r
93 //                            (curTime.tm_hour == sleep_time_hour && curTime.tm_min < sleep_time_min))) ||      \\r
94 //                          ((wake_time_hour >= sleep_time_hour) &&                                             \\r
95 //                               (((curTime.tm_hour > wake_time_hour) ||                                        \\r
96 //                                 (curTime.tm_hour == wake_time_hour && curTime.tm_min >= wake_time_min)) ||   \\r
97 //                                ((curTime.tm_hour < sleep_time_hour) ||                                       \\r
98 //                                 (curTime.tm_hour == sleep_time_hour && curTime.tm_min < sleep_time_min))) || \\r
99 //                           ((curTime.tm_hour > wake_time_hour) && (curTime.tm_hour < sleep_time_hour))))\r
100 \r
101     // 设置目标睡眠时间\r
102     void set_sleep_and_wake_time(void)\r
103     {\r
104         sleep_time = get_sleep_time_from_config_model();\r
105         wake_up_time = get_wake_up_time_from_config_model();\r
106         // 解析开始时间\r
107         sleep_time_hour = (sleep_time & 0xFFFF0000) >> 16;\r
108         sleep_time_min = sleep_time & 0x0000FFFF;\r
109         wake_time_hour = (wake_up_time & 0xFFFF0000) >> 16;\r
110         wake_time_min = wake_up_time & 0x0000FFFF;\r
111         clean_sleep_monitoring_flag();\r
112         // 解析结束时间\r
113         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sleep_time_hour:%d sleep_time_min:%d wake_time_hour:%d wake_time_min:%d", sleep_time_hour, sleep_time_min, wake_time_hour, wake_time_min);\r
114     }\r
115 \r
116     void set_sedentary_data(void)\r
117     {\r
118         sedentary_switch = get_sedentary_switch_from_config_model();\r
119         sedentary_time = get_sedentary_time_from_config_model();\r
120         sedentary_interval = get_sedentary_interval_from_config_model();\r
121 #ifdef SUPPORT_CYWEE_SERVICE\r
122         do_cywee_service_check_msg(CYWEE_SERVICE_CMD_SET_SEDENTARY_INTERVAL, &sedentary_interval); // 设置久坐提醒间隔\r
123 #endif\r
124 \r
125         // sedentary_start_hour = (sedentary_time & 0XFF000000) >> 24;\r
126         // sedentary_start_min = (sedentary_time & 0X00FF0000) >> 16;\r
127         // sedentary_stop_hour = (sedentary_time & 0X0000FF00) >> 8;\r
128         // sedentary_stop_min = sedentary_time & 0X000000FF;\r
129         sedentary_stop_min = (sedentary_time & 0XFF000000) >> 24;\r
130         sedentary_stop_hour = (sedentary_time & 0X00FF0000) >> 16;\r
131         sedentary_start_min = (sedentary_time & 0X0000FF00) >> 8;\r
132         sedentary_start_hour = sedentary_time & 0X000000FF;\r
133         clean_sedentary_flag();\r
134         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "set_sedentary_data:%d:%d~%d:%d", sedentary_start_hour, sedentary_start_min, sedentary_stop_hour, sedentary_stop_min);\r
135     }\r
136 \r
137     void set_drinkreminder_data(void)\r
138     {\r
139         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "set_drinkreminder_data");\r
140         drinkreminder_switch = OHOS::ConfigModel::GetInstance()->GetDrinkSwitch();\r
141         drinkreminder_freq = OHOS::ConfigModel::GetInstance()->GetDrinkFreq();\r
142         drinkreminder_goal = OHOS::ConfigModel::GetInstance()->GetDrinkGoal();\r
143 \r
144         // 获取提醒时间段\r
145         drinkreminder_start_time = OHOS::ConfigModel::GetInstance()->GetDrinkStart(); // 获取喝水提醒开始时间,int类型 前16位小时,后16位分钟\r
146         drinkreminder_end_time = OHOS::ConfigModel::GetInstance()->GetDrinkEnd();     // 获取喝水提醒结束时间, int类型 前16位小时,后16位分钟\r
147 \r
148         // 解析开始时间\r
149         drinkreminder_start_hour = (drinkreminder_start_time & 0XFFFF0000) >> 16; // 前16位是小时\r
150         drinkreminder_start_min = drinkreminder_start_time & 0X0000FFFF;          // 后16位是分钟\r
151         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "%d:%d", drinkreminder_start_hour, drinkreminder_start_min);\r
152 \r
153         // 解析结束时间\r
154         drinkreminder_end_hour = (drinkreminder_end_time & 0XFFFF0000) >> 16; // 前16位是小时\r
155         drinkreminder_end_min = drinkreminder_end_time & 0x0000FFFF;          // 后16位是分钟\r
156         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "%d:%d", drinkreminder_end_hour, drinkreminder_end_min);\r
157 \r
158         if (drinkreminder_switch == 2)\r
159         {\r
160             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "%d:%d~%d:%d", drinkreminder_start_hour, drinkreminder_start_min, drinkreminder_end_hour, drinkreminder_end_min);\r
161         }\r
162     }\r
163 \r
164     static bool is_time_range(const struct tm &curTime, int start_time_hour, int start_time_min, int end_time_hour, int end_time_min)\r
165     {\r
166         int start_min = start_time_hour * 60 + start_time_min;    /* 开始时间的分钟数 */\r
167         int end_min = end_time_hour * 60 + end_time_min;          /* 结束时间的分钟数 */\r
168         int cur_time_min = curTime.tm_hour * 60 + curTime.tm_min; /* 当前时间的分钟数 */\r
169 \r
170         // 处理非跨天的情况\r
171         if (end_min > start_min)\r
172         {\r
173             if (cur_time_min >= start_min && cur_time_min < end_min)\r
174             {\r
175                 return true;\r
176             }\r
177         }\r
178         else // 处理跨天的情况\r
179         {\r
180             if (cur_time_min >= start_min || cur_time_min < end_min)\r
181             {\r
182                 return true;\r
183             }\r
184         }\r
185         return false;\r
186     }\r
187 \r
188     void clean_sleep_monitoring_flag(void)\r
189     {\r
190         uapi_dev_runtime_set_sleep_monitoring_status(0);\r
191         uapi_dev_runtime_set_nap_monitoring_status(0);\r
192     }\r
193 \r
194     void clean_sedentary_flag(void)\r
195     {\r
196         uapi_dev_runtime_set_sedentary_status(0);\r
197     }\r
198 \r
199     // 设置睡眠提醒时间\r
200     void get_sleep_time_notify(void)\r
201     {\r
202         int goal_hour = (sleep_time & 0XFFFF0000) >> 16;\r
203         int goal_min = (sleep_time & 0X0000FFFF);\r
204         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "goal_hour:%d goal_min:%d", goal_hour, goal_min);\r
205 \r
206         sleep_notify_time_min = (goal_min >= SLEPPNOTIFY) ? goal_min - SLEPPNOTIFY : ((goal_min + 60) - SLEPPNOTIFY); // 避免分钟数为负\r
207         sleep_notify_time_hour = goal_hour;\r
208         if (goal_min < SLEPPNOTIFY)\r
209         {                                // 如果需要借位\r
210             sleep_notify_time_hour -= 1; // 小时减1\r
211         }\r
212         // 确保小时数正确\r
213         sleep_notify_time_hour = (sleep_notify_time_hour < 0) ? 23 : sleep_notify_time_hour; // 处理从0点前20分钟的情况,变为前一天的23点40分\r
214 \r
215         sleep_notify_time = (sleep_notify_time_hour << 16) | sleep_notify_time_min;\r
216         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sleep_notify_time_hour:%d sleep_notify_time_min:%d sleep_notify_time:%d", sleep_notify_time_hour, sleep_notify_time_min, sleep_notify_time);\r
217     }\r
218     void AlarmEventPublish(uint16_t topic, uint8_t *data, uint32_t size)\r
219     {\r
220         int32 ret;\r
221 \r
222         BroadcastApi *broadcastApi = NULL;\r
223         IUnknown *api = NULL;\r
224         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChargerEventPublish topic=%u!!", topic);\r
225 \r
226         void *publishData = nullptr;\r
227         if (size > 0)\r
228         {\r
229             publishData = malloc(size);\r
230             if (publishData == nullptr)\r
231             {\r
232                 return;\r
233             }\r
234             ret = memcpy_s(publishData, size, (const void *)data, size);\r
235             if (ret != EOK)\r
236             {\r
237                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ChargerEventPublish memcpy_s rateDataTmp fail! ret = %d", ret);\r
238                 free(publishData);\r
239                 return;\r
240             }\r
241         }\r
242 \r
243         Request request = {.msgId = topic, .len = size, .msgValue = 0, .data = publishData};\r
244 \r
245         /* public request */\r
246         api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME);\r
247         if (api == NULL)\r
248         {\r
249             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetFeatureApi failed");\r
250             free(publishData);\r
251             return;\r
252         }\r
253         ret = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);\r
254         if (ret != 0 || broadcastApi == NULL)\r
255         {\r
256             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "QueryInterface failed");\r
257             free(publishData);\r
258             return;\r
259         }\r
260         broadcastApi->PublishTopic((IUnknown *)broadcastApi, &request);\r
261         broadcastApi->Release((IUnknown *)broadcastApi);\r
262         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ChargerEventPublish end!!");\r
263 \r
264         return;\r
265     }\r
266     void AlarmTimerEventPublish(uint16 topic, AlarmClockEventData data)\r
267     {\r
268         int32 ret;\r
269         uint32 size = sizeof(AlarmClockEventData);\r
270         BroadcastApi *broadcastApi = nullptr;\r
271         IUnknown *api = nullptr;\r
272 \r
273         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AlarmTimerEventPublish topic=%u!!", topic);\r
274 \r
275         void *publishData = malloc(size);\r
276         if (publishData == nullptr)\r
277         {\r
278             return;\r
279         }\r
280         ret = memcpy_s(publishData, size, (const void *)&data, size);\r
281         if (ret != EOK)\r
282         {\r
283             free(publishData);\r
284             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AlarmTimerEventPublish memcpy_s fail! ret = %d", ret);\r
285             return;\r
286         }\r
287 \r
288         Request request = {\r
289             .msgId = topic,\r
290             .len = size,\r
291             .msgValue = 0,\r
292             .data = publishData,\r
293         };\r
294 \r
295         /* public request */\r
296         api = SAMGR_GetInstance()->GetFeatureApi(BROADCAST_SERVICE_NAME, BROADCAST_FEATURE_NAME);\r
297         if (api == nullptr)\r
298         {\r
299             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetFeatureApi failed");\r
300             free(publishData);\r
301             return;\r
302         }\r
303         ret = api->QueryInterface(api, DEFAULT_VERSION, (void **)&broadcastApi);\r
304         if (ret != 0 || broadcastApi == nullptr)\r
305         {\r
306             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "QueryInterface failed");\r
307             free(publishData);\r
308             return;\r
309         }\r
310         broadcastApi->PublishTopic((IUnknown *)broadcastApi, &request);\r
311         broadcastApi->Release((IUnknown *)broadcastApi);\r
312         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AlarmTimerEventPublish end!!");\r
313 \r
314         return;\r
315     }\r
316     /*闹钟*/\r
317     static void AlarmCallBackProcA(void)\r
318     {\r
319         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AlarmCallBackProcA");\r
320         AlarmClockEventData unuse;\r
321         AlarmTimerEventPublish(TOPIC_EVENT_ALARM_RING, unuse);\r
322     }\r
323 \r
324     /*NextDay*/\r
325     static void AlarmCallBackProcB(void)\r
326     {\r
327         AlarmClockEventData unuse;\r
328         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AlarmCallBackProcB");\r
329 #if 0\r
330     // 记录当前时间\r
331     time_t now = time(nullptr);\r
332     struct tm *localTime = localtime(&now);\r
333     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Current time - Hour: %d, Minute: %d", localTime->tm_hour, localTime->tm_min);\r
334     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Posting next day update event");\r
335 \r
336 #endif\r
337 \r
338         GraphicService::GetInstance()->PostGraphicEvent(std::bind(AlarmTimerEventPublish, TOPIC_EVENT_NEXTDAY_UPDATE, unuse));\r
339 \r
340         // AlarmTimerEventPublish(TOPIC_EVENT_NEXTDAY_UPDATE, unuse);\r
341 \r
342         // 重置nextday闹钟\r
343         SetZeroAlarm();\r
344     }\r
345 \r
346     static void on_time_CallBackProc(void)\r
347     {\r
348         AlarmClockEventData unuse;\r
349         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "on_time_CallBackProc invoked");\r
350         AlarmTimerEventPublish(TOPIC_EVENT_ON_TIME, unuse);\r
351         // GraphicService::GetInstance()->PostGraphicEvent(\r
352         // std::bind(AlarmTimerEventPublish, TOPIC_EVENT_ON_TIME, unuse));\r
353 \r
354         // AlarmTimerEventPublish(TOPIC_EVENT_ON_TIME, unuse);\r
355     }\r
356 \r
357     void AlarmScan(void *arg)\r
358     {\r
359         struct tm curTime;\r
360         int32_t ret = AlarmGetCurrentTimeInfo(&curTime);\r
361         if (ret != ERRCODE_SUCC)\r
362         {\r
363             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get current time info, error code: %d", ret);\r
364             return;\r
365         }\r
366 \r
367         if (curTime.tm_sec % 3 == 0)\r
368         {\r
369             do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_BLE_ADV_CHECK, nullptr, 0); // 3秒钟检查一次广播\r
370         }\r
371 \r
372         if (curTime.tm_sec % 60 == 0)\r
373         {\r
374 #ifdef SUPPORT_CYWEE_SERVICE\r
375             do_cywee_service_check_msg(CYWEE_SERVICE_CMD_CHECK_ACC, NULL); // 一分钟检查一次gsensor是否停止\r
376 #endif\r
377         }\r
378 \r
379         if (g_alarmCtrA.state == ALARM_STATUS_RUNNING)\r
380         {\r
381             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Checking Alarm A");\r
382             if ((g_alarmCtrA.callback != nullptr) &&\r
383                 (g_alarmCtrA.info.hour == curTime.tm_hour) &&\r
384                 (g_alarmCtrA.info.minute == curTime.tm_min))\r
385             {\r
386                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Alarm A triggered");\r
387                 OHOS::AlarmClockModel::GetInstance()->SetPopTimeData(g_alarmCtrA.info.hour, g_alarmCtrA.info.minute);\r
388                 g_alarmCtrA.state = ALARM_STATUS_CREATED;\r
389                 g_alarmCtrA.callback();\r
390             }\r
391         }\r
392 \r
393         if (g_alarmCtrB.state == ALARM_STATUS_RUNNING)\r
394         {\r
395             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Checking Alarm B");\r
396             if ((g_alarmCtrB.callback != NULL) &&\r
397                 // (g_alarmCtrB.info.week == curTime.tm_wday) &&\r
398                 (g_alarmCtrB.info.hour == curTime.tm_hour) &&\r
399                 (g_alarmCtrB.info.minute == curTime.tm_min) &&\r
400                 (g_alarmCtrB.info.second == curTime.tm_sec))\r
401             {\r
402                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Alarm B triggered");\r
403                 g_alarmCtrB.state = ALARM_STATUS_CREATED;\r
404                 g_alarmCtrB.callback();\r
405             }\r
406         }\r
407 \r
408         // 业务逻辑回调\r
409         do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_TIMECALL_BACK, nullptr, 0);\r
410     }\r
411 \r
412     // 每秒回调\r
413     void custom_timer_callback()\r
414     {\r
415         struct tm curTime;\r
416         int32_t ret = AlarmGetCurrentTimeInfo(&curTime);\r
417         if (ret != ERRCODE_SUCC)\r
418         {\r
419             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get current time info, error code: %d", ret);\r
420             return;\r
421         }\r
422 \r
423         // 绑定判断\r
424         if (HandleIsBind())\r
425         {\r
426             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HandleAlarmOnTime: not binded");\r
427             return;\r
428         }\r
429 \r
430         if (curTime.tm_min % 60 == 0 && curTime.tm_sec == 0)\r
431         {\r
432             do_custom_fileoperate_service_check_msg(CUSTOM_FILEOPERATE_MSG_TYPE_BATTERY_DATA_SAVE, nullptr, 0); // 十分钟存一次电池信息\r
433         }\r
434 \r
435         HandleAlarmOnTime(&curTime);\r
436         HandleSleepReminder(&curTime);\r
437         HandleMusicUpdate();\r
438 \r
439         // 以下弹窗被控制\r
440         if (HandleCanShowDialog())\r
441         {\r
442             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HandleAlarmOnTime: not show dialog");\r
443             return;\r
444         }\r
445 \r
446         HandleDrinkReminder(&curTime);\r
447         HandleHeartRateDetection(&curTime);\r
448     }\r
449 \r
450     // 判断是否绑定\r
451     bool HandleIsBind(void)\r
452     {\r
453         // 未绑定状态下,以下操作不进行\r
454         if (OHOS::ConfigModel::GetInstance()->get_configData_bool(\r
455                 OHOS::ConfigModel::CONFIGMODEL_ITEM_FIRSTTIMESTART))\r
456         {\r
457             return true;\r
458         }\r
459         return false;\r
460     }\r
461 \r
462     // 判断是否可以弹窗\r
463     bool HandleCanShowDialog(void)\r
464     {\r
465         bool state = false;\r
466 \r
467         if (uapi_dev_runtime_get_saveele_status())\r
468         {\r
469             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "saveele!");\r
470             state = true;\r
471         }\r
472 \r
473         if (uapi_dev_runtime_get_train_status())\r
474         {\r
475             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "training!");\r
476             state = true;\r
477         }\r
478 \r
479         return state;\r
480     }\r
481 \r
482     // 整点回调\r
483     void HandleAlarmOnTime(const struct tm *curTime)\r
484     {\r
485         if (curTime->tm_min == 0 && curTime->tm_sec == 0)\r
486         {\r
487             AlarmClockEventData unuse;\r
488             time_t timetemp = mktime((struct tm *)curTime);\r
489             unuse.value = timetemp - 60 * 60;\r
490             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "on_time_CallBackProc invoked");\r
491             GraphicService::GetInstance()->PostGraphicEvent(\r
492                 std::bind(AlarmTimerEventPublish, TOPIC_EVENT_ON_TIME, unuse));\r
493         }\r
494     }\r
495 \r
496     // 睡眠提醒\r
497     void HandleSleepReminder(const struct tm *curTime)\r
498     {\r
499         // 睡眠总开关\r
500         if (OHOS::ConfigModel::GetInstance()->get_configData_int(OHOS::ConfigModel::CONFIGMODEL_ITEM_SLEEP))\r
501         {\r
502             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CONFIGMODEL_ITEM_SLEEP is OK");\r
503             // 睡眠提醒[前提开启睡眠提醒]\r
504             if (OHOS::ConfigModel::GetInstance()->get_configData_int(OHOS::ConfigModel::CONFIGMODEL_ITEM_SLEEP_REMIND))\r
505             {\r
506                 // 提醒一次\r
507                 if ((curTime->tm_hour == sleep_notify_time_hour) && (curTime->tm_min == sleep_notify_time_min) && (curTime->tm_sec == 0))\r
508                 {\r
509                     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "It's bedtime in 20 minutes");\r
510                     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "20分钟后要睡觉啦!");\r
511                     // 设置状态为睡眠提醒\r
512                     OHOS::SleepModel::GetInstance().set_sleep_state(OHOS::SLEEPSTATE::SLEEPNOTIFY);\r
513                     AlarmEventPublish(TOPIC_EVENT_SLEEPNOTE, NULL, 0);\r
514                 }\r
515             }\r
516             if ((curTime->tm_hour == wake_time_hour && curTime->tm_min == wake_time_min && curTime->tm_sec == 0) ||\r
517                 (curTime->tm_hour == sleep_time_hour && curTime->tm_min == sleep_time_min && curTime->tm_sec == 0) && curTime->tm_min)\r
518             {\r
519                 #ifdef CUSTOM_UTILS\r
520                 uapi_cywee_time_sync();\r
521                 #endif\r
522             }\r
523             else if (!time_sync_flag && curTime->tm_min)\r
524             {\r
525                 time_sync_flag = 1;\r
526                 #ifdef CUSTOM_UTILS\r
527                 uapi_cywee_time_sync();\r
528                 #endif\r
529             }\r
530             // 退出睡眠检测模式并进入小睡检测模式\r
531             if (!is_time_range(*curTime, sleep_time_hour, sleep_time_min, wake_time_hour, wake_time_min) && (uapi_dev_runtime_get_nap_monitoring_status() == 0))\r
532             {\r
533                 if (curTime->tm_hour == wake_time_hour && curTime->tm_min == wake_time_min && curTime->tm_sec == 0)\r
534                 {\r
535                     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "闹铃!");\r
536                     // 退出睡眠模式\r
537                     OHOS::SleepModeModel::GetInstance().SetSleepModeDisabled();\r
538                     OHOS::SleepModel::GetInstance().set_sleep_state(OHOS::SLEEPSTATE::WAKE);\r
539                 }\r
540 \r
541                 // 判断是否还在睡眠\r
542                 if (uapi_dev_runtime_get_sleep_status() == 0)\r
543                 {\r
544                     // 设置状态为小睡\r
545                     uapi_dev_runtime_set_nap_status(0);                                     // 清零小睡状态\r
546                     uapi_dev_runtime_set_absolute_static_status(0);                         // 清零绝对静止状态\r
547                 \r
548 #ifdef SUPPORT_CYWEE_SERVICE                      \r
549                     do_cywee_service_check_msg(CYWEE_SERVICE_CMD_NAP_SEDENTARY_MODE, NULL); // 算法底层切换小睡监测模式\r
550 #endif\r
551                     time_sync_flag = 0;\r
552                 }\r
553             }\r
554             // 进入睡眠检测模式并退出小睡检测模式\r
555             else if (is_time_range(*curTime, sleep_time_hour, sleep_time_min, wake_time_hour, wake_time_min) && (uapi_dev_runtime_get_sleep_monitoring_status() == 0))\r
556             {\r
557                 int cmd = 1;\r
558                 uapi_dev_runtime_set_sleep_status(0);           // 清零睡眠状态\r
559                 uapi_dev_runtime_set_absolute_static_status(0); // 清零绝对静止状态\r
560                 // OHOS::clean_sleep_data();                       // 清零睡眠文件存储数据\r
561                 // if(uapi_dev_runtime_get_nap_monitoring_status() == 1)\r
562                 // uapi_clean_sleep_flag();                        // 清除睡眠标志文件\r
563                 // OHOS::create_sleep_folder();                     // 创建睡眠文件夹\r
564 #ifdef SUPPORT_CYWEE_SERVICE    \r
565                 do_cywee_service_check_msg(CYWEE_SERVICE_CMD_GET_SLEEP_DATA, &cmd); // 强制获取小睡数据,结束小睡\r
566 #endif\r
567 \r
568                 // 睡眠弹窗\r
569                 WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "要睡觉啦!");\r
570                 // 设置状态为睡眠\r
571                 OHOS::SleepModel::GetInstance().clean_sleep_data(); // 清除历史数据\r
572                 OHOS::SleepModel::GetInstance().set_sleep_state(OHOS::SLEEPSTATE::SLEPP);\r
573 \r
574                 if (curTime->tm_hour == sleep_time_hour && curTime->tm_min == sleep_time_min && curTime->tm_sec == 0)\r
575                 {\r
576                     // 进入睡眠模式\r
577                     OHOS::SleepModeModel::GetInstance().SetSleepModeEnabled();\r
578                     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "要睡觉啦!!!! 开始");\r
579                     AlarmEventPublish(TOPIC_EVENT_SLEEPNOTE, NULL, 0);\r
580                     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "要睡觉啦!!!! 结束");\r
581                 }\r
582 \r
583 #ifdef SUPPORT_CYWEE_SERVICE\r
584                 do_cywee_service_check_msg(CYWEE_SERVICE_CMD_SLEEPING_MODE, NULL); // 算法底层切换睡眠监测模式\r
585 #endif\r
586                 time_sync_flag = 0;\r
587             }\r
588         }\r
589     }\r
590 \r
591     // 喝水提醒\r
592     void HandleDrinkReminder(const struct tm *curTime)\r
593     {\r
594         if (drinkreminder_switch == 1)\r
595         { // 定时提醒\r
596             if (curTime->tm_hour == drinkreminder_start_hour &&\r
597                 curTime->tm_min == drinkreminder_start_min &&\r
598                 curTime->tm_sec == 0)\r
599             {\r
600                 WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "该喝水了!!该喝水了!!");\r
601                 AlarmEventPublish(TOPIC_EVENT_DRINKREMINDER, NULL, 0);\r
602             }\r
603         }\r
604         else if (drinkreminder_switch == 2)\r
605         { // 间隔提醒\r
606             // 判断当前时间是否在提醒时间段内\r
607             if (is_time_range(*curTime, drinkreminder_start_hour, drinkreminder_start_min, drinkreminder_end_hour, drinkreminder_end_min))\r
608             {\r
609                 double interval_time = (drinkreminder_freq == 0) ? 0.5 : drinkreminder_freq;\r
610                 int interval_time_seconds = (int)(interval_time * 60) * 60;\r
611                 int current_seconds = (curTime->tm_hour * 60 + curTime->tm_min) * 60;\r
612                 int hour_24_seconds = 24 * 60 * 60;\r
613                 // 进行间隔判断和提醒\r
614                 if (uapi_dev_runtime_get_drinkremind_status() == 0)\r
615                 {\r
616                     uapi_dev_runtime_set_drinkremind_status(1);\r
617                     drinkremind_expectedTime = current_seconds + interval_time_seconds;\r
618                     drinkremind_expectedTime %= hour_24_seconds; // 同时处理24小时循环\r
619                 }\r
620                 else if (current_seconds == drinkremind_expectedTime && curTime->tm_sec == 0)\r
621                 {\r
622                     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "该喝水了!!该喝水了!!");\r
623                     drinkremind_expectedTime += interval_time_seconds;\r
624                     drinkremind_expectedTime %= hour_24_seconds; // 处理24小时循环\r
625                     AlarmEventPublish(TOPIC_EVENT_DRINKREMINDER, NULL, 0);\r
626                 }\r
627             }\r
628             else if (!is_time_range(*curTime, drinkreminder_start_hour, drinkreminder_start_min, drinkreminder_end_hour, drinkreminder_end_min) && uapi_dev_runtime_get_drinkremind_status() == 1)\r
629             {\r
630                 uapi_dev_runtime_set_drinkremind_status(0);\r
631             }\r
632         }\r
633     }\r
634 \r
635     // 心率周期检测\r
636     void HandleHeartRateDetection(const struct tm *curTime)\r
637     {\r
638         int heartRateDetectionInterval = 0;\r
639 \r
640         if (uapi_dev_runtime_get_sleep_monitoring_status())\r
641             heartRateDetectionInterval = 20; // 晚上 20分钟检测一次\r
642         else\r
643             heartRateDetectionInterval = OHOS::ConfigModel::GetInstance()->get_configData_int(OHOS::ConfigModel::CONFIGMODEL_ITEM_HEARTRATE_DETECTED);\r
644 \r
645         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Heart rate detection cycle detection is enabled %d", heartRateDetectionInterval);\r
646         if (heartRateDetectionInterval)\r
647         {\r
648             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Heart rate detection cycle detection is enabled %d", curTime->tm_min % heartRateDetectionInterval);\r
649             if (curTime->tm_min % heartRateDetectionInterval == 0 && curTime->tm_sec == 0)\r
650             {\r
651                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "开启心率周期检测");\r
652                 // 开启心率检测\r
653                 OHOS::HeartModel::GetInstance()->Heart_Control(OHOS::HeartState::Start, OHOS::HeartCheck::PASSIVITY);\r
654             }\r
655         }\r
656     }\r
657 \r
658     // 音乐更新\r
659     void HandleMusicUpdate()\r
660     {\r
661         int16_t curviewid = OHOS::NativeAbility::GetInstance().GetCurSliceId();\r
662         if (curviewid != VIEW_MAIN && OHOS::PlayersView::GetInstance())\r
663         { // 当前不在主界面且音乐界面不为空\r
664             OHOS::UICheckBox::UICheckBoxState state = OHOS::PlayersView::GetInstance()->GetPlayerButtonState();\r
665             if (state == OHOS::UICheckBox::UICheckBoxState::SELECTED)\r
666             {\r
667                 SendMsgToUIService(UI_UPDATE_PLAYERPROCESS, 0, nullptr, 0); // 音乐进度条更新\r
668             }\r
669         }\r
670         else if (OHOS::RecordingPlayerView::GetInstance())\r
671         {\r
672             OHOS::UICheckBox::UICheckBoxState state = OHOS::RecordingPlayerView::GetInstance()->GetPlayerButtonState();\r
673             if (state == OHOS::UICheckBox::UICheckBoxState::SELECTED)\r
674             {\r
675                 SendMsgToUIService(UI_UPDATE_RECORDPROCESS, 0, nullptr, 0); // 录音进度条更新\r
676             }\r
677         }\r
678     }\r
679 \r
680     static int32_t AlarmCreate(AlarmCtrl *alarmCtrl, AlarmCallBack callback)\r
681     {\r
682         if (alarmCtrl == nullptr)\r
683         {\r
684             return ERRCODE_FAIL;\r
685         }\r
686         if (alarmCtrl->state == ALARM_STATUS_UNUSED)\r
687         {\r
688             alarmCtrl->state = ALARM_STATUS_CREATED;\r
689             alarmCtrl->callback = callback;\r
690         }\r
691         return ERRCODE_SUCC;\r
692     }\r
693 \r
694     int32_t AlarmTimerInit(void)\r
695     {\r
696         int32_t timerStatus;\r
697         int32_t ret;\r
698 \r
699         set_sleep_and_wake_time();\r
700         set_sedentary_data();\r
701         set_drinkreminder_data();\r
702         get_sleep_time_notify();\r
703 \r
704         g_alarmCtrA.state = ALARM_STATUS_UNUSED;\r
705         g_alarmCtrB.state = ALARM_STATUS_UNUSED;\r
706         g_AlarmHandle = osTimerNew(AlarmScan, osTimerPeriodic, nullptr, nullptr);\r
707         if (g_AlarmHandle == nullptr)\r
708         {\r
709             return ERRCODE_FAIL;\r
710         }\r
711         timerStatus = osTimerStart(g_AlarmHandle, ALARM_INTERVAL_MS);\r
712         if (timerStatus != osOK)\r
713         {\r
714             return ERRCODE_FAIL;\r
715         }\r
716         ret = AlarmCreate(&g_alarmCtrA, AlarmCallBackProcA);\r
717         if (ret != ERRCODE_SUCC)\r
718         {\r
719             return ERRCODE_FAIL;\r
720         }\r
721         ret = AlarmCreate(&g_alarmCtrB, AlarmCallBackProcB);\r
722         if (ret != ERRCODE_SUCC)\r
723         {\r
724             return ERRCODE_FAIL;\r
725         }\r
726 \r
727         return ERRCODE_SUCC;\r
728     }\r
729 \r
730     int32_t SetAlarm(AlarmType type, uint8_t week, uint8_t hour, uint8_t minute)\r
731     {\r
732         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SetAlarm %d %d %d %d", type, week, hour, minute);\r
733         if (type == ALARM_A)\r
734         {\r
735             g_alarmCtrA.state = ALARM_STATUS_RUNNING;\r
736             g_alarmCtrA.info.hour = hour;\r
737             g_alarmCtrA.info.minute = minute;\r
738         }\r
739         else if (type == ALARM_B)\r
740         {\r
741             g_alarmCtrB.state = ALARM_STATUS_RUNNING;\r
742             g_alarmCtrB.info.week = week;\r
743             g_alarmCtrB.info.hour = hour;\r
744             g_alarmCtrB.info.minute = minute;\r
745             g_alarmCtrB.info.second = 5;\r
746         }\r
747         else\r
748         {\r
749             return ERRCODE_FAIL;\r
750         }\r
751         return ERRCODE_SUCC;\r
752     }\r
753 \r
754     int32_t SetZeroAlarm(void)\r
755     {\r
756         struct tm curTime;\r
757         int32_t ret = AlarmGetCurrentTimeInfo(&curTime);\r
758         if (ret != ERRCODE_SUCC)\r
759         {\r
760             return ERRCODE_FAIL;\r
761         }\r
762         int32_t weekday = (++curTime.tm_wday) % 7;\r
763         return SetAlarm(ALARM_B, weekday, 0, 0);\r
764     }\r
765 \r
766     int32_t AlarmGetCurrentTimeInfo(struct tm *timeInfo)\r
767     {\r
768         if (timeInfo == nullptr)\r
769         {\r
770             return ERRCODE_FAIL;\r
771         }\r
772         time_t sec = time(nullptr);\r
773         localtime_r(&sec, timeInfo);\r
774         return ERRCODE_SUCC;\r
775     }\r
776 \r
777 #ifdef __cplusplus\r
778 }\r
779 #endif\r