Add exception code.
[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         SysTryReturn(NID_SYS, pAlarmManager, -1, E_SYSTEM, "It is fail to get AlarmManager.");
93         pAlarmManager->OnAlarmExpired((int)alarmId);
94         return 0;
95 }
96
97 result
98 _AlarmManager::Construct(void)
99 {
100         int errorCode;
101         Tizen::App::App* pApp = null;
102         pApp = Tizen::App::App::GetInstance();
103         SysTryReturnResult(NID_SYS, pApp, E_SYSTEM, "It is failed to get app instance.");
104         String appId = pApp->GetAppId();
105         std::unique_ptr<char[]> pAppId(_StringConverter::CopyToCharArrayN(appId));
106         errorCode = alarmmgr_init(pAppId.get());
107         SysTryReturnResult(NID_SYS, errorCode == ALARMMGR_RESULT_SUCCESS, E_SYSTEM, "It is failed to init alarmmgr. error [%d]", errorCode);
108         errorCode = alarmmgr_set_cb(alarm_callback, null);
109         SysTryReturnResult(NID_SYS, errorCode == ALARMMGR_RESULT_SUCCESS, E_SYSTEM, "It is failed to set cb to alarmmgr. error [%d]", errorCode);
110         return E_SUCCESS;
111 }
112
113 _AlarmManager*
114 _AlarmManager::GetInstance(void)
115 {
116         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
117         if(__pAlarmManager == null)
118         {
119                 pthread_once(&onceBlock, InitSingleton);
120         }
121         return __pAlarmManager;
122 }
123
124 void
125 _AlarmManager::InitSingleton(void)
126 {
127         result r = E_SUCCESS;
128         std::unique_ptr<_AlarmManager> pAlarmManager(new (std::nothrow) _AlarmManager());
129         SysTryReturnVoidResult(NID_SYS, pAlarmManager, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
130                                                    GetErrorMessage(E_OUT_OF_MEMORY));
131         r = pAlarmManager->Construct();
132         SysTryReturnVoidResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to construct alarm manager.");
133         __pAlarmManager = pAlarmManager.release();
134         std::atexit(DestroySingleton);
135 }
136
137 void
138 _AlarmManager::DestroySingleton(void)
139 {
140         delete __pAlarmManager;
141 }
142
143 int
144 _AlarmManager::ReserveAlarm(Tizen::Base::String appId, Tizen::Base::DateTime startTime, int period)
145 {
146         int reservedAlarmId = -1;
147         result r = E_SUCCESS;
148
149         int ret = 0;
150         service_h service;
151
152         SysLog(NID_SYS, "Reserve time is %d/%d/%d %d:%d:%d", startTime.GetYear(), startTime.GetMonth(), startTime.GetDay(), startTime.GetHour(), startTime.GetMinute(), startTime.GetSecond());
153
154         bundle* pBundle = null;
155         alarm_entry_t* pAlarmInfo = null;
156         alarm_date_t expireTime = {0,};
157
158         std::unique_ptr<char[]> pId(_StringConverter::CopyToCharArrayN(appId));
159
160         pBundle = bundle_create();
161         SysTryCatch(NID_SYS, pBundle != null, r = E_SYSTEM, r, "It is failed to create bundle");
162
163         ret = appsvc_set_operation(pBundle,"osp.operation.ALARM");
164         SysTryCatch(NID_SYS, ret == SERVICE_ERROR_NONE, r = E_SYSTEM, r, "It is failed to set operation");
165
166         ret = appsvc_set_appid(pBundle, (const char*)(pId.get()));
167         SysTryCatch(NID_SYS, ret == SERVICE_ERROR_NONE, r = E_SYSTEM, r, "It is failed to set appid for %ls", appId.GetPointer());
168
169         pAlarmInfo = alarmmgr_create_alarm();
170         SysTryCatch(NID_SYS, pAlarmInfo != null, r = E_SYSTEM, r, "It is failed to create alarm entry");
171
172         expireTime.year = startTime.GetYear();
173         expireTime.month = startTime.GetMonth();
174         expireTime.day = startTime.GetDay();
175         expireTime.hour = startTime.GetHour();
176         expireTime.min = startTime.GetMinute();
177         expireTime.sec = startTime.GetSecond();
178
179         ret = alarmmgr_set_time(pAlarmInfo, expireTime);
180         SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "It is failed to set new alarm time");
181
182         if(period > 0)
183         {
184                 SysLog(NID_SYS, "It is repeated alarm and period time is %d minutes", period);
185                 ret = alarmmgr_set_repeat_mode(pAlarmInfo, ALARM_REPEAT_MODE_REPEAT, period * _SECOND_OF_MINUTE);
186                 SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "It is failed to set repeat mode");
187         }
188
189         ret = alarmmgr_set_type(pAlarmInfo, ALARM_TYPE_NOLAUNCH);
190         SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "It is failed to set repeat mode");
191
192         ret = alarmmgr_add_alarm_with_localtime(pAlarmInfo, null, &reservedAlarmId);
193         SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "Alarm creation failed!!! Alrmgr error code is %d", ret);
194
195 CATCH:
196         if(r == E_SYSTEM)
197         {
198                 reservedAlarmId = -1;
199         }
200         if(pAlarmInfo != null)
201         {
202                 alarmmgr_free_alarm(pAlarmInfo);
203         }
204
205         if(pBundle != null)
206         {
207                 bundle_free(pBundle);
208         }
209
210         return reservedAlarmId;
211 }
212
213 result
214 _AlarmManager::AddAlarmList(int alarmId, int period, String appId, DateTime* endTime)
215 {
216         result r = E_SUCCESS;
217
218         SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
219         SysLog(NID_SYS, "New Alarm Id is added (%d, %d, %ls)", alarmId, period, appId.GetPointer());
220
221         Integer* reservedAlarmId = null;
222         Integer* alarmPeriod = null;
223         String* alarmAppId = null;
224
225         Integer* reverseAlarmId = null;
226         String* reverseAppId = null;
227
228         reservedAlarmId = new (std::nothrow) Integer(alarmId);
229         SysTryCatch(NID_SYS, reservedAlarmId != null, r = E_SYSTEM, E_SYSTEM, "reservedAlarmId should not be null");
230
231         alarmPeriod = new (std::nothrow) Integer(period);
232         SysTryCatch(NID_SYS, alarmPeriod != null, r = E_SYSTEM, E_SYSTEM, "alarmPeriod should not be null");
233
234         alarmAppId = new (std::nothrow) String(appId);
235         SysTryCatch(NID_SYS, alarmAppId != null, r = E_SYSTEM, E_SYSTEM, "alarmAppId should not be null");
236
237         //Forward
238         r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmAppId);
239         SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm app id on the alarm list");
240
241         r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmPeriod);
242         SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm period on the alarm list");
243
244         if(endTime != null)
245         {
246                 DateTime* alarmEndTime = new DateTime(*endTime);
247
248                 SysLog(NID_SYS, "Endtime exists %d:%d:%d", alarmEndTime->GetHour(), alarmEndTime->GetMinute(), alarmEndTime->GetSecond());
249                 r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmEndTime);
250                 SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm endtime on the alarm list");
251         }
252
253         //Reverse
254         reverseAlarmId = new (std::nothrow) Integer(alarmId);
255         SysTryCatch(NID_SYS, reverseAlarmId != null, r = E_SYSTEM, E_SYSTEM, "reverseAlarmId should not be null");
256
257         reverseAppId = new (std::nothrow) String(appId);
258         SysTryCatch(NID_SYS, reverseAppId != null, r = E_SYSTEM, E_SYSTEM, "reverseAppId should not be null");
259
260         r = __pAlarmHashMap->Add(*reverseAppId, *reverseAlarmId);
261         SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm on the alarm list");
262
263 CATCH:
264         if(r != E_SUCCESS)
265         {
266                 if(reservedAlarmId != null)
267                 {
268                         __pAlarmHashMap->Remove(*reservedAlarmId, false);
269                         delete reservedAlarmId;
270                 }
271
272                 if(alarmPeriod != null)
273                 {
274                         delete alarmPeriod;
275                 }
276
277                 if(alarmAppId != null)
278                 {
279                         delete alarmAppId;
280                 }
281
282                 if(reverseAppId != null)
283                 {
284                         __pAlarmHashMap->Remove(*reverseAppId, false);
285                         delete reverseAppId;
286                 }
287
288                 if(reverseAlarmId != null)
289                 {
290                         delete reverseAlarmId;
291                 }
292         }
293         return r;
294 }
295
296 result
297 _AlarmManager::RemoveAlarmList(int alarmId)
298 {
299         result r = E_SUCCESS;
300         Integer requiredAlarmId(alarmId);
301         std::unique_ptr<IEnumerator>pValueEnum(null);
302
303         SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
304
305         alarm_cancel(alarmId);
306         SysLog(NID_SYS, "AlarmId %d disarms the timer.", alarmId);
307
308         pValueEnum.reset(__pAlarmHashMap->GetValuesN(requiredAlarmId));
309
310         if(pValueEnum != null)
311         {
312                 SysLog(NID_SYS, "Reserved Alarms are exist");
313                 String* alarmAppId = null;
314                 r = pValueEnum->MoveNext();
315                 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "Reserved Alarm List is not valid.");
316                 alarmAppId = static_cast< String* >(pValueEnum->GetCurrent());
317
318                 if(alarmAppId != null)
319                 {
320                         SysLog(NID_SYS, "Alarm AppId is %S", alarmAppId->GetPointer());
321                         std::unique_ptr<IEnumerator>pAlarmEnum(__pAlarmHashMap->GetValuesN(*alarmAppId));
322                         if(pAlarmEnum != null)
323                         {
324                                 while(pAlarmEnum->MoveNext() == E_SUCCESS)
325                                 {
326                                         Integer* reverseAlarmId = static_cast< Integer* >(pAlarmEnum->GetCurrent());
327                                         if(reverseAlarmId != null)
328                                         {
329                                                 SysLog(NID_SYS, "Reserved Alarm is %d", reverseAlarmId->ToInt());
330                                                 if(reverseAlarmId->ToInt() == alarmId)
331                                                 {
332                                                         SysLog(NID_SYS, "Remove reservedAlarmId for reverse look-up");
333                                                          __pAlarmHashMap->Remove(*alarmAppId, *reverseAlarmId);
334                                                         delete reverseAlarmId;
335                                                         break;
336                                                 }
337                                         }
338                                 }
339                         }
340
341                         int count = 0;
342                         __pAlarmHashMap->GetCount(*alarmAppId, count);
343                         if(count == 0)
344                         {
345                                 SysLog(NID_SYS, "There is no more reserved alarm for AppId:%S", alarmAppId->GetPointer());
346                                 __pAlarmHashMap->Remove(*alarmAppId, true);
347                         }
348                 }
349         }
350         r = __pAlarmHashMap->Remove(requiredAlarmId, true);
351
352         return r;
353 }
354
355 result
356 _AlarmManager::RemoveAlarmList(String appId)
357 {
358         result r = E_SUCCESS;
359         Integer requiredAlarmId;
360         IEnumerator *pValueEnum = null;
361
362         SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
363         pValueEnum = __pAlarmHashMap->GetValuesN(appId);
364
365         if(pValueEnum != null)
366         {
367                 SysLog(NID_SYS, "Reserved Alarms are exist for AppId:%S", appId.GetPointer());
368                 while(pValueEnum->MoveNext() == E_SUCCESS)
369                 {
370                         Integer* reverseAlarmId = static_cast< Integer* >(pValueEnum->GetCurrent());
371                         if(reverseAlarmId != null)
372                         {
373                                 SysLog(NID_SYS, "Reserved AlarmId is %d", reverseAlarmId->ToInt());
374                                 alarm_cancel(reverseAlarmId->ToInt());
375                                 __pAlarmHashMap->Remove(*reverseAlarmId, true);
376                         }
377                 }
378                 delete pValueEnum;
379         }
380         r = __pAlarmHashMap->Remove(appId, true);
381
382         return r;
383 }
384
385 result
386 _AlarmManager::RegisterAlarm(_AlarmImpl* pAlarmImpl)
387 {
388         SysTryReturnResult(NID_SYS, pAlarmImpl != null, E_INVALID_ARG, "There is no alarmImpl.");
389         Integer alarmId(pAlarmImpl->__alarmId.value);
390         SysTryReturnResult(NID_SYS, __alarmList.ContainsKey(alarmId) == false, E_OBJ_ALREADY_EXIST, "Required Alarm[%d] is already registered.", pAlarmImpl->__alarmId.value);
391
392         result r = E_SUCCESS;
393         ArrayList requestMessage;
394         ArrayList responseMessage;
395
396         String startTimeStr;
397         String periodStr;
398         String endTimeStr;
399         String appId;
400
401         int reservedAlarmId = 0;
402         int period = pAlarmImpl->GetPeriod();
403         int ret = 0;
404         Tizen::App::App* pApp = null;
405  
406         DateTime currentTime;
407         DateTime startTime = pAlarmImpl->GetStartTime();
408         const DateTime* pEndTime = pAlarmImpl->GetEndTime();
409         DateTime endTime;
410
411         //Argument check
412         startTime.AddMilliseconds(-1 * startTime.GetMillisecond());
413         r = SystemTime::GetCurrentTime(WALL_TIME, currentTime);
414         currentTime.AddMilliseconds(-1 * currentTime.GetMillisecond());
415
416         SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get current time.");
417         SysTryReturnResult(NID_SYS, DateTime::Compare(currentTime, startTime) < 0, E_INVALID_ARG, "Designated start time has to be greater than current time.");
418         SysTryReturnResult(NID_SYS, period > -1, E_INVALID_ARG, "Period has to greater than -1");
419
420         ret = pthread_mutex_lock(&__lock);
421         SysTryCatch(NID_SYS, ret == 0, r = E_INVALID_ARG, r, "It is failed to lock mutex.");
422
423         if(pEndTime != null)
424         {
425                 endTime = *pEndTime;
426                 endTime.AddMilliseconds(-1 * endTime.GetMillisecond());
427
428                 SysTryCatch(NID_SYS, DateTime::Compare(startTime, endTime) < 0, r = E_INVALID_ARG, r, "Designated end time is less than start time.");
429         }
430         //End Alarm validation check
431
432         pApp = Tizen::App::App::GetInstance();
433         SysTryCatch(NID_SYS, pApp != null, r = E_SYSTEM, r, "[%s] A system error has been occurred. App::GetInstance() failed.", GetErrorMessage(E_SYSTEM));
434         appId = pApp->GetAppId();
435
436         reservedAlarmId = ReserveAlarm(appId, startTime, period);
437         SysTryCatch(NID_SYS, reservedAlarmId != -1, r = E_SYSTEM, r, "It is failed to register alarm.");
438
439         SysLog(NID_SYS, "Reserved AppId %ls, alarmId: %d", appId.GetPointer(), reservedAlarmId);
440
441         if(pEndTime == null)
442         {
443                 r = AddAlarmList(reservedAlarmId, period, appId, null);
444         }
445         else
446         {
447                 r = AddAlarmList(reservedAlarmId, period, appId, (DateTime*)(&endTime));
448         }
449         SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, r, "It is failed to add new alarm on the alarm list.");
450
451         pAlarmImpl->__alarmId.value = reservedAlarmId;
452         r = __alarmList.Add(&(pAlarmImpl->__alarmId), pAlarmImpl);
453
454 CATCH:
455         ret = pthread_mutex_unlock(&__lock);
456         SysTryReturnResult(NID_SYS, ret == 0, E_INVALID_ARG, "It is failed to unlock mutex.");
457         return r;
458 }
459
460 result
461 _AlarmManager::UnregisterAlarm(_AlarmImpl* pAlarmImpl)
462 {
463         result r = E_SUCCESS;
464         Integer alarmId;
465         int ret = 0;
466         SysLog(NID_SYS, "Alarm Cancel request");
467         SysTryCatch(NID_SYS, pAlarmImpl != null, r = E_INVALID_ARG, r, "There is no alarmImpl.");
468
469         ret = pthread_mutex_lock(&__lock);
470         SysTryCatch(NID_SYS, ret == 0, r = E_SYSTEM, r, "It is failed to lock mutex.");
471
472         alarmId.value = pAlarmImpl->__alarmId.value;
473         SysTryCatch(NID_SYS, __alarmList.ContainsKey(alarmId) == true, r = E_OBJ_NOT_FOUND, r, "There is no registered alarm.");
474
475         r = __alarmList.Remove(alarmId);
476         SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, r, "It is failed to remove reserved alarmImpl instance.");
477
478         r = RemoveAlarmList(alarmId.ToInt());
479         SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, r, "It is failed to remove reserved alarm list.");
480
481 CATCH:
482         ret = pthread_mutex_unlock(&__lock);
483         SysTryReturnResult(NID_SYS, ret == 0, E_SYSTEM, "It is failed to unlock mutex.");
484         return r;
485 }
486
487 result
488 _AlarmManager::UpdateAlarm(_AlarmImpl* pAlarmImpl)
489 {
490         result r = E_SUCCESS;
491         Integer alarmId;
492         SysTryReturnResult(NID_SYS, pAlarmImpl != null, E_SYSTEM, "There is no alarmImpl.");
493
494         alarmId.value = pAlarmImpl->__alarmId.value;
495         SysTryReturnResult(NID_SYS, __alarmList.ContainsKey(alarmId) == true, E_SYSTEM, "There is no registered alarm.");
496
497         r = UnregisterAlarm(pAlarmImpl);
498         SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to unregister reserved alarm list.");
499
500         r = RegisterAlarm(pAlarmImpl);
501         SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to register alarm.");
502         return r;
503 }
504
505 void
506 _AlarmManager::OnAlarmExpired(int alarmId)
507 {
508         result r = E_SUCCESS;
509         int ret = 0;
510         String* pAppId = null;
511         Integer* pPeriod = null;
512         String alarmAppId;
513         std::unique_ptr<IEnumerator> pValueEnum(null);
514         Integer reservedAlarmId(alarmId);
515         DateTime* endTime = null;
516         _AlarmImpl* pAlarmImpl = null;
517
518         SysTryCatch(NID_SYS, __pAlarmHashMap != null, r = E_SYSTEM, r, "Alarm list does not initialized");
519
520         ret = pthread_mutex_lock(&__lock);
521         SysTryReturnVoidResult(NID_SYS, ret == 0, E_SYSTEM, "It is failed to lock mutex.");
522
523         pValueEnum.reset(__pAlarmHashMap->GetValuesN(reservedAlarmId));
524
525         SysLog(NID_SYS, "Alarm expire event is delivered. alarm id is %d", alarmId);
526
527         pAlarmImpl = (_AlarmImpl*)__alarmList.GetValue(reservedAlarmId);
528         if(pAlarmImpl == null)
529         {
530                 SysLog(NID_SYS, "pAlarmImpl of reserved alarm[%d] is not found.", alarmId);
531         }
532
533         if(pValueEnum != null)
534         {
535                 SysLog(NID_SYS, "Matching Alarm Id is %d \n", alarmId);
536
537                 r = pValueEnum->MoveNext();
538                 SysTryCatch(NID_SYS,  r == E_SUCCESS, r = E_SYSTEM, r, "Alarm enum value is not valid.");
539                 pAppId = static_cast< String* >(pValueEnum->GetCurrent());
540                 alarmAppId.Append(*pAppId);
541                 r = pValueEnum->MoveNext();
542                 pPeriod = static_cast< Integer* >(pValueEnum->GetCurrent());
543                 SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, r, "Alarm enum value is not valid.");
544
545                 if(pValueEnum->MoveNext() == E_SUCCESS)
546                 {
547                         endTime = static_cast< DateTime* >(pValueEnum->GetCurrent());
548                 }
549
550                 SysLog(NID_SYS, "Reserved Alarm AppId:%ls, Period:%d\n", pAppId->GetPointer(), pPeriod->ToInt());
551
552                 if (pPeriod->ToInt() > 0)
553                 {
554                         if(endTime != null)
555                         {
556                                 DateTime currentTime;
557
558                                 SystemTime::GetCurrentTime(WALL_TIME, currentTime);
559                                 currentTime.AddMilliseconds(-1 * currentTime.GetMillisecond()); //Remove millisecond
560                                 currentTime.AddMinutes(pPeriod->ToInt());
561                                 SysLog(NID_SYS, "Next time[%d min]: %d:%d:%d:%d", pPeriod->ToInt(), currentTime.GetHour(), currentTime.GetMinute(), currentTime.GetSecond(), currentTime.GetMillisecond());
562                                 SysLog(NID_SYS, "Endtime exists %d:%d:%d:%d", endTime->GetHour(), endTime->GetMinute(), endTime->GetSecond(), endTime->GetMillisecond());
563
564                                 if (currentTime.CompareTo(*endTime) > 0)
565                                 {
566                                         SysLog(NID_SYS, "Next time is greater than end time.");
567                                         RemoveAlarmList(alarmId);
568                                         pValueEnum->Reset();
569
570                                         if(pAlarmImpl != null)
571                                         {
572                                                 pAlarmImpl->__alarmId.value = 0;
573                                         }
574                                 }
575                         }
576                 }
577                 else if (pPeriod->ToInt() == 0)
578                 {
579                         RemoveAlarmList(alarmId);
580
581                         if(pAlarmImpl != null)
582                         {
583                                 pAlarmImpl->__alarmId.value = 0;
584                         }
585                 }
586                 else
587                 {
588                         pValueEnum->Reset();
589                 }
590
591         }
592
593         ret = pthread_mutex_unlock(&__lock);
594
595         if(pAlarmImpl != null)
596         {
597                 pAlarmImpl->OnAlarmExpired(alarmId);
598         }
599
600         if(__pAlarmHashMap->ContainsKey(reservedAlarmId) == false)
601         {
602                 ret = pthread_mutex_lock(&__lock);
603                 SysLog(NID_SYS, "Remove an alarm list[%d].", reservedAlarmId.value);
604                 r = __alarmList.Remove(reservedAlarmId);
605                 ret = pthread_mutex_unlock(&__lock);
606                 SetLastResult(r);
607         }
608
609         return;
610
611 CATCH:
612         ret = pthread_mutex_unlock(&__lock);
613         SysTryReturnVoidResult(NID_SYS, ret == 0, E_SYSTEM, "It is failed to unlock mutex.");
614 }
615
616 } } // Tizen::System