Merge branch 'master' into tizen_2.1
[framework/appfw/alarm-manager.git] / alarm-manager.c
index 14bb771..951b96b 100755 (executable)
@@ -134,6 +134,7 @@ static void __alarm_handler(int sigNum, siginfo_t *pSigInfo, void *pUContext);
 static void __clean_registry();
 static bool __alarm_manager_reset();
 static void __on_system_time_changed(keynode_t *node, void *data);
+static void __on_system_time_external_changed(keynode_t *node, void *data);
 static void __initialize_timer();
 static void __initialize_alarm_list();
 static void __initialize_scheduled_alarm_lsit();
@@ -273,7 +274,7 @@ int _set_rtc_time(time_t _time)
        rtc_tm.tm_year = time_r.tm_year;
        rtc_tm.tm_hour = time_r.tm_hour;
        rtc_tm.tm_min = time_r.tm_min;
-       rtc_tm.tm_sec = 0;
+       rtc_tm.tm_sec = time_r.tm_sec;
 
 
        retval0 = ioctl(fd0, RTC_SET_TIME, &rtc_tm);
@@ -692,7 +693,15 @@ static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id
        snprintf(proc_file, 512, "/proc/%d/cmdline", pid);
 
        fd = open(proc_file, O_RDONLY);
-       if (fd > 0) {
+       if (fd < 0) {           /* failure */
+               ALARM_MGR_EXCEPTION_PRINT("Caution!! app_pid(%d) seems to be "
+                                         "killed, so we failed to get proc file(%s) and do not create "
+                                         "alarm_info\n", pid, proc_file);
+               *error_code = -1;       /*-1 means that system failed
+                                                       internally.*/
+               free(__alarm_info);
+               return false;
+       } else {
                ret = read(fd, process_name, 512);
                close(fd);
                if (ret <=0)
@@ -718,14 +727,6 @@ static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id
                }
                __alarm_info->quark_app_unique_name =
                    g_quark_from_string(app_name);
-       } else {                /* failure */
-               ALARM_MGR_EXCEPTION_PRINT("Caution!! app_pid(%d) seems to be "
-                                         "killed, so we failed to get proc file(%s) and do not create "
-                                         "alarm_info\n", pid, proc_file);
-               *error_code = -1;       /*-1 means that system failed
-                                                       internally.*/
-               free(__alarm_info);
-               return false;
        }
 
        __alarm_info->quark_bundle=g_quark_from_string(bundle_data);
@@ -838,7 +839,17 @@ static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id,
        int ret;
        int i = 0;
        fd = open(proc_file, O_RDONLY);
-       if (fd > 0) {
+       if (fd < 0) {   /* failure */
+               __alarm_info->quark_app_unique_name =
+                   g_quark_from_string("unknown");
+               ALARM_MGR_EXCEPTION_PRINT("Caution!! app_pid(%d) seems to be "
+                                         "killed, so we failed to get proc file(%s) and do not create "
+                                         "alarm_info\n", pid, proc_file);
+               *error_code = -1;       /*-1 means that system failed
+                                                       internally.*/
+               free(__alarm_info);
+               return false;
+       } else {
                ret = read(fd, process_name, 512);
                close(fd);
                while (process_name[i] != '\0') {
@@ -859,17 +870,6 @@ static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id,
                }
                __alarm_info->quark_app_unique_name =
                    g_quark_from_string(app_name);
-       } else {                /* failure */
-
-               __alarm_info->quark_app_unique_name =
-                   g_quark_from_string("unknown");
-               ALARM_MGR_EXCEPTION_PRINT("Caution!! app_pid(%d) seems to be "
-                                         "killed, so we failed to get proc file(%s) and do not create "
-                                         "alarm_info\n", pid, proc_file);
-               *error_code = -1;       /*-1 means that system failed
-                                                       internally.*/
-               free(__alarm_info);
-               return false;
        }
 
        __alarm_info->quark_app_service_name =
@@ -1146,7 +1146,6 @@ static bool __alarm_power_on(int app_id, bool on_off, int *error_code)
 #ifdef __ALARM_BOOT
        time_t min_time = 0;
        time_t current_time = 0;
-       struct tm *temp_info = NULL;
        struct rtc_time rtc_tm = { 0, };
        struct tm min_time_r = { 0, };
        int fd = 0;
@@ -1173,7 +1172,7 @@ static bool __alarm_power_on(int app_id, bool on_off, int *error_code)
                        if (min_time <= current_time)
                                min_time = current_time + 5;
 
-                       temp_info = gmtime_r(&min_time, &min_time_r);
+                       gmtime_r(&min_time, &min_time_r);
 
                        ALARM_MGR_LOG_PRINT("__alarm_power_on : %d %d %d %d "
                                                "%d\n", \
@@ -1348,6 +1347,7 @@ static void __alarm_expired()
        char alarm_id_val[32]={0,};
        int b_len = 0;
        bundle *b = NULL;
+       char *appid = NULL;
 
        ALARM_MGR_LOG_PRINT("[alarm-server]: Enter \n");
 
@@ -1362,7 +1362,12 @@ static void __alarm_expired()
                current_time, interval);
 
        if (alarm_context.c_due_time > current_time) {
-               ALARM_MGR_LOG_PRINT("[alarm-server]: False Alarm\n");
+               ALARM_MGR_LOG_PRINT("[alarm-server]: False Alarm (time changed to past)\n");
+               goto done;
+       }
+       // 3 seconds is maximum permitted delay from timer expire to this function
+       if (alarm_context.c_due_time + 3 < current_time) {
+               ALARM_MGR_LOG_PRINT("[alarm-server]: False Alarm (time changed to future)\n");
                goto done;
        }
 
@@ -1399,13 +1404,21 @@ static void __alarm_expired()
                                        }
                                        else
                                        {
-                                               if ( appsvc_run_service(b, 0, NULL, NULL) < 0)
+                                               appid = appsvc_get_appid(b);
+                                               if( (__alarm_info->alarm_info.alarm_type & ALARM_TYPE_NOLAUNCH) && !aul_app_is_running(appid))
                                                {
-                                                       ALARM_MGR_EXCEPTION_PRINT("Unable to run app svc\n");
+                                                       ALARM_MGR_EXCEPTION_PRINT("This alarm is ignored\n");
                                                }
                                                else
                                                {
-                                                       ALARM_MGR_LOG_PRINT("Successfuly ran app svc\n");
+                                                       if ( appsvc_run_service(b, 0, NULL, NULL) < 0)
+                                                       {
+                                                               ALARM_MGR_EXCEPTION_PRINT("Unable to run app svc\n");
+                                                       }
+                                                       else
+                                                       {
+                                                               ALARM_MGR_LOG_PRINT("Successfuly ran app svc\n");
+                                                       }
                                                }
                                        }
                                        bundle_free(b);
@@ -1473,12 +1486,17 @@ static void __alarm_expired()
                                char appid[MAX_SERVICE_NAME_LEN] = { 0, };
                                char alarm_id_str[32] = { 0, };
 
+                               if (__alarm_info->alarm_info.alarm_type & ALARM_TYPE_WITHCB) {
+                                       __alarm_remove_from_list(__alarm_info->pid, alarm_id, NULL);
+                                       goto done;
+                               }
+
                                expire_info = malloc(sizeof(__expired_alarm_t));
                                if (G_UNLIKELY(NULL == expire_info)){
                                        ALARM_MGR_ASSERT_PRINT("[alarm-server]:Malloc failed!Can't notify alarm expiry info\n");
                                        goto done;
                                }
-                               bzero(expire_info, sizeof (expire_info));
+                               memset(expire_info, '\0', MAX_SERVICE_NAME_LEN);
                                strncpy(expire_info->service_name,
                                        destination_app_service_name,
                                        MAX_SERVICE_NAME_LEN-1);
@@ -1654,6 +1672,87 @@ this value to 0(zero)
        return;
 }
 
+static void __on_system_time_external_changed(keynode_t *node, void *data)
+{
+       double diff_time;
+       time_t cur_time = 0;
+
+       _alarm_disable_timer(alarm_context);
+
+       if (node) {
+               diff_time = vconf_keynode_get_dbl(node);
+       } else {
+               vconf_get_dbl(VCONFKEY_SYSTEM_TIMECHANGE_EXTERNAL, &diff_time);
+       }
+
+       tzset();
+
+       ALARM_MGR_ASSERT_PRINT("diff_time is %f\n", diff_time);
+
+       ALARM_MGR_LOG_PRINT("[alarm-server] System time has been changed externally\n");
+       ALARM_MGR_LOG_PRINT("1.alarm_context.c_due_time is %d\n",
+                           alarm_context.c_due_time);
+
+       // set rtc time only because the linux time is set externally
+       time(&cur_time);
+       _set_rtc_time(cur_time);
+
+       vconf_set_dbl(VCONFKEY_SYSTEM_TIMEDIFF, diff_time);
+       vconf_set_int(VCONFKEY_SYSTEM_TIME_CHANGED,(int)diff_time);
+
+       __alarm_update_due_time_of_all_items_in_list(diff_time);
+
+       ALARM_MGR_LOG_PRINT("2.alarm_context.c_due_time is %d\n",
+                           alarm_context.c_due_time);
+       _clear_scheduled_alarm_list();
+       _alarm_schedule();
+       __rtc_set();
+#ifdef __ALARM_BOOT
+       /*alarm boot */
+       if (enable_power_on_alarm) {
+/* orginally first arg's value was 21(app_id, WAKEUP_ALARM_
+APP_ID) in a platform with app-server. because _alarm_power_
+on(..) fuction don't use first parameter internally, we set
+this value to 0(zero)
+*/
+               __alarm_power_on(0, enable_power_on_alarm, NULL);
+       }
+#endif
+       return;
+}
+
+static void __on_time_zone_changed(keynode_t *node, void *data)
+{
+       double diff_time = 0;
+
+       _alarm_disable_timer(alarm_context);
+
+       tzset();
+
+       ALARM_MGR_LOG_PRINT("[alarm-server] time zone has been changed\n");
+       ALARM_MGR_LOG_PRINT("1.alarm_context.c_due_time is %d\n", alarm_context.c_due_time);
+
+       __alarm_update_due_time_of_all_items_in_list(diff_time);
+
+       ALARM_MGR_LOG_PRINT("2.alarm_context.c_due_time is %d\n", alarm_context.c_due_time);
+       _clear_scheduled_alarm_list();
+       _alarm_schedule();
+       __rtc_set();
+#ifdef __ALARM_BOOT
+       /*alarm boot */
+       if (enable_power_on_alarm) {
+/* orginally first arg's value was 21(app_id, WAKEUP_ALARM_
+APP_ID) in a platform with app-server. because _alarm_power_
+on(..) fuction don't use first parameter internally, we set
+this value to 0(zero)
+*/
+               __alarm_power_on(0, enable_power_on_alarm, NULL);
+       }
+#endif
+       return;
+}
+
+
 gboolean alarm_manager_alarm_set_rtc_time(void *pObject, int pid,
                                int year, int mon, int day,
                                int hour, int min, int sec, char *e_cookie,
@@ -2037,7 +2136,17 @@ gboolean alarm_manager_alarm_get_number_of_ids(void *pObject, int pid,
        int ret;
        int i = 0;
        fd = open(proc_file, O_RDONLY);
-       if (fd > 0) {
+       if (fd < 0) {           /* failure */
+               quark_app_unique_name = g_quark_from_string("unknown");
+               memcpy(app_name, "unknown", strlen("unknown") + 1);
+
+               ALARM_MGR_EXCEPTION_PRINT("Caution!! app_pid(%d) seems to be "
+                                         "killed, so we failed to get proc file(%s) \n",
+                                         pid, proc_file);
+               *return_code = -1;      /* -1 means that system
+                                          failed internally. */
+               return true;
+       } else {
                ret = read(fd, process_name, 512);
                close(fd);
                while (process_name[i] != '\0') {
@@ -2057,17 +2166,6 @@ gboolean alarm_manager_alarm_get_number_of_ids(void *pObject, int pid,
                        word = strtok_r(NULL, "/", &proc_name_ptr);
                }
                quark_app_unique_name = g_quark_from_string(app_name);
-       } else {                /* failure */
-
-               quark_app_unique_name = g_quark_from_string("unknown");
-               memcpy(app_name, "unknown", strlen("unknown") + 1);
-
-               ALARM_MGR_EXCEPTION_PRINT("Caution!! app_pid(%d) seems to be "
-                                         "killed, so we failed to get proc file(%s) \n",
-                                         pid, proc_file);
-               *return_code = -1;      /* -1 means that system
-                                          failed internally. */
-               return true;
        }
 
        ALARM_MGR_LOG_PRINT("called for  app(pid:%d, name=%s)\n",
@@ -2137,7 +2235,16 @@ gboolean alarm_manager_alarm_get_list_of_ids(void *pObject, int pid,
        snprintf(proc_file, 256, "/proc/%d/cmdline", pid);
 
        fd = open(proc_file, O_RDONLY);
-       if (fd > 0) {
+       if (fd < 0) {           /* failure */
+               quark_app_unique_name = g_quark_from_string("unknown");
+               memcpy(app_name, "unknown", strlen("unknown") + 1);
+
+               ALARM_MGR_EXCEPTION_PRINT("Caution!! app_pid(%d) seems to be "
+               "killed, so we failed to get proc file(%s)\n", pid, proc_file);
+               *return_code = -1;
+               /* -1 means that system failed internally. */
+               return true;
+       } else {
                ret = read(fd, process_name, 512);
                close(fd);
                while (process_name[i] != '\0') {
@@ -2157,16 +2264,6 @@ gboolean alarm_manager_alarm_get_list_of_ids(void *pObject, int pid,
                        word = strtok_r(NULL, "/", &proc_name_ptr);
                }
                quark_app_unique_name = g_quark_from_string(app_name);
-       } else {                /* failure */
-
-               quark_app_unique_name = g_quark_from_string("unknown");
-               memcpy(app_name, "unknown", strlen("unknown") + 1);
-
-               ALARM_MGR_EXCEPTION_PRINT("Caution!! app_pid(%d) seems to be "
-               "killed, so we failed to get proc file(%s)\n", pid, proc_file);
-               *return_code = -1;
-               /* -1 means that system failed internally. */
-               return true;
        }
 
        ALARM_MGR_LOG_PRINT("called for  app(pid:%d, name=%s)\n",
@@ -2411,7 +2508,7 @@ static void __hibernation_leave_callback()
 
 static bool __initialize_noti()
 {
-
+       int ret = -1;
        int fd = heynoti_init();
        if (fd < 0) {
                ALARM_MGR_EXCEPTION_PRINT("fail to heynoti_init\n");
@@ -2419,7 +2516,10 @@ static bool __initialize_noti()
        }
        heynoti_subscribe(fd, "HIBERNATION_LEAVE", __hibernation_leave_callback,
                          NULL);
-       heynoti_attach_handler(fd);
+       ret = heynoti_attach_handler(fd);
+       if(ret<0) {
+               ALARM_MGR_EXCEPTION_PRINT("heynoti_attach_handler fail");
+       }
 
        if (vconf_notify_key_changed
            (VCONFKEY_SYSTEM_TIMECHANGE, __on_system_time_changed, NULL) < 0) {
@@ -2428,6 +2528,18 @@ static bool __initialize_noti()
        }
        /*system state change noti Ã³¸® */
 
+       if (vconf_notify_key_changed
+           (VCONFKEY_SETAPPL_TIMEZONE_ID, __on_time_zone_changed, NULL) < 0) {
+               ALARM_MGR_LOG_PRINT(
+                       "Failed to add callback for time zone changing event\n");
+       }
+
+       if (vconf_notify_key_changed
+           (VCONFKEY_SYSTEM_TIMECHANGE_EXTERNAL, __on_system_time_external_changed, NULL) < 0) {
+               ALARM_MGR_LOG_PRINT(
+                       "Failed to add callback for time external changing event\n");
+       }
+
        return true;
 }