2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "alarm_manager.h"
21 #include <app_alarm.h>
22 #include <app_control_internal.h>
24 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
25 #include <notification_internal.h>
28 #include "common/converter.h"
29 #include "common/logger.h"
30 #include "common/scope_exit.h"
31 #include "common/tools.h"
33 #include "alarm_instance.h"
34 #include "alarm_utils.h"
36 #include "notification/common_notification.h"
37 #include "notification/status_notification.h"
38 #include "notification/user_notification.h"
40 using namespace common;
41 using namespace common::tools;
47 const int kDateSize = 22; //"yyy mm dd hh mm ss dd" e.g 115 11 28 11 25 50 -1
48 const std::string kPrivilegeAlarm = "http://tizen.org/privilege/alarm";
49 const std::string kPrivilegeNotification = "http://tizen.org/privilege/notification";
51 const std::string kAlarmRelative = "AlarmRelative";
52 const std::string kAlarmAbsolute = "AlarmAbsolute";
54 const char* kAlarmAbsoluteRecurrenceTypeKey = "RECURRENCE";
55 const char* kAlarmAbsoluteReccurrenceTypeInterval = "INTERVAL";
56 const char* kAlarmAbsoluteReccurrenceTypeByDayValue = "BYDAYVALUE";
57 const char* kAlarmAbsoluteRecurrenceTypeNone = "NONE";
58 const char* kAlarmAbsoluteDateKey = "DATE";
60 const char* kAlarmKeyType = "TYPE";
62 const char* kAlarmTypeValueAbsolute = "ABSOLUTE";
63 const char* kAlarmTypeValueRelative = "RELATIVE";
65 const char* kAlarmRelativeDelayKey = "RELATIVE_DELAY";
68 AlarmManager::AlarmManager() {
72 AlarmManager::~AlarmManager() {
76 void AlarmManager::Add(const picojson::value& args, picojson::object& out) {
78 CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
80 if (!args.contains("alarm")) {
81 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
85 const picojson::object& alarm = args.get("alarm").get<picojson::object>();
87 std::string alarm_type;
88 if (args.contains("type")) {
89 alarm_type = args.get("type").get<std::string>();
93 if (args.contains("applicationId")) {
94 app_id = args.get("applicationId").get<std::string>();
97 app_control_h app_control = nullptr;
99 app_control_destroy(app_control);
102 if (args.contains("appControl") && args.get("appControl").is<picojson::object>()) {
103 PlatformResult result =
104 util::AppControlToService(args.get("appControl").get<picojson::object>(), &app_control);
106 LogAndReportError(result, &out, ("Failed: util::AppControlToService"));
110 app_control_create(&app_control);
111 app_control_set_operation(app_control, APP_CONTROL_OPERATION_DEFAULT);
114 app_control_set_app_id(app_control, app_id.c_str());
120 picojson::value result = picojson::value(picojson::object());
121 picojson::object& result_obj = result.get<picojson::object>();
123 if (kAlarmRelative == alarm_type) {
124 app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueRelative);
126 const auto it_delay = alarm.find("delay");
127 const auto it_period = alarm.find("period");
129 if (alarm.end() == it_delay || alarm.end() == it_period || !it_delay->second.is<double>()) {
130 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
134 int delay = static_cast<int>(it_delay->second.get<double>());
136 if (it_period->second.is<double>()) {
137 period = static_cast<int>(it_period->second.get<double>());
140 bool isPeriodSet = false;
141 if (args.contains("isPeriodSet")) {
142 isPeriodSet = args.get("isPeriodSet").get<bool>();
145 std::string delay_str = std::to_string(delay);
146 int ret_app = app_control_add_extra_data(app_control, kAlarmRelativeDelayKey, delay_str.c_str());
147 if (APP_CONTROL_ERROR_NONE != ret_app) {
149 PlatformResult(ErrorCode::UNKNOWN_ERR, "Fail to add data from app_control."), &out,
150 ("Fail to add data from app_control: %d (%s)", ret_app, get_error_message(ret_app)));
154 int ret = ALARM_ERROR_NONE;
156 ret = alarm_schedule_once_after_delay(app_control, delay, &alarm_id);
158 ret = alarm_schedule_after_delay(app_control, delay, period, &alarm_id);
160 if (ALARM_ERROR_NONE != ret) {
161 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while add alarm to server."),
163 ("Error while add alarm to server: %d (%s)", ret, get_error_message(ret)));
167 ret = alarm_get_scheduled_period(alarm_id, &period);
168 if (ALARM_ERROR_NONE != ret) {
169 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out,
170 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
174 result_obj.insert(std::make_pair("period", picojson::value(std::to_string(period))));
177 app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueAbsolute);
179 const auto it_period = alarm.find("period");
180 const auto it_daysOfTheWeek = alarm.find("daysOfTheWeek");
182 long long int seconds = 0;
183 if (args.contains("seconds")) {
184 seconds = atoll(args.get("seconds").get<std::string>().c_str());
187 time_t second = seconds / 1000;
188 struct tm start_date = {0};
191 if (nullptr == localtime_r(&second, &start_date)) {
192 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Invalid date."), &out);
198 char str_date[kDateSize];
200 snprintf(str_date, sizeof(str_date), "%d %d %d %d %d %d %d", start_date.tm_year,
201 start_date.tm_mon, start_date.tm_mday, start_date.tm_hour, start_date.tm_min,
202 start_date.tm_sec, start_date.tm_isdst);
204 app_control_add_extra_data(app_control, kAlarmAbsoluteDateKey, str_date);
207 if (alarm.end() != it_period && it_period->second.is<double>()) {
208 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
209 kAlarmAbsoluteReccurrenceTypeInterval);
210 period = static_cast<int>(it_period->second.get<double>());
211 ret = alarm_schedule_at_date(app_control, &start_date, period, &alarm_id);
212 if (ALARM_ERROR_NONE != ret) {
213 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Adding alarm to server failed."),
215 ("Adding alarm to server failed: %d (%s)", ret, get_error_message(ret)));
219 ret = alarm_get_scheduled_period(alarm_id, &period);
220 result_obj.insert(std::make_pair("period", picojson::value(std::to_string(period))));
221 } else if (alarm.end() != it_daysOfTheWeek && it_daysOfTheWeek->second.is<picojson::array>() &&
222 !(it_daysOfTheWeek->second.get<picojson::array>()).empty()) {
223 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
224 kAlarmAbsoluteReccurrenceTypeByDayValue);
225 const picojson::array& days_of_the_week = it_daysOfTheWeek->second.get<picojson::array>();
226 int repeat_value = 0;
227 PlatformResult result = util::ArrayDaysToMask(days_of_the_week, &repeat_value);
229 LogAndReportError(PlatformResult(result.error_code(), result.message()), &out);
232 ret = alarm_schedule_with_recurrence_week_flag(app_control, &start_date, repeat_value,
235 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
236 kAlarmAbsoluteRecurrenceTypeNone);
237 ret = alarm_schedule_at_date(app_control, &start_date, 0, &alarm_id);
240 if (ALARM_ERROR_NONE != ret) {
241 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Adding alarm to server failed."),
243 ("Adding alarm to server failed: %d (%s)", ret, get_error_message(ret)));
248 result_obj.insert(std::make_pair("id", picojson::value(std::to_string(alarm_id))));
249 ReportSuccess(result, out);
252 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
253 void AlarmManager::AddAlarmNotification(const picojson::value& args, picojson::object& out) {
254 using namespace extension::notification;
256 CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
257 CHECK_PRIVILEGE_ACCESS(kPrivilegeNotification, &out);
259 if (!args.contains("alarm") || !args.contains("notification")) {
260 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
265 const picojson::object& alarm = args.get("alarm").get<picojson::object>();
267 std::string alarm_type;
268 if (args.contains("type")) {
269 alarm_type = args.get("type").get<std::string>();
272 notification_h notification_handle = nullptr;
273 app_control_h app_control = nullptr;
276 notification_free(notification_handle);
277 app_control_destroy(app_control);
280 using namespace std::placeholders;
281 GetHandleFromJsonFun impl{};
282 if (args.contains("newImpl") && args.get("newImpl").is<bool>() &&
283 args.get("newImpl").get<bool>()) {
284 LoggerD("New implementation");
285 impl = std::bind(&UserNotification::GetNotiHandleFromJson, _1, _2, _3);
287 LoggerW("Deprecated object used");
288 impl = std::bind(&StatusNotification::GetNotiHandleFromJson, _1, _2, _3);
291 PlatformResult platform_result = impl(args.get("notification"), false, ¬ification_handle);
292 if (!platform_result) {
293 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, platform_result.message().c_str()),
296 platform_result = CommonNotification::GetAppControl(notification_handle, &app_control);
298 if (!platform_result) {
300 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
306 if (kAlarmRelative == alarm_type) {
307 ret = app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueRelative);
308 if (ret != APP_CONTROL_ERROR_NONE) {
310 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
311 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
315 const auto it_period = alarm.find("period");
316 const auto it_delay = alarm.find("delay");
318 if (alarm.end() == it_delay || alarm.end() == it_period || !it_delay->second.is<double>()) {
319 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
324 int delay = static_cast<int>(it_delay->second.get<double>());
326 std::string delay_str = std::to_string(delay);
327 ret = app_control_add_extra_data(app_control, kAlarmRelativeDelayKey, delay_str.c_str());
328 if (APP_CONTROL_ERROR_NONE != ret) {
330 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
331 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
335 platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
337 if (!platform_result) {
339 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
343 if (it_period->second.is<double>()) {
344 period = static_cast<int>(it_period->second.get<double>());
347 bool isPeriodSet = false;
348 if (args.contains("isPeriodSet")) {
349 isPeriodSet = args.get("isPeriodSet").get<bool>();
353 ret = alarm_schedule_noti_once_after_delay(notification_handle, delay, &alarm_id);
355 ret = alarm_schedule_noti_after_delay(notification_handle, delay, period, &alarm_id);
358 if (alarm.find("period")->second.is<double>()) {
359 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR,
360 "AlarmAbsolute constructed by deprecated constructor."),
365 ret = app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueAbsolute);
366 if (APP_CONTROL_ERROR_NONE != ret) {
368 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
369 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
373 const auto it_daysOfTheWeek = alarm.find("daysOfTheWeek");
374 long long int milliseconds = 0;
376 if (args.contains("milliseconds")) {
377 milliseconds = strtoll(args.get("milliseconds").get<std::string>().c_str(), nullptr, 10);
380 time_t second = milliseconds / 1000;
381 struct tm start_date = {0};
384 if (nullptr == localtime_r(&second, &start_date)) {
385 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Invalid date."), &out);
391 char str_date[kDateSize];
393 snprintf(str_date, sizeof(str_date), "%d %d %d %d %d %d %d", start_date.tm_year,
394 start_date.tm_mon, start_date.tm_mday, start_date.tm_hour, start_date.tm_min,
395 start_date.tm_sec, start_date.tm_isdst);
397 ret = app_control_add_extra_data(app_control, kAlarmAbsoluteDateKey, str_date);
398 if (APP_CONTROL_ERROR_NONE != ret) {
400 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
401 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
405 if (alarm.end() != it_daysOfTheWeek && it_daysOfTheWeek->second.is<picojson::array>() &&
406 !(it_daysOfTheWeek->second.get<picojson::array>()).empty()) {
407 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
408 kAlarmAbsoluteReccurrenceTypeByDayValue);
410 const picojson::array& days_of_the_week = it_daysOfTheWeek->second.get<picojson::array>();
411 int repeat_value = 0;
412 util::ArrayDaysToMask(days_of_the_week, &repeat_value);
414 platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
415 if (!platform_result) {
417 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
420 ret = alarm_schedule_noti_with_recurrence_week_flag(notification_handle, &start_date,
421 repeat_value, &alarm_id);
423 ret = app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
424 kAlarmAbsoluteRecurrenceTypeNone);
425 if (APP_CONTROL_ERROR_NONE != ret) {
427 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
428 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
432 platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
433 if (!platform_result) {
435 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
438 ret = alarm_schedule_noti_once_at_date(notification_handle, &start_date, &alarm_id);
442 if (ALARM_ERROR_NONE != ret) {
443 if (ALARM_ERROR_INVALID_TIME == ret || ALARM_ERROR_INVALID_DATE == ret ||
444 ALARM_ERROR_INVALID_PARAMETER == ret) {
445 platform_result = PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid data.");
447 platform_result = PlatformResult(ErrorCode::ABORT_ERR, "Error while adding alarm to server.");
450 LogAndReportError(platform_result, &out,
451 ("Error while add alarm to server: %d (%s)", ret, get_error_message(ret)));
455 picojson::value result = picojson::value(picojson::object());
456 picojson::object& result_obj = result.get<picojson::object>();
458 if (alarm_type == kAlarmRelative) {
460 ret = alarm_get_scheduled_period(alarm_id, &period);
461 if (ALARM_ERROR_NONE != ret) {
462 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out,
463 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
467 result_obj.insert(std::make_pair("period", picojson::value(std::to_string(period))));
471 result_obj.insert(std::make_pair("id", picojson::value(std::to_string(alarm_id))));
472 ReportSuccess(result, out);
476 void AlarmManager::Remove(const picojson::value& args, picojson::object& out) {
478 CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
482 if (args.contains("id") && args.get("id").is<double>()) {
483 id = static_cast<int>(args.get("id").get<double>());
487 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid id."), &out,
488 ("id is wrong: %d", id));
492 int ret = alarm_cancel(id);
493 if (ALARM_ERROR_NONE == ret) {
495 } else if (ALARM_ERROR_INVALID_PARAMETER == ret) {
496 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Alarm not found."), &out);
498 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out,
499 ("Platform unknown error: %d (%s)", ret, get_error_message(ret)));
503 void AlarmManager::RemoveAll(const picojson::value& args, picojson::object& out) {
505 CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
507 int ret = alarm_cancel_all();
508 if (ALARM_ERROR_NONE != ret) {
509 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out,
510 ("Platform unknown error: %d (%s)", ret, get_error_message(ret)));
517 PlatformResult AlarmManager::GetAlarm(int id, picojson::object& obj) {
521 return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid id.",
522 ("id is wrong: %d", id));
525 int ret = ALARM_ERROR_NONE;
526 app_control_h app_control = nullptr;
527 char* alarm_type = nullptr;
528 char* date_string = nullptr;
529 char* delay_string = nullptr;
530 notification_h notification_handle = nullptr;
533 app_control_destroy(app_control);
537 notification_free(notification_handle);
540 if (ALARM_ERROR_NONE != alarm_get_app_control(id, &app_control)) {
541 if (ALARM_ERROR_NONE != alarm_get_notification(id, ¬ification_handle)) {
542 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Alarm not found.",
543 ("Alarm not found: %d (%s)", ret, get_error_message(ret)));
545 PlatformResult platform_result = extension::notification::CommonNotification::GetAppControl(
546 notification_handle, &app_control);
547 if (!platform_result) {
548 return LogAndCreateResult(
549 platform_result.error_code(), platform_result.message().c_str(),
550 ("Failed to get AppControl: %d (%s)", static_cast<int>(platform_result.error_code()),
551 platform_result.message().c_str()));
556 ret = app_control_get_extra_data(app_control, kAlarmKeyType, &alarm_type);
557 if (APP_CONTROL_ERROR_NONE != ret) {
558 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
559 ("Getting data failed: %d (%s)", ret, get_error_message(ret)));
562 obj.insert(std::make_pair("id", picojson::value(std::to_string(id))));
564 if (!strcmp(alarm_type, kAlarmTypeValueAbsolute)) {
566 memset(&date, 0, sizeof(tm));
568 ret = app_control_get_extra_data(app_control, kAlarmAbsoluteDateKey, &date_string);
570 if (APP_CONTROL_ERROR_NONE != ret) {
571 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
572 ("Failed to get data: %d (%s)", ret, get_error_message(ret)));
575 sscanf(date_string, "%5d %5d %5d %5d %5d %5d %5d", &date.tm_year, &date.tm_mon, &date.tm_mday,
576 &date.tm_hour, &date.tm_min, &date.tm_sec, &date.tm_isdst);
579 obj.insert(std::make_pair("year", picojson::value(std::to_string(date.tm_year + 1900))));
580 obj.insert(std::make_pair("month", picojson::value(std::to_string(date.tm_mon))));
581 obj.insert(std::make_pair("day", picojson::value(std::to_string(date.tm_mday))));
582 obj.insert(std::make_pair("hour", picojson::value(std::to_string(date.tm_hour))));
583 obj.insert(std::make_pair("min", picojson::value(std::to_string(date.tm_min))));
584 obj.insert(std::make_pair("sec", picojson::value(std::to_string(date.tm_sec))));
588 app_control_get_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey, &alarm_type);
590 if (!strcmp(alarm_type, kAlarmAbsoluteReccurrenceTypeInterval)) {
591 ret = alarm_get_scheduled_period(id, &interval);
592 if (ALARM_ERROR_NONE != ret) {
593 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
594 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
597 obj.insert(std::make_pair("second", picojson::value(std::to_string(interval))));
598 } else if (!strcmp(alarm_type, kAlarmAbsoluteReccurrenceTypeByDayValue)) {
601 ret = alarm_get_scheduled_recurrence_week_flag(id, &byDayValue);
602 if (ALARM_ERROR_NONE != ret) {
603 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
604 ("Failed to get data: %d (%s)", ret, get_error_message(ret)));
607 picojson::array& array =
608 obj.insert(std::make_pair("second", picojson::value(picojson::array())))
609 .first->second.get<picojson::array>();
611 using namespace util;
612 if (byDayValue & ALARM_WEEK_FLAG_SUNDAY) array.push_back(picojson::value(kSundayShort));
613 if (byDayValue & ALARM_WEEK_FLAG_MONDAY) array.push_back(picojson::value(kMondayShort));
614 if (byDayValue & ALARM_WEEK_FLAG_TUESDAY) array.push_back(picojson::value(kTuesdayShort));
615 if (byDayValue & ALARM_WEEK_FLAG_WEDNESDAY) array.push_back(picojson::value(kWednesdayShort));
616 if (byDayValue & ALARM_WEEK_FLAG_THURSDAY) array.push_back(picojson::value(kThuesdayShort));
617 if (byDayValue & ALARM_WEEK_FLAG_FRIDAY) array.push_back(picojson::value(kFridayShort));
618 if (byDayValue & ALARM_WEEK_FLAG_SATURDAY) array.push_back(picojson::value(kSaturdayShort));
621 obj.insert(std::make_pair("type", picojson::value(kAlarmAbsolute)));
623 } else if (!strcmp(alarm_type, kAlarmTypeValueRelative)) {
626 ret = alarm_get_scheduled_period(id, &interval);
627 if (ALARM_ERROR_NONE != ret) {
628 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
629 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
632 int ret_app = app_control_get_extra_data(app_control, kAlarmRelativeDelayKey, &delay_string);
633 if (APP_CONTROL_ERROR_NONE != ret_app) {
634 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
635 ("Failed to get data: %d (%s)", ret_app, get_error_message(ret_app)));
638 obj.insert(std::make_pair("type", picojson::value(kAlarmRelative)));
639 obj.insert(std::make_pair("delay", picojson::value(delay_string)));
641 // according to documentation interval will not be lower than 600,
642 // thus 0 from native means period wasn't set by user
643 obj.insert(std::make_pair("period", picojson::value(std::to_string(interval))));
646 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.");
649 return PlatformResult(ErrorCode::NO_ERROR);
652 void AlarmManager::Get(const picojson::value& args, picojson::object& out) {
657 if (args.contains("id") && args.get("id").is<double>()) {
658 id = static_cast<int>(args.get("id").get<double>());
661 picojson::value result = picojson::value(picojson::object());
662 picojson::object& result_obj = result.get<picojson::object>();
664 PlatformResult platform_result = GetAlarm(id, result_obj);
666 if (!platform_result) {
667 LogAndReportError(platform_result, &out);
669 ReportSuccess(result, out);
673 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
674 void AlarmManager::GetAlarmNotification(const picojson::value& args, picojson::object& out) {
675 using namespace extension::notification;
679 int ret = ALARM_ERROR_NONE;
680 notification_h notification_handle = nullptr;
681 PlatformResult platform_result = PlatformResult(ErrorCode::NO_ERROR);
684 notification_free(notification_handle);
687 if (args.contains("id") && args.get("id").is<double>()) {
688 alarm_id = static_cast<int>(args.get("id").get<double>());
691 ret = alarm_get_notification(alarm_id, ¬ification_handle);
693 if (ALARM_ERROR_NONE != ret) {
694 if (ALARM_ERROR_INVALID_PARAMETER == ret) {
696 PlatformResult(ErrorCode::NOT_FOUND_ERR, "Alarm with given ID was not found.");
698 platform_result = PlatformResult(ErrorCode::ABORT_ERR, "Failed to get notification.");
700 LogAndReportError(platform_result, &out);
703 app_control_h app_control = nullptr;
704 platform_result = CommonNotification::GetAppControl(notification_handle, &app_control);
706 if (!platform_result) {
707 LogAndReportError(platform_result, &out);
710 picojson::value result = picojson::value(picojson::object());
711 picojson::object& result_obj = result.get<picojson::object>();
713 platform_result = UserNotification::ToJson(-1, notification_handle, app_control, &result_obj);
715 if (ALARM_ERROR_NONE != ret) {
716 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Failed ToJson()."), &out);
719 ReportSuccess(result, out);
722 static bool AlarmIterateCB(int alarm_id, void* user_data) {
725 std::vector<int>* alarm_ids = reinterpret_cast<std::vector<int>*>(user_data);
727 alarm_ids->push_back(alarm_id);
732 void AlarmManager::GetAll(const picojson::value& args, picojson::object& out) {
734 std::vector<int> alarm_ids;
735 int ret = alarm_foreach_registered_alarm(AlarmIterateCB, &alarm_ids);
737 if (ALARM_ERROR_NONE != ret) {
738 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out,
739 ("Platform unknown error: %d (%s)", ret, get_error_message(ret)));
743 picojson::value result_array = picojson::value(picojson::array());
744 picojson::array& array_obj = result_array.get<picojson::array>();
746 for (size_t i = 0; i < alarm_ids.size(); i++) {
747 picojson::value result = picojson::value(picojson::object());
748 picojson::object& obj = result.get<picojson::object>();
750 PlatformResult platform_result = GetAlarm(alarm_ids.at(i), obj);
751 if (!platform_result) {
752 LogAndReportError(platform_result, &out, ("Failed GetAlarm()"));
755 array_obj.push_back(result);
758 ReportSuccess(result_array, out);
761 void AlarmManager::GetRemainingSeconds(const picojson::value& args, picojson::object& out) {
771 if (args.contains("id") && args.get("id").is<double>()) {
772 id = static_cast<int>(args.get("id").get<double>());
775 picojson::value result = picojson::value(picojson::object());
776 picojson::object& result_obj = result.get<picojson::object>();
778 int ret = alarm_get_scheduled_date(id, &date);
779 if (ALARM_ERROR_NONE != ret) {
780 LoggerI("alarm_get_scheduled_date error: %d (%s)", ret, get_error_message(ret));
781 if (ALARM_ERROR_INVALID_PARAMETER == ret || ALARM_ERROR_CONNECTION_FAIL == ret) {
782 result_obj.insert(std::make_pair("seconds", picojson::value()));
783 ReportSuccess(result, out);
786 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out);
791 alarm_get_current_time(¤t);
792 next_time = mktime(&date);
793 current_time = mktime(¤t);
795 long seconds = next_time - current_time;
797 result_obj.insert(std::make_pair("seconds", picojson::value(std::to_string(seconds))));
798 ReportSuccess(result, out);
801 void AlarmManager::GetNextScheduledDate(const picojson::value& args, picojson::object& out) {
805 if (args.contains("id") && args.get("id").is<double>()) {
806 id = static_cast<int>(args.get("id").get<double>());
810 int ret = alarm_get_scheduled_date(id, &date);
812 picojson::value result = picojson::value(picojson::object());
813 picojson::object& result_obj = result.get<picojson::object>();
815 if (ALARM_ERROR_NONE != ret) {
816 result_obj.insert(std::make_pair("year", picojson::value()));
817 ReportSuccess(result, out);
822 ret = alarm_get_current_time(&curr_date);
823 if (ALARM_ERROR_NONE != ret || mktime(&date) < mktime(&curr_date)) {
824 result_obj.insert(std::make_pair("year", picojson::value()));
825 ReportSuccess(result, out);
829 // tm struct contains years since 1900
830 // there is added 1900 to tm_year to return proper date
831 result_obj.insert(std::make_pair("year", picojson::value(std::to_string(date.tm_year + 1900))));
832 result_obj.insert(std::make_pair("month", picojson::value(std::to_string(date.tm_mon))));
833 result_obj.insert(std::make_pair("day", picojson::value(std::to_string(date.tm_mday))));
834 result_obj.insert(std::make_pair("hour", picojson::value(std::to_string(date.tm_hour))));
835 result_obj.insert(std::make_pair("min", picojson::value(std::to_string(date.tm_min))));
836 result_obj.insert(std::make_pair("sec", picojson::value(std::to_string(date.tm_sec))));
838 ReportSuccess(result, out);
842 } // namespace extension