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_AlarmService.cpp
20 * @brief This is the implementation file for _AlarmService class.
23 #include <unique_ptr.h>
25 #include <appfw/app.h>
27 #include <FBaseRtLibrary.h>
28 #include <FBaseSysLog.h>
30 #include <FSec_AccessController.h>
31 #include <FSys_SystemTimeImpl.h>
32 #include <FAppPkg_PackageManagerImpl.h>
33 #include "FApp_CommunicationDispatcher.h"
34 #include "FSys_AlarmService.h"
38 using namespace Tizen::App;
39 using namespace Tizen::App::Package;
40 using namespace Tizen::Io;
41 using namespace Tizen::System;
42 using namespace Tizen::Base;
43 using namespace Tizen::Base::Runtime;
44 using namespace Tizen::Base::Collection;
45 using namespace Tizen::Security;
48 const String _ALARM_ALARM_SERVICE_ID = L"osp.alarm.service";
49 const String _ALARM_SET_SINGLEALARM = L"osp.alarm.set.singlealarm";
50 const String _ALARM_SET_REPEATEDALARM = L"osp.alarm.set.repeatedalarm";
51 const String _ALARM_CANCEL = L"osp.alarm.cancel";
52 const String _ALARM_NONE = L"osp.alarm.none";
53 const String _ALARM_EXPIRY_EVENT = L"osp.alarm.expired.callback";
54 const String _ALARM_RESULT_OK = L"osp.alarm.result.ok";
55 const String _ALARM_RESULT_ERROR = L"osp.alarm.result.error";
57 static const long _SECOND_OF_MINUTE = 60;
58 static const long _ADJUST_MONTH_FOR_TM = 1;
59 static const long _ADJUST_YEAR_FOR_TM = 1900;
60 static const int _ALARM_SERVICE_ID = 0;
61 static const int _ALARM_COMMAND_ID = 1;
62 static const int _ALARM_CANCEL_ID = 2;
63 static const int _ALARM_START_TIME = 2;
64 static const int _ALARM_PERIOD = 3;
65 static const int _ALARM_END_TIME = 4;
67 static const wchar_t* ALARM_PLUGIN_LIBRARY_PATH = L"/opt/apps/aospd00043/lib/libosp-cond-alarm.so";
70 Tizen::System::_AlarmService* Tizen::System::_AlarmService::__pAlarmService = null;
71 typedef void (*OnAlarmForLaunch)(int alarmId);
73 _AlarmService::_AlarmService()
74 : _ICommunicationRequestListener()
75 , __pCommunicationDispatcher(null)
76 , __pAlarmHashMap(null)
81 __pCommunicationDispatcher = _CommunicationDispatcher::GetInstance();
82 SysTryCatch(NID_SYS, __pCommunicationDispatcher != null, r = E_SYSTEM, E_SYSTEM, "_CommunicationDispatcher initiate is failed");
84 r = __pCommunicationDispatcher->AddCommunicationEventListener(*this);
85 SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "fail to add event listener");
89 __pAlarmHashMap = new (std::nothrow) MultiHashMap();
90 SysTryCatch(NID_SYS, __pAlarmHashMap != null, r = E_SYSTEM, E_SYSTEM, "__pAlarmHashMap should not be null");
92 r = __pAlarmHashMap->Construct();
93 SysTryCatch(NID_SYS, !IsFailed(r), r= E_SYSTEM, E_SYSTEM, "[%s] Propagated.", GetErrorMessage(r));
96 //Checks for any alarm existence
103 _AlarmService::~_AlarmService()
105 result r = E_SUCCESS;
107 SysTryCatch(NID_SYS, __pCommunicationDispatcher != null, r = E_SYSTEM, E_SYSTEM, "_CommunicationDispatcher is not ready");
109 r = __pCommunicationDispatcher->RemoveCommunicationEventListener(*this);
110 SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "fail to remove event listener");
112 SysLog(NID_SYS, "Alarm Service destruct to cancel all alarms.");
114 //Cancel all the alarms before exiting
117 delete __pAlarmHashMap;
118 __pAlarmHashMap = null;
125 _AlarmService::GetInstance(void)
127 if(__pAlarmService == null)
129 __pAlarmService = new (std::nothrow) _AlarmService();
131 return __pAlarmService;
135 _AlarmService::GetId(void)
137 return _ALARM_ALARM_SERVICE_ID;
141 _AlarmService::ReserveAlarm(Tizen::Base::DateTime startTime, int period)
143 int reservedAlarmId = -1;
144 struct tm expireTime = {0,};
145 result r = E_SUCCESS;
148 char* packageName = null;
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());
153 expireTime.tm_year = startTime.GetYear() - _ADJUST_YEAR_FOR_TM;
154 expireTime.tm_mon = startTime.GetMonth() - _ADJUST_MONTH_FOR_TM;
155 expireTime.tm_mday = startTime.GetDay();
156 expireTime.tm_hour = startTime.GetHour();
157 expireTime.tm_min = startTime.GetMinute();
158 expireTime.tm_sec = startTime.GetSecond();
160 ret = service_create(&service);
161 SysTryCatch(NID_SYS, ret == SERVICE_ERROR_NONE, r = E_SYSTEM, r, "Failed to create service");
163 ret = app_get_package(&packageName);
164 SysTryCatch(NID_SYS, ret == APP_ERROR_NONE, r = E_SYSTEM, r, "Failed to get package name");
166 ret = service_set_operation(service, "osp.appsvc.operation.ALARM");
167 SysTryCatch(NID_SYS, ret == SERVICE_ERROR_NONE, r = E_SYSTEM, r, "Failed to set operation");
169 ret = service_set_package(service, packageName);
170 SysTryCatch(NID_SYS, ret == SERVICE_ERROR_NONE, r = E_SYSTEM, r, "Failed to create service for %s", packageName);
172 ret = alarm_schedule_at_date(service, &expireTime, period * _SECOND_OF_MINUTE, &reservedAlarmId);
173 SysTryCatch(NID_SYS, ret == ALARM_ERROR_NONE, r = E_SYSTEM, r, "Failed to set the Alarm time for %s", packageName);
175 SysLog(NID_SYS, "Alarm is reserved for %s. AlarmId is %d.", packageName, reservedAlarmId);
180 if(packageName != null)
182 SysLog(NID_SYS, "Fail to reserve Alarm for %s", packageName);
184 reservedAlarmId = -1;
187 if(packageName != null)
194 service_destroy(service);
197 return reservedAlarmId;
201 _AlarmService::AddAlarmList(int alarmId, int period, String appId, DateTime* endTime)
203 result r = E_SUCCESS;
205 SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
206 SysLog(NID_SYS, "New Alarm Id is added (%d, %d, %ls)", alarmId, period, appId.GetPointer());
208 Integer* reservedAlarmId = null;
209 Integer* alarmPeriod = null;
210 String* alarmAppId = null;
212 Integer* reverseAlarmId = null;
213 String* reverseAppId = null;
215 reservedAlarmId = new (std::nothrow) Integer(alarmId);
216 SysTryCatch(NID_SYS, reservedAlarmId != null, r = E_SYSTEM, E_SYSTEM, "reservedAlarmId should not be null");
218 alarmPeriod = new (std::nothrow) Integer(period);
219 SysTryCatch(NID_SYS, alarmPeriod != null, r = E_SYSTEM, E_SYSTEM, "alarmPeriod should not be null");
221 alarmAppId = new (std::nothrow) String(appId);
222 SysTryCatch(NID_SYS, alarmAppId != null, r = E_SYSTEM, E_SYSTEM, "alarmAppId should not be null");
225 r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmAppId);
226 SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm app id on the alarm list");
228 r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmPeriod);
229 SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm period on the alarm list");
233 DateTime* alarmEndTime = new DateTime(*endTime);
235 SysLog(NID_SYS, "Endtime is exist %d:%d:%d", alarmEndTime->GetHour(), alarmEndTime->GetMinute(), alarmEndTime->GetSecond());
236 r = __pAlarmHashMap->Add(*reservedAlarmId, *alarmEndTime);
237 SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm endtime on the alarm list");
241 reverseAlarmId = new (std::nothrow) Integer(alarmId);
242 SysTryCatch(NID_SYS, reverseAlarmId != null, r = E_SYSTEM, E_SYSTEM, "reverseAlarmId should not be null");
244 reverseAppId = new (std::nothrow) String(appId);
245 SysTryCatch(NID_SYS, reverseAppId != null, r = E_SYSTEM, E_SYSTEM, "reverseAppId should not be null");
247 r = __pAlarmHashMap->Add(*reverseAppId, *reverseAlarmId);
248 SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Fail to add new alarm on the alarm list");
252 if(reservedAlarmId != null)
254 __pAlarmHashMap->Remove(*reservedAlarmId, false);
255 delete reservedAlarmId;
258 if(alarmPeriod != null)
263 if(alarmAppId != null)
268 if(reverseAppId != null)
270 __pAlarmHashMap->Remove(*reverseAppId, false);
274 if(reverseAlarmId != null)
276 delete reverseAlarmId;
283 _AlarmService::RemoveAlarmList(int alarmId)
285 result r = E_SUCCESS;
286 Integer requiredAlarmId(alarmId);
287 unique_ptr<IEnumerator>pValueEnum(null);
289 SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
291 alarm_cancel(alarmId);
292 SysLog(NID_SYS, "AlarmId %d disarms the timer.", alarmId);
294 pValueEnum.reset(__pAlarmHashMap->GetValuesN(requiredAlarmId));
296 if(pValueEnum != null)
298 SysLog(NID_SYS, "Reserved Alarms are exist");
299 String* alarmAppId = null;
300 r = pValueEnum->MoveNext();
301 SysTryReturnResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "Reserved Alarm List is not valid.");
302 alarmAppId = static_cast< String* >(pValueEnum->GetCurrent());
304 if(alarmAppId != null)
306 SysLog(NID_SYS, "Alarm AppId is %S", alarmAppId->GetPointer());
307 unique_ptr<IEnumerator>pAlarmEnum(__pAlarmHashMap->GetValuesN(*alarmAppId));
308 if(pAlarmEnum != null)
310 while(pAlarmEnum->MoveNext() == E_SUCCESS)
312 Integer* reverseAlarmId = static_cast< Integer* >(pAlarmEnum->GetCurrent());
313 if(reverseAlarmId != null)
315 SysLog(NID_SYS, "Reserved Alarm is %d", reverseAlarmId->ToInt());
316 if(reverseAlarmId->ToInt() == alarmId)
318 SysLog(NID_SYS, "Remove reservedAlarmId for reverse look-up");
319 __pAlarmHashMap->Remove(*alarmAppId, *reverseAlarmId);
320 delete reverseAlarmId;
328 __pAlarmHashMap->GetCount(*alarmAppId, count);
331 SysLog(NID_SYS, "There is no reserved alarm for AppId:%S", alarmAppId->GetPointer());
332 __pAlarmHashMap->Remove(*alarmAppId, true);
336 r = __pAlarmHashMap->Remove(requiredAlarmId, true);
341 _AlarmService::RemoveAlarmList(String appId)
343 result r = E_SUCCESS;
344 Integer requiredAlarmId;
345 IEnumerator *pValueEnum = null;
347 SysTryReturnResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
348 pValueEnum = __pAlarmHashMap->GetValuesN(appId);
350 if(pValueEnum != null)
352 SysLog(NID_SYS, "Reserved Alarms are exist for AppId:%S", appId.GetPointer());
353 while(pValueEnum->MoveNext() == E_SUCCESS)
355 Integer* reverseAlarmId = static_cast< Integer* >(pValueEnum->GetCurrent());
356 if(reverseAlarmId != null)
358 SysLog(NID_SYS, "Reserved AlarmId is %d", reverseAlarmId->ToInt());
359 alarm_cancel(reverseAlarmId->ToInt());
360 __pAlarmHashMap->Remove(*reverseAlarmId, true);
365 r = __pAlarmHashMap->Remove(appId, true);
371 _AlarmService::OnRequestOccured(AppId appId, ArrayList* request, ArrayList* response)
373 result r = E_SUCCESS;
375 String* serviceId = null;
376 String* commandId = null;
377 String* result = null;
378 int reservedAlarmId = 0;
380 SysTryReturnVoidResult(NID_SYS, request != null && response != null, E_INVALID_ARG, "This is critical issue. Parameters are null");
382 serviceId = new (std::nothrow) String(_ALARM_ALARM_SERVICE_ID);
383 SysTryReturnVoidResult(NID_SYS, serviceId != null, E_SYSTEM, "This is critical issue. serviceId should not be null");
385 String* alarmCommand = null;
387 alarmCommand = (String*)request->GetAt(_ALARM_COMMAND_ID);
388 SysTryCatch(NID_SYS, alarmCommand != null, r = E_INVALID_ARG, E_INVALID_ARG, "Parameters has no command %x", alarmCommand);
390 if(*alarmCommand == _ALARM_SET_SINGLEALARM || *alarmCommand == _ALARM_SET_REPEATEDALARM)
392 SysLog(NID_SYS, "Alarm setting request");
395 if(*alarmCommand == _ALARM_SET_SINGLEALARM)
397 SysLog(NID_SYS, "Single Alarm setting request");
398 commandId = new (std::nothrow) String(_ALARM_SET_SINGLEALARM);
399 SysTryCatch(NID_SYS, commandId != null, r = E_SYSTEM, E_SYSTEM, "commandId should not be null");
403 SysLog(NID_SYS, "Repeated Alarm setting request");
404 commandId = new (std::nothrow) String(_ALARM_SET_REPEATEDALARM);
405 SysTryCatch(NID_SYS, commandId != null, r = E_SYSTEM, E_SYSTEM, "commandId should not be null");
407 String* periodArg = (String*)request->GetAt(_ALARM_PERIOD);
408 SysTryCatch(NID_SYS, commandId != null, r = E_SYSTEM, E_SYSTEM, "Period should not be null");
409 Integer::Parse(*periodArg, period);
410 SysLog(NID_SYS, "period value parse done");
414 DateTime currentTime;
417 String* startTimeArg = (String*)request->GetAt(_ALARM_START_TIME);
418 SysLog(NID_SYS, "Alarm requested start time is %S", startTimeArg->GetPointer());
420 DateTime::Parse(*startTimeArg, startTime);
421 SysLog(NID_SYS, "Starttime Parse result: %d-%d-%d %d:%d:%d", startTime.GetYear(), startTime.GetMonth(), startTime.GetDay(), startTime.GetHour(), startTime.GetMinute(), startTime.GetSecond());
423 String* endTimeArg = (String*)request->GetAt(_ALARM_END_TIME);
425 if(endTimeArg != null)
427 DateTime::Parse(*endTimeArg, endTime);
428 SysLog(NID_SYS, "Endtime Parse result: %d-%d-%d %d:%d:%d", startTime.GetYear(), startTime.GetMonth(), startTime.GetDay(), startTime.GetHour(), startTime.GetMinute(), startTime.GetSecond());
431 r = _SystemTimeImpl::GetCurrentTime(WALL_TIME, currentTime);
432 SysTryCatch(NID_SYS, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "Failed to get current Time.");
434 SysTryCatch(NID_SYS, startTime.CompareTo(currentTime) > 0, r = E_SYSTEM, E_SYSTEM, "Requested time has to be greater then current time: %d-%d-%d %d:%d:%d", currentTime.GetYear(), currentTime.GetMonth(), currentTime.GetDay(), currentTime.GetHour(), currentTime.GetMinute(), currentTime.GetSecond());
436 reservedAlarmId = ReserveAlarm(startTime, period);
438 SysLog(NID_SYS, "Reserved AppId %S", appId.GetPointer());
439 if(reservedAlarmId != -1)
441 if(endTimeArg == null)
443 r = AddAlarmList(reservedAlarmId, period, appId, null);
447 r = AddAlarmList(reservedAlarmId, period, appId, &endTime);
456 else if(*alarmCommand == _ALARM_CANCEL)
458 SysLog(NID_SYS, "Alarm Cancel request");
462 commandId = new (std::nothrow) String(_ALARM_CANCEL);
463 SysTryCatch(NID_SYS, commandId != null, r = E_SYSTEM, E_SYSTEM, "commandId should not be null");
465 String* removableAlarmId = (String*)request->GetAt(_ALARM_CANCEL_ID);
467 r = Integer::Parse(*removableAlarmId, alarmId);
468 SysTryCatch(NID_SYS, r == E_SUCCESS, r = E_SYSTEM, r, "Failed to parse alarm id");
470 r = RemoveAlarmList(alarmId);
471 SysTryCatch(NID_SYS, r == E_SUCCESS, r, r, "Failed to parse alarm id");
476 commandId = new (std::nothrow) String(_ALARM_NONE);
477 SysTryCatch(NID_SYS, commandId != null, r = E_SYSTEM, E_SYSTEM, "commandId should not be null");
482 response->Add(*serviceId);
486 result = new (std::nothrow) String(_ALARM_RESULT_OK);
487 response->Add(*commandId);
488 response->Add(*result);
489 if(reservedAlarmId != -1)
491 String* tempAlarmId = new (std::nothrow) String();
492 tempAlarmId->Append(reservedAlarmId);
493 response->Add(tempAlarmId);
496 else if(r == E_SYSTEM)
498 result = new (std::nothrow) String(_ALARM_RESULT_ERROR);
499 response->Add(*commandId);
500 response->Add(*result);
502 else if(r == E_OBJ_NOT_FOUND)
504 result = new (std::nothrow) String(_ALARM_RESULT_ERROR);
505 response->Add(*commandId);
506 response->Add(*result);
510 result = new (std::nothrow) String(_ALARM_RESULT_ERROR);
511 if(commandId == null)
513 commandId = new (std::nothrow) String(_ALARM_NONE);
515 response->Add(*commandId);
516 response->Add(*result);
523 _AlarmService::OnAlarmExpired(int alarmId)
525 result r = E_SUCCESS;
526 String* pAppId = null;
527 Integer* pPeriod = null;
528 unique_ptr<IEnumerator> pValueEnum(null);
529 Integer requiredAlarmId(alarmId);
530 DateTime* endTime = null;
532 SysTryReturnVoidResult(NID_SYS, __pAlarmHashMap != null, E_SYSTEM, "Alarm list does not initialized");
534 pValueEnum.reset(__pAlarmHashMap->GetValuesN(requiredAlarmId));
536 if(pValueEnum != null)
539 SysLog(NID_SYS, "Matching Alarm Id is %d \n", alarmId);
540 r = pValueEnum->MoveNext();
541 SysTryReturnVoidResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "Alarm enum value is not valid.");
542 pAppId = static_cast< String* >(pValueEnum->GetCurrent());
543 alarmAppId.Append(*pAppId);
544 r = pValueEnum->MoveNext();
545 pPeriod = static_cast< Integer* >(pValueEnum->GetCurrent());
546 SysTryReturnVoidResult(NID_SYS, r == E_SUCCESS, E_SYSTEM, "Alarm enum value is not valid.");
548 if(pValueEnum->MoveNext() == E_SUCCESS)
550 endTime = static_cast< DateTime* >(pValueEnum->GetCurrent());
553 SysLog(NID_SYS, "Reserved Alarm AppId:%ls, Period:%d\n", pAppId->GetPointer(), pPeriod->ToInt());
555 if (pPeriod->ToInt() > 0)
559 DateTime currentTime;
560 _SystemTimeImpl::GetCurrentTime(WALL_TIME, currentTime);
561 SysLog(NID_SYS, "Current time: %d:%d:%d", currentTime.GetHour(), currentTime.GetMinute(), currentTime.GetSecond());
562 currentTime.AddMinutes(pPeriod->ToInt());
563 SysLog(NID_SYS, "Next time: %d:%d:%d", currentTime.GetHour(), currentTime.GetMinute(), currentTime.GetSecond());
564 SysLog(NID_SYS, "Endtime is exist %d:%d:%d", endTime->GetHour(), endTime->GetMinute(), endTime->GetSecond());
566 if (currentTime.CompareTo(*endTime) >= 0)
568 SysLog(NID_SYS, "Next time is greater then end time.");
569 RemoveAlarmList(alarmId);
574 else if (pPeriod->ToInt() == 0)
576 RemoveAlarmList(alarmId);
584 SysLog(NID_SYS, "Alarm Id match and need to call IPC callback. (%S)", alarmAppId.GetPointer());
586 String serviceId(_ALARM_ALARM_SERVICE_ID);
587 String commandId(_ALARM_EXPIRY_EVENT);
588 String expiredAlarmId(requiredAlarmId.ToString());
591 data.Add(expiredAlarmId);
593 r = __pCommunicationDispatcher->SendData(alarmAppId, data);
594 SysLog(NID_SYS, "Alarm expire event is delivered to %S with %S, Result: %s",alarmAppId.GetPointer(), expiredAlarmId.GetPointer(), GetErrorMessage(r));
598 SysLog(NID_SYS, "AlarmObj2 entry for alarm id not found: %d", alarmId);
600 //For conditional launch
601 SysLog(NID_SYS, "Start to load external lib");
603 OnAlarmForLaunch pOnAlarmForLaunch = null;
604 r = lib.Construct(ALARM_PLUGIN_LIBRARY_PATH);
608 SysLog(NID_SYS, "Open alarm condition library");
609 pOnAlarmForLaunch = (OnAlarmForLaunch)lib.GetProcAddress(L"OnAlarmForLaunch");
610 if(pOnAlarmForLaunch != null)
612 SysLog(NID_SYS, "Function is found");
613 pOnAlarmForLaunch(alarmId);
614 SysLog(NID_SYS, "Requested to check current alarm id to AlarmConditionHandler %d", alarmId);
618 SysLog(NID_SYS, "Fail to find alarm function");
623 SysLog(NID_SYS, "Fail to open alarm condition library");
629 _AlarmService::OnApplicationTerminated(const AppId& appId, _AppType type)
631 SysLog(NID_SYS, "Terminated AppId %S", appId.GetPointer());
632 RemoveAlarmList(appId);