bf61df028410add087141ee95c24e7d7576926cb
[platform/framework/native/appfw.git] / src / system / FSys_AlarmManager.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file                FSys_AlarmManager.cpp
19  * @brief               This is the implementation file for _AlarmManager class.
20  */
21
22 #include <unique_ptr.h>
23
24 #include <appfw/app.h>
25 #include <alarm.h>
26 #include <appsvc/appsvc.h>
27
28 #include <FBaseSysLog.h>
29 #include <FSysSystemTime.h>
30 #include <FAppApp.h>
31 #include <FBaseColArrayList.h>
32
33 #include <FBase_NativeError.h>
34 #include <FBase_StringConverter.h>
35
36 #include "inc/FSys_AlarmManager.h"
37
38 using namespace Tizen::Base;
39 using namespace Tizen::Base::Runtime;
40 using namespace Tizen::Base::Collection;
41 using namespace Tizen::Io;
42
43 namespace Tizen { namespace System
44 {
45 static const long _SECOND_OF_MINUTE = 60;
46
47 _AlarmManager* _AlarmManager::__pAlarmManager = null;
48
49 _AlarmManager::_AlarmManager()
50         : __pAlarmHashMap(null)
51 {
52         result r = E_SUCCESS;
53         int ret = pthread_mutex_init(&__lock, null);
54         SysTryCatch(NID_SYS, ret == 0, r = E_SYSTEM, E_SYSTEM, "It is failed to init mutex.");
55
56         __alarmList.Construct();
57
58         if (!__pAlarmHashMap)
59         {
60                 __pAlarmHashMap = new (std::nothrow) MultiHashMap();
61                 SysTryCatch(NID_SYS, __pAlarmHashMap != null, r = E_SYSTEM, E_SYSTEM, "__pAlarmHashMap should not be null");
62
63                 r = __pAlarmHashMap->Construct();
64                 SysTryCatch(NID_SYS, r == E_SUCCESS, r= E_SYSTEM, E_SYSTEM, "[%s] Propagated.", GetErrorMessage(r));
65         }
66
67         //Checks for any alarm existence
68         alarm_cancel_all();
69
70 CATCH:
71         SetLastResult(r);
72 }
73
74 _AlarmManager::~_AlarmManager()
75 {
76         int ret = pthread_mutex_destroy(&__lock);
77         if(ret != 0)
78         {
79                 SysLogException(NID_SYS, E_SYSTEM, "It is failed to destroy mutex.");
80         }
81
82         delete __pAlarmHashMap;
83         __pAlarmHashMap = null;
84
85         //Cancel all the alarms before exiting
86         alarm_cancel_all();
87 }
88
89 int alarm_callback(alarm_id_t alarmId, void *user_param)
90 {
91         _AlarmManager* pAlarmManager = _AlarmManager::GetInstance();
92         pAlarmManager->OnAlarmExpired((int)alarmId);
93         return 0;
94 }
95
96 result
97 _AlarmManager::Construct(void)
98 {
99         int errorCode;
100         Tizen::App::App* pApp = null;
101         pApp = Tizen::App::App::GetInstance();
102         String appId = pApp->GetAppId();
103         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
104
105         errorCode = alarmmgr_init(pAppId.get());
106         SysTryReturnResult(NID_SYS, errorCode == ALARMMGR_RESULT_SUCCESS, E_SYSTEM, "It is failed to init alarmmgr. error [%d]", errorCode);
107         errorCode = alarmmgr_set_cb(alarm_callback, null);
108         SysTryReturnResult(NID_SYS, errorCode == ALARMMGR_RESULT_SUCCESS, E_SYSTEM, "It is failed to set cb to alarmmgr. error [%d]", errorCode);
109         return E_SUCCESS;
110 }
111
112 _AlarmManager*
113 _AlarmManager::GetInstance(void)
114 {
115         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
116         if(__pAlarmManager == null)
117         {
118                 pthread_once(&onceBlock, InitSingleton);
119         }
120         return __pAlarmManager;
121 }
122
123 void
124 _AlarmManager::InitSingleton(void)
125 {
126         result r = E_SUCCESS;
127         std::unique_ptr<_AlarmManager> pAlarmManager(new (std::nothrow) _AlarmManager());
128         SysTryReturnVoidResult(NID_SYS, pAlarmManager, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
129                                                    GetErrorMessage(E_OUT_OF_MEMORY));
130         r = pAlarmManager->Construct();
131         SysTryReturnVoidResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to construct alarm manager.");
132         __pAlarmManager = pAlarmManager.release();
133         std::atexit(DestroySingleton);
134 }
135
136 void
137 _AlarmManager::DestroySingleton(void)
138 {
139         delete __pAlarmManager;
140 }
141
142 int
143 _AlarmManager::ReserveAlarm(Tizen::Base::String appId, Tizen::Base::DateTime startTime, int period)
144 {
145         int reservedAlarmId = -1;
146         result r = E_SUCCESS;
147
148         int ret = 0;
149         service_h service;
150
151         SysLog(NID_SYS, "Reserve time is %d/%d/%d %d:%d:%d", startTime.GetYear(), startTime.GetMonth(), startTime.GetDay(), startTime.GetHour(), startTime.GetMinute(), startTime.GetSecond());
152
153         bundle* pBundle = null;
154         alarm_entry_t* pAlarmInfo = null;
155         alarm_date_t expireTime = {0,};
156
157         std::unique_ptr<char[]> pId(_StringConverter::CopyToCharArrayN(appId));
158
159         pBundle = bundle_create();
160         SysTryCatch(NID_SYS, pBundle != null, r = E_SYSTEM, r, "It is failed to create bundle");
161
162         ret = appsvc_set_operation(pBundle,"osp.operation.ALARM");
163         SysTryCatch(NID_SYS, ret == SERVICE_ERROR_NONE, r = E_SYSTEM, r, "It is failed to set operation");
164
165         ret = appsvc_set_appid(pBundle, (const char*)(pId.get()));
166         SysTryCatch(NID_SYS, ret == SERVICE_ERROR_NONE, r = E_SYSTEM, r, "It is failed to set appid for %ls", appId.GetPointer());
167
168         pAlarmInfo = alarmmgr_create_alarm();
169         SysTryCatch(NID_SYS, pAlarmInfo != null, r = E_SYSTEM, r, "It is failed to create alarm entry");
170
171         expireTime.year = startTime.GetYear();
172         expireTime.month = startTime.GetMonth();
173         expireTime.day = startTime.GetDay();
174         expireTime.hour = startTime.GetHour();
175         expireTime.min = startTime.GetMinute();
176         expireTime.sec = startTime.GetSecond();
177
178         ret = alarmmgr_set_time(pAlarmInfo, expireTime);
179         SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "It is failed to set new alarm time");
180
181         if(period > 0)
182         {
183                 SysLog(NID_SYS, "It is repeated alarm and period time is %d minutes", period);
184                 ret = alarmmgr_set_repeat_mode(pAlarmInfo, ALARM_REPEAT_MODE_REPEAT, period * _SECOND_OF_MINUTE);
185                 SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "It is failed to set repeat mode");
186         }
187
188         ret = alarmmgr_set_type(pAlarmInfo, ALARM_TYPE_NOLAUNCH);
189         SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "It is failed to set repeat mode");
190
191         ret = alarmmgr_add_alarm_with_localtime(pAlarmInfo, null, &reservedAlarmId);
192         SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "Alarm creation failed!!! Alrmgr error code is %d", ret);
193
194 CATCH:
195         if(r == E_SYSTEM)
196         {
197                 reservedAlarmId = -1;
198         }
199         if(pAlarmInfo != null)
200         {
201                 alarmmgr_free_alarm(pAlarmInfo);
202         }
203
204         if(pBundle != null)
205         {
206                 bundle_free(pBundle);
207         }
208
209         return reservedAlarmId;
210 }
211
212 result
213 _AlarmManager::AddAlarmList(int alarmId, int period, String appId, DateTime* endTime)
214 {
215         result r = E_SUCCESS;
216
217         SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
218         SysLog(NID_SYS, "New Alarm Id is added (%d, %d, %ls)", alarmId, period, appId.GetPointer());
219
220         Integer* reservedAlarmId = null;
221         Integer* alarmPeriod = null;
222         String* alarmAppId = null;
223
224         Integer* reverseAlarmId = null;
225         String* reverseAppId = null;
226
227         reservedAlarmId = new (std::nothrow) Integer(alarmId);
228         SysTryCatch(NID_SYS, reservedAlarmId != null, r = E_SYSTEM, E_SYSTEM, "reservedAlarmId should not be null");
229
230         alarmPeriod = new (std::nothrow) Integer(period);
231         SysTryCatch(NID_SYS, alarmPeriod != null, r = E_SYSTEM, E_SYSTEM, "alarmPeriod should not be null");
232
233         alarmAppId = new (std::nothrow) String(appId);
234         SysTryCatch(NID_SYS, alarmAppId != null, r = E_SYSTEM, E_SYSTEM, "alarmAppId should not be null");
235
236         //Forward
237         r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmAppId);
238         SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm app id on the alarm list");
239
240         r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmPeriod);
241         SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm period on the alarm list");
242
243         if(endTime != null)
244         {
245                 DateTime* alarmEndTime = new DateTime(*endTime);
246
247                 SysLog(NID_SYS, "Endtime exists %d:%d:%d", alarmEndTime->GetHour(), alarmEndTime->GetMinute(), alarmEndTime->GetSecond());
248                 r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmEndTime);
249                 SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm endtime on the alarm list");
250         }
251
252         //Reverse
253         reverseAlarmId = new (std::nothrow) Integer(alarmId);
254         SysTryCatch(NID_SYS, reverseAlarmId != null, r = E_SYSTEM, E_SYSTEM, "reverseAlarmId should not be null");
255
256         reverseAppId = new (std::nothrow) String(appId);
257         SysTryCatch(NID_SYS, reverseAppId != null, r = E_SYSTEM, E_SYSTEM, "reverseAppId should not be null");
258
259         r = __pAlarmHashMap->Add(*reverseAppId, *reverseAlarmId);
260         SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm on the alarm list");
261
262 CATCH:
263         if(r != E_SUCCESS)
264         {
265                 if(reservedAlarmId != null)
266                 {
267                         __pAlarmHashMap->Remove(*reservedAlarmId, false);
268                         delete reservedAlarmId;
269                 }
270
271                 if(alarmPeriod != null)
272                 {
273                         delete alarmPeriod;
274                 }
275
276                 if(alarmAppId != null)
277                 {
278                         delete alarmAppId;
279                 }
280
281                 if(reverseAppId != null)
282                 {
283                         __pAlarmHashMap->Remove(*reverseAppId, false);
284                         delete reverseAppId;
285                 }
286
287                 if(reverseAlarmId != null)
288                 {
289                         delete reverseAlarmId;
290                 }
291         }
292         return r;
293 }
294
295 result
296 _AlarmManager::RemoveAlarmList(int alarmId)
297 {
298         result r = E_SUCCESS;
299         Integer requiredAlarmId(alarmId);
300         std::unique_ptr<IEnumerator>pValueEnum(null);
301
302         SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
303
304         alarm_cancel(alarmId);
305         SysLog(NID_SYS, "AlarmId %d disarms the timer.", alarmId);
306
307         pValueEnum.reset(__pAlarmHashMap->GetValuesN(requiredAlarmId));
308
309         if(pValueEnum != null)
310         {
311                 SysLog(NID_SYS, "Reserved Alarms are exist");
312                 String* alarmAppId = null;
313                 r = pValueEnum->MoveNext();
314                 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "Reserved Alarm List is not valid.");
315                 alarmAppId = static_cast< String* >(pValueEnum->GetCurrent());
316
317                 if(alarmAppId != null)
318                 {
319                         SysLog(NID_SYS, "Alarm AppId is %S", alarmAppId->GetPointer());
320                         std::unique_ptr<IEnumerator>pAlarmEnum(__pAlarmHashMap->GetValuesN(*alarmAppId));
321                         if(pAlarmEnum != null)
322                         {
323                                 while(pAlarmEnum->MoveNext() == E_SUCCESS)
324                                 {
325                                         Integer* reverseAlarmId = static_cast< Integer* >(pAlarmEnum->GetCurrent());
326                                         if(reverseAlarmId != null)
327                                         {
328                                                 SysLog(NID_SYS, "Reserved Alarm is %d", reverseAlarmId->ToInt());
329                                                 if(reverseAlarmId->ToInt() == alarmId)
330                                                 {
331                                                         SysLog(NID_SYS, "Remove reservedAlarmId for reverse look-up");
332                                                          __pAlarmHashMap->Remove(*alarmAppId, *reverseAlarmId);
333                                                         delete reverseAlarmId;
334                                                         break;
335                                                 }
336                                         }
337                                 }
338                         }
339
340                         int count = 0;
341                         __pAlarmHashMap->GetCount(*alarmAppId, count);
342                         if(count == 0)
343                         {
344                                 SysLog(NID_SYS, "There is no more reserved alarm for AppId:%S", alarmAppId->GetPointer());
345                                 __pAlarmHashMap->Remove(*alarmAppId, true);
346                         }
347                 }
348         }
349         r = __pAlarmHashMap->Remove(requiredAlarmId, true);
350
351         return r;
352 }
353
354 result
355 _AlarmManager::RemoveAlarmList(String appId)
356 {
357         result r = E_SUCCESS;
358         Integer requiredAlarmId;
359         IEnumerator *pValueEnum = null;
360
361         SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
362         pValueEnum = __pAlarmHashMap->GetValuesN(appId);
363
364         if(pValueEnum != null)
365         {
366                 SysLog(NID_SYS, "Reserved Alarms are exist for AppId:%S", appId.GetPointer());
367                 while(pValueEnum->MoveNext() == E_SUCCESS)
368                 {
369                         Integer* reverseAlarmId = static_cast< Integer* >(pValueEnum->GetCurrent());
370                         if(reverseAlarmId != null)
371                         {
372                                 SysLog(NID_SYS, "Reserved AlarmId is %d", reverseAlarmId->ToInt());
373                                 alarm_cancel(reverseAlarmId->ToInt());
374                                 __pAlarmHashMap->Remove(*reverseAlarmId, true);
375                         }
376                 }
377                 delete pValueEnum;
378         }
379         r = __pAlarmHashMap->Remove(appId, true);
380
381         return r;
382 }
383
384 result
385 _AlarmManager::RegisterAlarm(_AlarmImpl* pAlarmImpl)
386 {
387         SysTryReturnResult(NID_SYS, pAlarmImpl != null, E_INVALID_ARG, "There is no alarmImpl.");
388         Integer alarmId(pAlarmImpl->__alarmId.value);
389         SysTryReturnResult(NID_SYS, __alarmList.ContainsKey(alarmId) == false, E_OBJ_ALREADY_EXIST, "Required Alarm[%d] is already registered.", pAlarmImpl->__alarmId.value);
390
391         result r = E_SUCCESS;
392         ArrayList requestMessage;
393         ArrayList responseMessage;
394
395         String startTimeStr;
396         String periodStr;
397         String endTimeStr;
398         String appId;
399
400         int reservedAlarmId = 0;
401         int period = pAlarmImpl->GetPeriod();
402         int ret = 0;
403         Tizen::App::App* pApp = null;
404  
405         DateTime currentTime;
406         DateTime startTime = pAlarmImpl->GetStartTime();
407         const DateTime* pEndTime = pAlarmImpl->GetEndTime();
408         DateTime endTime;
409
410         //Argument check
411         startTime.AddMilliseconds(-1 * startTime.GetMillisecond());
412         r = SystemTime::GetCurrentTime(WALL_TIME, currentTime);
413         currentTime.AddMilliseconds(-1 * currentTime.GetMillisecond());
414
415         SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get current time.");
416         SysTryReturnResult(NID_SYS, DateTime::Compare(currentTime, startTime) < 0, E_INVALID_ARG, "Designated start time has to be greater than current time.");
417         SysTryReturnResult(NID_SYS, period > -1, E_INVALID_ARG, "Period has to greater than -1");
418
419         ret = pthread_mutex_lock(&__lock);
420         SysTryCatch(NID_SYS, ret == 0, r = E_INVALID_ARG, r, "It is failed to lock mutex.");
421
422         if(pEndTime != null)
423         {
424                 endTime = *pEndTime;
425                 endTime.AddMilliseconds(-1 * endTime.GetMillisecond());
426
427                 SysTryCatch(NID_SYS, DateTime::Compare(startTime, endTime) < 0, r = E_INVALID_ARG, r, "Designated end time is less than start time.");
428         }
429         //End Alarm validation check
430
431         pApp = Tizen::App::App::GetInstance();
432         SysTryCatch(NID_SYS, pApp != null, r = E_SYSTEM, r, "[%s] A system error has been occurred. App::GetInstance() failed.", GetErrorMessage(E_SYSTEM));
433         appId = pApp->GetAppId();
434
435         reservedAlarmId = ReserveAlarm(appId, startTime, period);
436         SysTryCatch(NID_SYS, reservedAlarmId != -1, r = E_SYSTEM, r, "It is failed to register alarm.");
437
438         SysLog(NID_SYS, "Reserved AppId %ls, alarmId: %d", appId.GetPointer(), reservedAlarmId);
439
440         if(pEndTime == null)
441         {
442                 r = AddAlarmList(reservedAlarmId, period, appId, null);
443         }
444         else
445         {
446                 r = AddAlarmList(reservedAlarmId, period, appId, (DateTime*)(&endTime));
447         }
448         SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, r, "It is failed to add new alarm on the alarm list.");
449
450         pAlarmImpl->__alarmId.value = reservedAlarmId;
451         r = __alarmList.Add(&(pAlarmImpl->__alarmId), pAlarmImpl);
452
453 CATCH:
454         ret = pthread_mutex_unlock(&__lock);
455         SysTryReturnResult(NID_SYS, ret == 0, E_INVALID_ARG, "It is failed to unlock mutex.");
456         return r;
457 }
458
459 result
460 _AlarmManager::UnregisterAlarm(_AlarmImpl* pAlarmImpl)
461 {
462         result r = E_SUCCESS;
463         Integer alarmId;
464         int ret = 0;
465         SysLog(NID_SYS, "Alarm Cancel request");
466         SysTryCatch(NID_SYS, pAlarmImpl != null, r = E_INVALID_ARG, r, "There is no alarmImpl.");
467
468         ret = pthread_mutex_lock(&__lock);
469         SysTryCatch(NID_SYS, ret == 0, r = E_SYSTEM, r, "It is failed to lock mutex.");
470
471         alarmId.value = pAlarmImpl->__alarmId.value;
472         SysTryCatch(NID_SYS, __alarmList.ContainsKey(alarmId) == true, r = E_OBJ_NOT_FOUND, r, "There is no registered alarm.");
473
474         r = __alarmList.Remove(alarmId);
475         SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, r, "It is failed to remove reserved alarmImpl instance.");
476
477         r = RemoveAlarmList(alarmId.ToInt());
478         SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, r, "It is failed to remove reserved alarm list.");
479
480 CATCH:
481         ret = pthread_mutex_unlock(&__lock);
482         SysTryReturnResult(NID_SYS, ret == 0, E_SYSTEM, "It is failed to unlock mutex.");
483         return r;
484 }
485
486 result
487 _AlarmManager::UpdateAlarm(_AlarmImpl* pAlarmImpl)
488 {
489         result r = E_SUCCESS;
490         Integer alarmId;
491         SysTryReturnResult(NID_SYS, pAlarmImpl != null, E_SYSTEM, "There is no alarmImpl.");
492
493         alarmId.value = pAlarmImpl->__alarmId.value;
494         SysTryReturnResult(NID_SYS, __alarmList.ContainsKey(alarmId) == true, E_SYSTEM, "There is no registered alarm.");
495
496         r = UnregisterAlarm(pAlarmImpl);
497         SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to unregister reserved alarm list.");
498
499         r = RegisterAlarm(pAlarmImpl);
500         SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to register alarm.");
501         return r;
502 }
503
504 void
505 _AlarmManager::OnAlarmExpired(int alarmId)
506 {
507         result r = E_SUCCESS;
508         int ret = 0;
509         String* pAppId = null;
510         Integer* pPeriod = null;
511         String alarmAppId;
512         std::unique_ptr<IEnumerator> pValueEnum(null);
513         Integer reservedAlarmId(alarmId);
514         DateTime* endTime = null;
515         _AlarmImpl* pAlarmImpl = null;
516
517         SysTryCatch(NID_SYS, __pAlarmHashMap != null, r = E_SYSTEM, r, "Alarm list does not initialized");
518
519         ret = pthread_mutex_lock(&__lock);
520         SysTryReturnVoidResult(NID_SYS, ret == 0, E_SYSTEM, "It is failed to lock mutex.");
521
522         pValueEnum.reset(__pAlarmHashMap->GetValuesN(reservedAlarmId));
523
524         SysLog(NID_SYS, "Alarm expire event is delivered. alarm id is %d", alarmId);
525
526         pAlarmImpl = (_AlarmImpl*)__alarmList.GetValue(reservedAlarmId);
527         if(pAlarmImpl == null)
528         {
529                 SysLog(NID_SYS, "pAlarmImpl of reserved alarm[%d] is not found.", alarmId);
530         }
531
532         if(pValueEnum != null)
533         {
534                 SysLog(NID_SYS, "Matching Alarm Id is %d \n", alarmId);
535
536                 r = pValueEnum->MoveNext();
537                 SysTryCatch(NID_SYS,  r == E_SUCCESS, r = E_SYSTEM, r, "Alarm enum value is not valid.");
538                 pAppId = static_cast< String* >(pValueEnum->GetCurrent());
539                 alarmAppId.Append(*pAppId);
540                 r = pValueEnum->MoveNext();
541                 pPeriod = static_cast< Integer* >(pValueEnum->GetCurrent());
542                 SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, r, "Alarm enum value is not valid.");
543
544                 if(pValueEnum->MoveNext() == E_SUCCESS)
545                 {
546                         endTime = static_cast< DateTime* >(pValueEnum->GetCurrent());
547                 }
548
549                 SysLog(NID_SYS, "Reserved Alarm AppId:%ls, Period:%d\n", pAppId->GetPointer(), pPeriod->ToInt());
550
551                 if (pPeriod->ToInt() > 0)
552                 {
553                         if(endTime != null)
554                         {
555                                 DateTime currentTime;
556
557                                 SystemTime::GetCurrentTime(WALL_TIME, currentTime);
558                                 currentTime.AddMilliseconds(-1 * currentTime.GetMillisecond()); //Remove millisecond
559                                 currentTime.AddMinutes(pPeriod->ToInt());
560                                 SysLog(NID_SYS, "Next time[%d min]: %d:%d:%d:%d", pPeriod->ToInt(), currentTime.GetHour(), currentTime.GetMinute(), currentTime.GetSecond(), currentTime.GetMillisecond());
561                                 SysLog(NID_SYS, "Endtime exists %d:%d:%d:%d", endTime->GetHour(), endTime->GetMinute(), endTime->GetSecond(), endTime->GetMillisecond());
562
563                                 if (currentTime.CompareTo(*endTime) > 0)
564                                 {
565                                         SysLog(NID_SYS, "Next time is greater than end time.");
566                                         RemoveAlarmList(alarmId);
567                                         pValueEnum->Reset();
568
569                                         if(pAlarmImpl != null)
570                                         {
571                                                 pAlarmImpl->__alarmId.value = 0;
572                                         }
573                                 }
574                         }
575                 }
576                 else if (pPeriod->ToInt() == 0)
577                 {
578                         RemoveAlarmList(alarmId);
579
580                         if(pAlarmImpl != null)
581                         {
582                                 pAlarmImpl->__alarmId.value = 0;
583                         }
584                 }
585                 else
586                 {
587                         pValueEnum->Reset();
588                 }
589
590         }
591
592         ret = pthread_mutex_unlock(&__lock);
593
594         if(pAlarmImpl != null)
595         {
596                 pAlarmImpl->OnAlarmExpired(alarmId);
597         }
598
599         if(__pAlarmHashMap->ContainsKey(reservedAlarmId) == false)
600         {
601                 ret = pthread_mutex_lock(&__lock);
602                 SysLog(NID_SYS, "Remove an alarm list[%d].", reservedAlarmId.value);
603                 r = __alarmList.Remove(reservedAlarmId);
604                 ret = pthread_mutex_unlock(&__lock);
605                 SetLastResult(r);
606         }
607
608         return;
609
610 CATCH:
611         ret = pthread_mutex_unlock(&__lock);
612         SysTryReturnVoidResult(NID_SYS, ret == 0, E_SYSTEM, "It is failed to unlock mutex.");
613 }
614
615 } } // Tizen::System