To handle RTC reset 13/213313/1
authorInkyun Kil <inkyun.kil@samsung.com>
Wed, 4 Sep 2019 06:39:29 +0000 (15:39 +0900)
committerInkyun Kil <inkyun.kil@samsung.com>
Wed, 4 Sep 2019 06:39:29 +0000 (15:39 +0900)
- When RTC is reset, some alarms(relative) are wrong

Change-Id: I41f4038834e918a13a5e649a71009b26a9aa6203
Signed-off-by: Inkyun Kil <inkyun.kil@samsung.com>
alarm-manager.c

index b43e6c8addfbdb6992d68fe1a4dc5fe79deaa490..3ea3db512020b7d9bde822486de4e52cf2678086 100644 (file)
@@ -141,7 +141,7 @@ static bool __alarm_remove_from_list(uid_t uid, alarm_id_t alarm_id,
                                     int *error_code);
 static bool __alarm_set_start_and_end_time(alarm_info_t *alarm_info,
                                           __alarm_info_t *__alarm_info);
-static bool __alarm_update_due_time_of_all_items_in_list(double diff_time);
+static bool __alarm_update_due_time_of_all_items_in_list(time_t new_time, double diff_time);
 static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id, uid_t uid,
                        int pid, periodic_method_e method, long requested_interval, int is_ref,
                        char *app_service_name, char *app_service_name_mod,
@@ -549,6 +549,7 @@ static __alarm_info_t *__alarm_update_in_list(int uid, alarm_id_t alarm_id,
        GSList *iter = NULL;
        __alarm_info_t *entry = NULL;
        alarm_info_t *_alarm_info = NULL;
+       time_t current_time;
 
        for (iter = alarm_context.alarms; iter != NULL;
             iter = g_slist_next(iter)) {
@@ -570,6 +571,11 @@ static __alarm_info_t *__alarm_update_in_list(int uid, alarm_id_t alarm_id,
                        if (update_flag == ALARM_UPDATE_FLAG_TIME) {
                                __alarm_set_start_and_end_time(alarm_info, entry);
                                memcpy(_alarm_info, alarm_info, sizeof(alarm_info_t));
+
+                               if (_alarm_info->mode.repeat == ALARM_REPEAT_MODE_ONCE) {
+                                       time(&current_time);
+                                       _alarm_info->reserved_info = current_time;
+                               }
                        } else if (update_flag == ALARM_UPDATE_FLAG_PERIOD) {
                                _alarm_info->alarm_type |= ALARM_TYPE_INEXACT;
                                _alarm_info->alarm_type |= ALARM_TYPE_PERIOD;
@@ -779,7 +785,7 @@ gboolean __update_relative_alarms(gpointer user_data)
        return false;
 }
 
-static bool __alarm_update_due_time_of_all_items_in_list(double diff_time)
+static bool __alarm_update_due_time_of_all_items_in_list(time_t new_time, double diff_time)
 {
        time_t current_time;
        time_t min_time = -1;
@@ -788,6 +794,7 @@ static bool __alarm_update_due_time_of_all_items_in_list(double diff_time)
        __alarm_info_t *entry = NULL;
        struct tm *p_time = NULL ;
        struct tm due_time_result ;
+       bool is_rtc_reset = false;
        is_time_changed = true;
 
        if (periodic_alarm_standard_time != 0)
@@ -798,7 +805,33 @@ static bool __alarm_update_due_time_of_all_items_in_list(double diff_time)
                entry = iter->data;
                alarm_info_t *alarm_info = &(entry->alarm_info);
                if (alarm_info->alarm_type & ALARM_TYPE_RELATIVE) {
-                       entry->due_time += diff_time;
+                       /* case of RTC reset */
+                       if (entry->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE) {
+                               if ((entry->due_time + diff_time - new_time) >
+                                               (entry->due_time - entry->alarm_info.reserved_info)) {
+                                       LOGE("[ RTC reset]: new time %s %ld, diff %f, id %d duetime %s %ld %ld",
+                                                       ctime(&new_time), new_time, diff_time, entry->alarm_id,
+                                                       ctime(&entry->due_time), entry->due_time,
+                                                       entry->alarm_info.reserved_info);
+                                       continue;
+                               }
+
+                               entry->due_time += diff_time;
+                               entry->alarm_info.reserved_info = new_time;
+
+                       } else {
+                               entry->due_time += diff_time;
+                               is_rtc_reset = false;
+                               if ((entry->due_time - new_time) > alarm_info->mode.u_interval.interval) {
+                                       is_rtc_reset = true;
+                                       entry->due_time = new_time +
+                                               ((entry->due_time - new_time) % alarm_info->mode.u_interval.interval);
+                                       LOGE("[ RTC reset]: new time %s %ld, diff %f, id %d duetime %s %ld %ld",
+                                                       ctime(&new_time), new_time, diff_time, entry->alarm_id,
+                                                       ctime(&entry->due_time), entry->due_time,
+                                                       alarm_info->mode.u_interval.interval);
+                               }
+                       }
 
                        alarm_date_t *start = &alarm_info->start;       /**< start time of the alarm */
                        alarm_date_t *end = &alarm_info->end;   /**< end time of the alarm */
@@ -815,7 +848,7 @@ static bool __alarm_update_due_time_of_all_items_in_list(double diff_time)
                        if (entry->start != 0)
                                entry->start = entry->due_time;
 
-                       if (entry->end != 0) {
+                       if (entry->end != 0 && is_rtc_reset == false) {
                                entry->end += diff_time;
                                p_time = localtime_r(&entry->end, &due_time_result);
                                if (p_time != NULL) {
@@ -970,6 +1003,9 @@ static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id
 
        time(&current_time);
 
+       if (__alarm_info->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE)
+               __alarm_info->alarm_info.reserved_info = current_time;
+
        if (alarm_context.c_due_time < current_time) {
                ALARM_MGR_EXCEPTION_PRINT("Caution!! alarm_context.c_due_time "
                "(%ld) is less than current time(%ld)", alarm_context.c_due_time, current_time);
@@ -1080,6 +1116,9 @@ static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id, uid_t
 
        time(&current_time);
 
+       if (__alarm_info->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE)
+               __alarm_info->alarm_info.reserved_info = current_time;
+
        SECURE_LOGD("[alarm-server]:pid=%d, app_unique_name=%s, "
                        "app_service_name=%s,dst_service_name=%s, c_due_time=%ld", \
                        pid, __alarm_info->app_unique_name, \
@@ -1242,6 +1281,9 @@ static bool __alarm_create_noti(alarm_info_t *alarm_info, alarm_id_t *alarm_id,
 
        time(&current_time);
 
+       if (__alarm_info->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE)
+               __alarm_info->alarm_info.reserved_info = current_time;
+
        SECURE_LOGD("[alarm-server]:pid=%d, app_unique_name=%s, "
                        "app_service_name=%s,dst_service_name=%s, c_due_time=%ld", \
                        pid, __alarm_info->app_unique_name, \
@@ -1315,6 +1357,9 @@ static bool __alarm_update(uid_t uid, int pid, alarm_id_t alarm_id,
                return false;
        }
 
+       if (__alarm_info->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE)
+               __alarm_info->alarm_info.reserved_info = current_time;
+
        due_time = _alarm_next_duetime(__alarm_info);
 
        result = _remove_from_scheduled_alarm_list(uid, alarm_id);
@@ -2197,7 +2242,7 @@ static void __on_system_time_external_changed(keynode_t *node, void *data)
        eventsystem_send_system_event(SYS_EVENT_TIME_CHANGED, b);
        bundle_free(b);
 
-       __alarm_update_due_time_of_all_items_in_list(diff_time);
+       __alarm_update_due_time_of_all_items_in_list(cur_time, diff_time);
 
        ALARM_MGR_LOG_PRINT("2.alarm_context.c_due_time is %ld\n",
                            alarm_context.c_due_time);
@@ -2695,7 +2740,7 @@ void __reschedule_alarms_with_newtime(int cur_time, int new_time, double diff_ti
        eventsystem_send_system_event(SYS_EVENT_TIME_CHANGED, b);
        bundle_free(b);
 
-       __alarm_update_due_time_of_all_items_in_list(diff_time); /* Rescheduling alarms with ALARM_TYPE_RELATIVE */
+       __alarm_update_due_time_of_all_items_in_list(new_time, diff_time); /* Rescheduling alarms with ALARM_TYPE_RELATIVE */
        ALARM_MGR_LOG_PRINT("Next duetime is %ld", alarm_context.c_due_time);
 
        _clear_scheduled_alarm_list();
@@ -3004,6 +3049,7 @@ gboolean alarm_manager_alarm_set_timezone(AlarmManager *pObject, GDBusMethodInvo
        char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,};
        char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,};
 #endif
+       time_t cur_time;
 
        ALARM_MGR_LOG_PRINT("[TIMESTAMP]Set the timezone to %s.", tzpath_str);
 
@@ -3034,7 +3080,8 @@ gboolean alarm_manager_alarm_set_timezone(AlarmManager *pObject, GDBusMethodInvo
 
        /* Rescheduling alarms */
        _alarm_disable_timer(alarm_context);
-       __alarm_update_due_time_of_all_items_in_list(0);
+       time(&cur_time);
+       __alarm_update_due_time_of_all_items_in_list(cur_time, 0);
        ALARM_MGR_LOG_PRINT("next expiring due_time is %ld", alarm_context.c_due_time);
 
        _clear_scheduled_alarm_list();