2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FSys_AlarmManager.cpp
20 * @brief This is the implementation file for _AlarmManager class.
23 #include <unique_ptr.h>
24 #include <appfw/app.h>
26 #include <appsvc/appsvc.h>
28 #include <FBaseSysLog.h>
29 #include <FSysSystemTime.h>
31 #include <FBase_NativeError.h>
33 #include <FBase_StringConverter.h>
35 #include "inc/FSys_AlarmManager.h"
37 using namespace Tizen::Base;
38 using namespace Tizen::Base::Runtime;
39 using namespace Tizen::Base::Collection;
40 using namespace Tizen::Io;
42 namespace Tizen { namespace System
44 static const long _SECOND_OF_MINUTE = 60;
46 _AlarmManager* _AlarmManager::pAlarmManager = null;
48 _AlarmManager::_AlarmManager()
49 : __pAlarmHashMap(null)
52 __alarmList.Construct();
56 __pAlarmHashMap = new (std::nothrow) MultiHashMap();
57 SysTryCatch(NID_SYS, __pAlarmHashMap != null, r = E_SYSTEM, E_SYSTEM, "__pAlarmHashMap should not be null");
59 r = __pAlarmHashMap->Construct();
60 SysTryCatch(NID_SYS, r == E_SUCCESS, r= E_SYSTEM, E_SYSTEM, "[%s] Propagated.", GetErrorMessage(r));
63 //Checks for any alarm existence
70 _AlarmManager::~_AlarmManager()
72 delete __pAlarmHashMap;
73 __pAlarmHashMap = null;
75 //Cancel all the alarms before exiting
80 _AlarmManager::GetInstance(void)
82 if(pAlarmManager == null)
84 pAlarmManager = new (std::nothrow) _AlarmManager();
90 _AlarmManager::ReserveAlarm(Tizen::Base::String appId, Tizen::Base::DateTime startTime, int period)
92 int reservedAlarmId = -1;
98 SysLog(NID_SYS, "Reserve time is %d/%d/%d %d:%d:%d", startTime.GetYear(), startTime.GetMonth(), startTime.GetDay(), startTime.GetHour(), startTime.GetMinute(), startTime.GetSecond());
100 bundle* pBundle = null;
101 alarm_entry_t* pAlarmInfo = null;
102 alarm_date_t expireTime = {0,};
104 std::unique_ptr<char[]> pId(_StringConverter::CopyToCharArrayN(appId));
106 pBundle = bundle_create();
107 SysTryCatch(NID_SYS, pBundle != null, r = E_SYSTEM, r, "It is failed to create bundle");
109 ret = appsvc_set_operation(pBundle,"osp.operation.ALARM");
110 SysTryCatch(NID_SYS, ret == SERVICE_ERROR_NONE, r = E_SYSTEM, r, "It is failed to set operation");
112 ret = appsvc_set_appid(pBundle, (const char*)(pId.get()));
113 SysTryCatch(NID_SYS, ret == SERVICE_ERROR_NONE, r = E_SYSTEM, r, "It is failed to set appid for %ls", appId.GetPointer());
115 pAlarmInfo = alarmmgr_create_alarm();
116 SysTryCatch(NID_SYS, pAlarmInfo != null, r = E_SYSTEM, r, "It is failed to create alarm entry");
118 expireTime.year = startTime.GetYear();
119 expireTime.month = startTime.GetMonth();
120 expireTime.day = startTime.GetDay();
121 expireTime.hour = startTime.GetHour();
122 expireTime.min = startTime.GetMinute();
123 expireTime.sec = startTime.GetSecond();
125 ret = alarmmgr_set_time(pAlarmInfo, expireTime);
126 SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "It is failed to set new alarm time");
130 SysLog(NID_SYS, "It is repeated alarm and period time is %d minutes", period);
131 ret = alarmmgr_set_repeat_mode(pAlarmInfo, ALARM_REPEAT_MODE_REPEAT, period * _SECOND_OF_MINUTE);
132 SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "It is failed to set repeat mode");
135 ret = alarmmgr_set_type(pAlarmInfo, ALARM_TYPE_NOLAUNCH);
136 SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "It is failed to set repeat mode");
138 ret = alarmmgr_add_alarm_appsvc_with_localtime(pAlarmInfo,(void *)pBundle, &reservedAlarmId);
139 SysTryCatch(NID_SYS, ret == ALARMMGR_RESULT_SUCCESS, r = E_SYSTEM, r, "Alarm creation failed!!! Alrmgr error code is %d", ret);
144 reservedAlarmId = -1;
146 if(pAlarmInfo != null)
148 alarmmgr_free_alarm(pAlarmInfo);
153 bundle_free(pBundle);
156 return reservedAlarmId;
160 _AlarmManager::AddAlarmList(int alarmId, int period, String appId, DateTime* endTime)
162 result r = E_SUCCESS;
164 SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
165 SysLog(NID_SYS, "New Alarm Id is added (%d, %d, %ls)", alarmId, period, appId.GetPointer());
167 Integer* reservedAlarmId = null;
168 Integer* alarmPeriod = null;
169 String* alarmAppId = null;
171 Integer* reverseAlarmId = null;
172 String* reverseAppId = null;
174 reservedAlarmId = new (std::nothrow) Integer(alarmId);
175 SysTryCatch(NID_SYS, reservedAlarmId != null, r = E_SYSTEM, E_SYSTEM, "reservedAlarmId should not be null");
177 alarmPeriod = new (std::nothrow) Integer(period);
178 SysTryCatch(NID_SYS, alarmPeriod != null, r = E_SYSTEM, E_SYSTEM, "alarmPeriod should not be null");
180 alarmAppId = new (std::nothrow) String(appId);
181 SysTryCatch(NID_SYS, alarmAppId != null, r = E_SYSTEM, E_SYSTEM, "alarmAppId should not be null");
184 r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmAppId);
185 SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm app id on the alarm list");
187 r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmPeriod);
188 SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm period on the alarm list");
192 DateTime* alarmEndTime = new DateTime(*endTime);
194 SysLog(NID_SYS, "Endtime exists %d:%d:%d", alarmEndTime->GetHour(), alarmEndTime->GetMinute(), alarmEndTime->GetSecond());
195 r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmEndTime);
196 SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm endtime on the alarm list");
200 reverseAlarmId = new (std::nothrow) Integer(alarmId);
201 SysTryCatch(NID_SYS, reverseAlarmId != null, r = E_SYSTEM, E_SYSTEM, "reverseAlarmId should not be null");
203 reverseAppId = new (std::nothrow) String(appId);
204 SysTryCatch(NID_SYS, reverseAppId != null, r = E_SYSTEM, E_SYSTEM, "reverseAppId should not be null");
206 r = __pAlarmHashMap->Add(*reverseAppId, *reverseAlarmId);
207 SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm on the alarm list");
212 if(reservedAlarmId != null)
214 __pAlarmHashMap->Remove(*reservedAlarmId, false);
215 delete reservedAlarmId;
218 if(alarmPeriod != null)
223 if(alarmAppId != null)
228 if(reverseAppId != null)
230 __pAlarmHashMap->Remove(*reverseAppId, false);
234 if(reverseAlarmId != null)
236 delete reverseAlarmId;
243 _AlarmManager::RemoveAlarmList(int alarmId)
245 result r = E_SUCCESS;
246 Integer requiredAlarmId(alarmId);
247 std::unique_ptr<IEnumerator>pValueEnum(null);
249 SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
251 alarm_cancel(alarmId);
252 SysLog(NID_SYS, "AlarmId %d disarms the timer.", alarmId);
254 pValueEnum.reset(__pAlarmHashMap->GetValuesN(requiredAlarmId));
256 if(pValueEnum != null)
258 SysLog(NID_SYS, "Reserved Alarms are exist");
259 String* alarmAppId = null;
260 r = pValueEnum->MoveNext();
261 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "Reserved Alarm List is not valid.");
262 alarmAppId = static_cast< String* >(pValueEnum->GetCurrent());
264 if(alarmAppId != null)
266 SysLog(NID_SYS, "Alarm AppId is %S", alarmAppId->GetPointer());
267 std::unique_ptr<IEnumerator>pAlarmEnum(__pAlarmHashMap->GetValuesN(*alarmAppId));
268 if(pAlarmEnum != null)
270 while(pAlarmEnum->MoveNext() == E_SUCCESS)
272 Integer* reverseAlarmId = static_cast< Integer* >(pAlarmEnum->GetCurrent());
273 if(reverseAlarmId != null)
275 SysLog(NID_SYS, "Reserved Alarm is %d", reverseAlarmId->ToInt());
276 if(reverseAlarmId->ToInt() == alarmId)
278 SysLog(NID_SYS, "Remove reservedAlarmId for reverse look-up");
279 __pAlarmHashMap->Remove(*alarmAppId, *reverseAlarmId);
280 delete reverseAlarmId;
288 __pAlarmHashMap->GetCount(*alarmAppId, count);
291 SysLog(NID_SYS, "There is no more reserved alarm for AppId:%S", alarmAppId->GetPointer());
292 __pAlarmHashMap->Remove(*alarmAppId, true);
296 r = __pAlarmHashMap->Remove(requiredAlarmId, true);
302 _AlarmManager::RemoveAlarmList(String appId)
304 result r = E_SUCCESS;
305 Integer requiredAlarmId;
306 IEnumerator *pValueEnum = null;
308 SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
309 pValueEnum = __pAlarmHashMap->GetValuesN(appId);
311 if(pValueEnum != null)
313 SysLog(NID_SYS, "Reserved Alarms are exist for AppId:%S", appId.GetPointer());
314 while(pValueEnum->MoveNext() == E_SUCCESS)
316 Integer* reverseAlarmId = static_cast< Integer* >(pValueEnum->GetCurrent());
317 if(reverseAlarmId != null)
319 SysLog(NID_SYS, "Reserved AlarmId is %d", reverseAlarmId->ToInt());
320 alarm_cancel(reverseAlarmId->ToInt());
321 __pAlarmHashMap->Remove(*reverseAlarmId, true);
326 r = __pAlarmHashMap->Remove(appId, true);
332 _AlarmManager::RegisterAlarm(_AlarmImpl* pAlarmImpl)
334 SysTryReturnResult(NID_SYS, pAlarmImpl != null, E_INVALID_ARG, "There is no alarmImpl.");
335 Integer alarmId(pAlarmImpl->__alarmId.value);
336 SysTryReturnResult(NID_SYS, __alarmList.ContainsKey(alarmId) == false, E_OBJ_ALREADY_EXIST, "Required Alarm[%d] is already registered.", pAlarmImpl->__alarmId.value);
338 result r = E_SUCCESS;
339 ArrayList requestMessage;
340 ArrayList responseMessage;
347 int period = pAlarmImpl->GetPeriod();
349 DateTime currentTime;
350 DateTime startTime = pAlarmImpl->GetStartTime();
351 const DateTime* pEndTime = pAlarmImpl->GetEndTime();
355 startTime.AddMilliseconds(-1 * startTime.GetMillisecond());
356 r = SystemTime::GetCurrentTime(WALL_TIME, currentTime);
357 currentTime.AddMilliseconds(-1 * currentTime.GetMillisecond());
359 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to get current time.");
360 SysTryReturnResult(NID_SYS, DateTime::Compare(currentTime, startTime) < 0, E_INVALID_ARG, "Designated start time has to be greater than current time.");
361 SysTryReturnResult(NID_SYS, period > -1, E_INVALID_ARG, "Period has to greater than -1");
366 endTime.AddMilliseconds(-1 * endTime.GetMillisecond());
368 SysTryReturnResult(NID_SYS, DateTime::Compare(startTime, endTime) < 0, E_INVALID_ARG, "Designated end time is less than start time.");
370 //End Alarm validation check
372 Tizen::App::App* pApp = Tizen::App::App::GetInstance();
373 SysTryReturnResult(NID_SYS, pApp != null, E_SYSTEM, "[%s] A system error has been occurred. App::GetInstance() failed.", GetErrorMessage(E_SYSTEM));
374 appId = pApp->GetAppId();
376 String* result = null;
377 int reservedAlarmId = 0;
379 SysLog(NID_SYS, "Alarm setting request");
381 reservedAlarmId = ReserveAlarm(appId, startTime, period);
382 SysTryReturnResult(NID_SYS, reservedAlarmId != -1, E_SYSTEM, "It is failed to register alarm.");
384 SysLog(NID_SYS, "Reserved AppId %ls, alarmId: %d", appId.GetPointer(), reservedAlarmId);
388 r = AddAlarmList(reservedAlarmId, period, appId, null);
392 r = AddAlarmList(reservedAlarmId, period, appId, (DateTime*)(&endTime));
394 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to add new alarm on the alarm list.");
396 pAlarmImpl->__alarmId.value = reservedAlarmId;
397 r = __alarmList.Add(&(pAlarmImpl->__alarmId), pAlarmImpl);
403 _AlarmManager::UnregisterAlarm(_AlarmImpl* pAlarmImpl)
405 SysLog(NID_SYS, "Alarm Cancel request");
407 result r = E_SUCCESS;
408 SysTryReturnResult(NID_SYS, pAlarmImpl != null, E_INVALID_ARG, "There is no alarmImpl.");
410 Integer alarmId(pAlarmImpl->__alarmId.value);
411 SysTryReturnResult(NID_SYS, __alarmList.ContainsKey(alarmId) == true, E_OBJ_NOT_FOUND, "There is no registered alarm.");
413 r = __alarmList.Remove(alarmId);
414 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to remove reserved alarmImpl instance.");
416 r = RemoveAlarmList(alarmId.ToInt());
417 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to remove reserved alarm list.");
423 _AlarmManager::UpdateAlarm(_AlarmImpl* pAlarmImpl)
425 result r = E_SUCCESS;
426 SysTryReturnResult(NID_SYS, pAlarmImpl != null, E_INVALID_ARG, "There is no alarmImpl.");
428 Integer alarmId(pAlarmImpl->__alarmId.value);
429 SysTryReturnResult(NID_SYS, __alarmList.ContainsKey(alarmId) == true, E_OBJ_NOT_FOUND, "There is no registered alarm.");
431 r = UnregisterAlarm(pAlarmImpl);
432 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "It is failed to unregister reserved alarm list.");
434 r = RegisterAlarm(pAlarmImpl);
439 _AlarmManager::OnAlarmExpired(int alarmId)
441 result r = E_SUCCESS;
442 String* pAppId = null;
443 Integer* pPeriod = null;
444 std::unique_ptr<IEnumerator> pValueEnum(null);
445 Integer reservedAlarmId(alarmId);
446 DateTime* endTime = null;
448 SysTryReturnVoidResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
449 pValueEnum.reset(__pAlarmHashMap->GetValuesN(reservedAlarmId));
451 SysLog(NID_SYS, "Alarm expire event is delivered. alarm id is %d", alarmId);
453 _AlarmImpl* pAlarmImpl = (_AlarmImpl*)__alarmList.GetValue(reservedAlarmId);
454 if(pAlarmImpl == null)
456 SysLog(NID_SYS, "pAlarmImpl of reserved alarm[%d] is not found.", alarmId);
459 if(pValueEnum != null)
462 SysLog(NID_SYS, "Matching Alarm Id is %d \n", alarmId);
463 r = pValueEnum->MoveNext();
464 SysTryReturnVoidResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "Alarm enum value is not valid.");
465 pAppId = static_cast< String* >(pValueEnum->GetCurrent());
466 alarmAppId.Append(*pAppId);
467 r = pValueEnum->MoveNext();
468 pPeriod = static_cast< Integer* >(pValueEnum->GetCurrent());
469 SysTryReturnVoidResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "Alarm enum value is not valid.");
471 if(pValueEnum->MoveNext() == E_SUCCESS)
473 endTime = static_cast< DateTime* >(pValueEnum->GetCurrent());
476 SysLog(NID_SYS, "Reserved Alarm AppId:%ls, Period:%d\n", pAppId->GetPointer(), pPeriod->ToInt());
478 if (pPeriod->ToInt() > 0)
482 DateTime currentTime;
484 SystemTime::GetCurrentTime(WALL_TIME, currentTime);
485 currentTime.AddMilliseconds(-1 * currentTime.GetMillisecond()); //Remove millisecond
486 currentTime.AddMinutes(pPeriod->ToInt());
487 SysLog(NID_SYS, "Next time[%d min]: %d:%d:%d:%d", pPeriod->ToInt(), currentTime.GetHour(), currentTime.GetMinute(), currentTime.GetSecond(), currentTime.GetMillisecond());
488 SysLog(NID_SYS, "Endtime exists %d:%d:%d:%d", endTime->GetHour(), endTime->GetMinute(), endTime->GetSecond(), endTime->GetMillisecond());
490 if (currentTime.CompareTo(*endTime) > 0)
492 SysLog(NID_SYS, "Next time is greater than end time.");
493 RemoveAlarmList(alarmId);
496 if(pAlarmImpl != null)
498 pAlarmImpl->__alarmId.value = 0;
503 else if (pPeriod->ToInt() == 0)
505 RemoveAlarmList(alarmId);
507 if(pAlarmImpl != null)
509 pAlarmImpl->__alarmId.value = 0;
518 if(pAlarmImpl != null)
520 pAlarmImpl->OnAlarmExpired(alarmId);
523 if(__pAlarmHashMap->ContainsKey(reservedAlarmId) == false)
525 SysLog(NID_SYS, "Remove an alarm list[%d].", reservedAlarmId.value);
526 r = __alarmList.Remove(reservedAlarmId);