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 int ret = app_control_create(&app_control);
112 if (APP_CONTROL_ERROR_NONE != ret) {
113 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "app_control_create() failed."),
115 ("app_control_create() failed: %d (%s)", ret, get_error_message(ret)));
118 ret = app_control_set_operation(app_control, APP_CONTROL_OPERATION_DEFAULT);
119 if (APP_CONTROL_ERROR_NONE != ret) {
121 PlatformResult(ErrorCode::UNKNOWN_ERR, "app_control_set_operation() failed."), &out,
122 ("app_control_set_operation() failed: %d (%s)", ret, get_error_message(ret)));
127 app_control_set_app_id(app_control, app_id.c_str());
133 picojson::value result = picojson::value(picojson::object());
134 picojson::object& result_obj = result.get<picojson::object>();
136 if (kAlarmRelative == alarm_type) {
137 app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueRelative);
139 const auto it_delay = alarm.find("delay");
140 const auto it_period = alarm.find("period");
142 if (alarm.end() == it_delay || alarm.end() == it_period || !it_delay->second.is<double>()) {
143 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
147 int delay = static_cast<int>(it_delay->second.get<double>());
149 if (it_period->second.is<double>()) {
150 period = static_cast<int>(it_period->second.get<double>());
153 bool isPeriodSet = false;
154 if (args.contains("isPeriodSet")) {
155 isPeriodSet = args.get("isPeriodSet").get<bool>();
158 std::string delay_str = std::to_string(delay);
160 app_control_add_extra_data(app_control, kAlarmRelativeDelayKey, delay_str.c_str());
161 if (APP_CONTROL_ERROR_NONE != ret_app) {
163 PlatformResult(ErrorCode::UNKNOWN_ERR, "Fail to add data from app_control."), &out,
164 ("Fail to add data from app_control: %d (%s)", ret_app, get_error_message(ret_app)));
168 int ret = ALARM_ERROR_NONE;
170 ret = alarm_schedule_once_after_delay(app_control, delay, &alarm_id);
172 ret = alarm_schedule_after_delay(app_control, delay, period, &alarm_id);
174 if (ALARM_ERROR_NONE != ret) {
175 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while add alarm to server."),
177 ("Error while add alarm to server: %d (%s)", ret, get_error_message(ret)));
181 ret = alarm_get_scheduled_period(alarm_id, &period);
182 if (ALARM_ERROR_NONE != ret) {
183 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out,
184 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
188 result_obj.insert(std::make_pair("period", picojson::value(std::to_string(period))));
191 app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueAbsolute);
193 const auto it_period = alarm.find("period");
194 const auto it_daysOfTheWeek = alarm.find("daysOfTheWeek");
196 long long int seconds = 0;
197 if (args.contains("seconds")) {
198 seconds = atoll(args.get("seconds").get<std::string>().c_str());
201 time_t second = seconds / 1000;
202 struct tm start_date = {0};
205 if (nullptr == localtime_r(&second, &start_date)) {
206 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Invalid date."), &out);
212 char str_date[kDateSize];
214 snprintf(str_date, sizeof(str_date), "%d %d %d %d %d %d %d", start_date.tm_year,
215 start_date.tm_mon, start_date.tm_mday, start_date.tm_hour, start_date.tm_min,
216 start_date.tm_sec, start_date.tm_isdst);
218 app_control_add_extra_data(app_control, kAlarmAbsoluteDateKey, str_date);
221 if (alarm.end() != it_period && it_period->second.is<double>()) {
222 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
223 kAlarmAbsoluteReccurrenceTypeInterval);
224 period = static_cast<int>(it_period->second.get<double>());
225 ret = alarm_schedule_at_date(app_control, &start_date, period, &alarm_id);
226 if (ALARM_ERROR_NONE != ret) {
227 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Adding alarm to server failed."),
229 ("Adding alarm to server failed: %d (%s)", ret, get_error_message(ret)));
233 ret = alarm_get_scheduled_period(alarm_id, &period);
234 result_obj.insert(std::make_pair("period", picojson::value(std::to_string(period))));
235 } else if (alarm.end() != it_daysOfTheWeek && it_daysOfTheWeek->second.is<picojson::array>() &&
236 !(it_daysOfTheWeek->second.get<picojson::array>()).empty()) {
237 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
238 kAlarmAbsoluteReccurrenceTypeByDayValue);
239 const picojson::array& days_of_the_week = it_daysOfTheWeek->second.get<picojson::array>();
240 int repeat_value = 0;
241 PlatformResult result = util::ArrayDaysToMask(days_of_the_week, &repeat_value);
243 LogAndReportError(PlatformResult(result.error_code(), result.message()), &out);
246 ret = alarm_schedule_with_recurrence_week_flag(app_control, &start_date, repeat_value,
249 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
250 kAlarmAbsoluteRecurrenceTypeNone);
251 ret = alarm_schedule_at_date(app_control, &start_date, 0, &alarm_id);
254 if (ALARM_ERROR_NONE != ret) {
255 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Adding alarm to server failed."),
257 ("Adding alarm to server failed: %d (%s)", ret, get_error_message(ret)));
262 result_obj.insert(std::make_pair("id", picojson::value(std::to_string(alarm_id))));
263 ReportSuccess(result, out);
266 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
267 void AlarmManager::AddAlarmNotification(const picojson::value& args, picojson::object& out) {
268 using namespace extension::notification;
270 CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
271 CHECK_PRIVILEGE_ACCESS(kPrivilegeNotification, &out);
273 if (!args.contains("alarm") || !args.contains("notification")) {
274 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
279 const picojson::object& alarm = args.get("alarm").get<picojson::object>();
281 std::string alarm_type;
282 if (args.contains("type")) {
283 alarm_type = args.get("type").get<std::string>();
286 notification_h notification_handle = nullptr;
287 app_control_h app_control = nullptr;
290 notification_free(notification_handle);
291 app_control_destroy(app_control);
294 using namespace std::placeholders;
295 GetHandleFromJsonFun impl{};
296 if (args.contains("newImpl") && args.get("newImpl").is<bool>() &&
297 args.get("newImpl").get<bool>()) {
298 LoggerD("New implementation");
299 impl = std::bind(&UserNotification::GetNotiHandleFromJson, _1, _2, _3);
301 LoggerW("Deprecated object used");
302 impl = std::bind(&StatusNotification::GetNotiHandleFromJson, _1, _2, _3);
305 PlatformResult platform_result = impl(args.get("notification"), false, ¬ification_handle);
306 if (!platform_result) {
307 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, platform_result.message().c_str()),
310 platform_result = CommonNotification::GetAppControl(notification_handle, &app_control);
312 if (!platform_result) {
314 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
320 if (kAlarmRelative == alarm_type) {
321 ret = app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueRelative);
322 if (ret != APP_CONTROL_ERROR_NONE) {
324 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
325 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
329 const auto it_period = alarm.find("period");
330 const auto it_delay = alarm.find("delay");
332 if (alarm.end() == it_delay || alarm.end() == it_period || !it_delay->second.is<double>()) {
333 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
338 int delay = static_cast<int>(it_delay->second.get<double>());
340 std::string delay_str = std::to_string(delay);
341 ret = app_control_add_extra_data(app_control, kAlarmRelativeDelayKey, delay_str.c_str());
342 if (APP_CONTROL_ERROR_NONE != ret) {
344 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
345 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
349 platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
351 if (!platform_result) {
353 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
357 if (it_period->second.is<double>()) {
358 period = static_cast<int>(it_period->second.get<double>());
361 bool isPeriodSet = false;
362 if (args.contains("isPeriodSet")) {
363 isPeriodSet = args.get("isPeriodSet").get<bool>();
367 ret = alarm_schedule_noti_once_after_delay(notification_handle, delay, &alarm_id);
369 ret = alarm_schedule_noti_after_delay(notification_handle, delay, period, &alarm_id);
372 if (alarm.find("period")->second.is<double>()) {
373 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR,
374 "AlarmAbsolute constructed by deprecated constructor."),
379 ret = app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueAbsolute);
380 if (APP_CONTROL_ERROR_NONE != ret) {
382 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
383 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
387 const auto it_daysOfTheWeek = alarm.find("daysOfTheWeek");
388 long long int milliseconds = 0;
390 if (args.contains("milliseconds")) {
391 milliseconds = strtoll(args.get("milliseconds").get<std::string>().c_str(), nullptr, 10);
394 time_t second = milliseconds / 1000;
395 struct tm start_date = {0};
398 if (nullptr == localtime_r(&second, &start_date)) {
399 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Invalid date."), &out);
405 char str_date[kDateSize];
407 snprintf(str_date, sizeof(str_date), "%d %d %d %d %d %d %d", start_date.tm_year,
408 start_date.tm_mon, start_date.tm_mday, start_date.tm_hour, start_date.tm_min,
409 start_date.tm_sec, start_date.tm_isdst);
411 ret = app_control_add_extra_data(app_control, kAlarmAbsoluteDateKey, str_date);
412 if (APP_CONTROL_ERROR_NONE != ret) {
414 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
415 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
419 if (alarm.end() != it_daysOfTheWeek && it_daysOfTheWeek->second.is<picojson::array>() &&
420 !(it_daysOfTheWeek->second.get<picojson::array>()).empty()) {
421 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
422 kAlarmAbsoluteReccurrenceTypeByDayValue);
424 const picojson::array& days_of_the_week = it_daysOfTheWeek->second.get<picojson::array>();
425 int repeat_value = 0;
426 util::ArrayDaysToMask(days_of_the_week, &repeat_value);
428 platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
429 if (!platform_result) {
431 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
434 ret = alarm_schedule_noti_with_recurrence_week_flag(notification_handle, &start_date,
435 repeat_value, &alarm_id);
437 ret = app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
438 kAlarmAbsoluteRecurrenceTypeNone);
439 if (APP_CONTROL_ERROR_NONE != ret) {
441 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
442 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
446 platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
447 if (!platform_result) {
449 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
452 ret = alarm_schedule_noti_once_at_date(notification_handle, &start_date, &alarm_id);
456 if (ALARM_ERROR_NONE != ret) {
457 if (ALARM_ERROR_INVALID_TIME == ret || ALARM_ERROR_INVALID_DATE == ret ||
458 ALARM_ERROR_INVALID_PARAMETER == ret) {
459 platform_result = PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid data.");
461 platform_result = PlatformResult(ErrorCode::ABORT_ERR, "Error while adding alarm to server.");
464 LogAndReportError(platform_result, &out,
465 ("Error while add alarm to server: %d (%s)", ret, get_error_message(ret)));
469 picojson::value result = picojson::value(picojson::object());
470 picojson::object& result_obj = result.get<picojson::object>();
472 if (alarm_type == kAlarmRelative) {
474 ret = alarm_get_scheduled_period(alarm_id, &period);
475 if (ALARM_ERROR_NONE != ret) {
476 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out,
477 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
481 result_obj.insert(std::make_pair("period", picojson::value(std::to_string(period))));
485 result_obj.insert(std::make_pair("id", picojson::value(std::to_string(alarm_id))));
486 ReportSuccess(result, out);
490 void AlarmManager::Remove(const picojson::value& args, picojson::object& out) {
492 CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
496 if (args.contains("id") && args.get("id").is<double>()) {
497 id = static_cast<int>(args.get("id").get<double>());
501 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid id."), &out,
502 ("id is wrong: %d", id));
506 int ret = alarm_cancel(id);
507 if (ALARM_ERROR_NONE == ret) {
509 } else if (ALARM_ERROR_INVALID_PARAMETER == ret) {
510 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Alarm not found."), &out);
512 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out,
513 ("Platform unknown error: %d (%s)", ret, get_error_message(ret)));
517 void AlarmManager::RemoveAll(const picojson::value& args, picojson::object& out) {
519 CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
521 int ret = alarm_cancel_all();
522 if (ALARM_ERROR_NONE != ret) {
523 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out,
524 ("Platform unknown error: %d (%s)", ret, get_error_message(ret)));
531 PlatformResult AlarmManager::GetAlarm(int id, picojson::object& obj) {
535 return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid id.",
536 ("id is wrong: %d", id));
539 int ret = ALARM_ERROR_NONE;
540 app_control_h app_control = nullptr;
541 char* alarm_type = nullptr;
542 char* date_string = nullptr;
543 char* delay_string = nullptr;
544 notification_h notification_handle = nullptr;
547 app_control_destroy(app_control);
551 notification_free(notification_handle);
554 if (ALARM_ERROR_NONE != alarm_get_app_control(id, &app_control)) {
555 // This is a special kind of alarm, which has the notification instead of an app_control handle.
556 // In case of error during app_control gathering, we check if it has notification. If both calls
557 // end with error, then we report NOT_FOUND_ERROR
558 if (ALARM_ERROR_NONE != alarm_get_notification(id, ¬ification_handle)) {
559 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Alarm not found.",
560 ("Alarm not found: %d (%s)", ret, get_error_message(ret)));
562 PlatformResult platform_result = extension::notification::CommonNotification::GetAppControl(
563 notification_handle, &app_control);
564 if (!platform_result) {
565 return LogAndCreateResult(
566 platform_result.error_code(), platform_result.message().c_str(),
567 ("Failed to get AppControl: %d (%s)", static_cast<int>(platform_result.error_code()),
568 platform_result.message().c_str()));
573 ret = app_control_get_extra_data(app_control, kAlarmKeyType, &alarm_type);
574 if (APP_CONTROL_ERROR_NONE != ret) {
575 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
576 ("Getting data failed: %d (%s)", ret, get_error_message(ret)));
579 obj.insert(std::make_pair("id", picojson::value(std::to_string(id))));
581 if (!strcmp(alarm_type, kAlarmTypeValueAbsolute)) {
583 memset(&date, 0, sizeof(tm));
585 ret = app_control_get_extra_data(app_control, kAlarmAbsoluteDateKey, &date_string);
587 if (APP_CONTROL_ERROR_NONE != ret) {
588 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
589 ("Failed to get data: %d (%s)", ret, get_error_message(ret)));
592 sscanf(date_string, "%5d %5d %5d %5d %5d %5d %5d", &date.tm_year, &date.tm_mon, &date.tm_mday,
593 &date.tm_hour, &date.tm_min, &date.tm_sec, &date.tm_isdst);
596 obj.insert(std::make_pair("year", picojson::value(std::to_string(date.tm_year + 1900))));
597 obj.insert(std::make_pair("month", picojson::value(std::to_string(date.tm_mon))));
598 obj.insert(std::make_pair("day", picojson::value(std::to_string(date.tm_mday))));
599 obj.insert(std::make_pair("hour", picojson::value(std::to_string(date.tm_hour))));
600 obj.insert(std::make_pair("min", picojson::value(std::to_string(date.tm_min))));
601 obj.insert(std::make_pair("sec", picojson::value(std::to_string(date.tm_sec))));
605 ret = app_control_get_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey, &alarm_type);
606 if (APP_CONTROL_ERROR_NONE != ret) {
607 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
608 ("Getting data failed: %d (%s)", ret, get_error_message(ret)));
611 if (!strcmp(alarm_type, kAlarmAbsoluteReccurrenceTypeInterval)) {
612 ret = alarm_get_scheduled_period(id, &interval);
613 if (ALARM_ERROR_NONE != ret) {
614 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
615 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
618 obj.insert(std::make_pair("second", picojson::value(std::to_string(interval))));
619 } else if (!strcmp(alarm_type, kAlarmAbsoluteReccurrenceTypeByDayValue)) {
622 ret = alarm_get_scheduled_recurrence_week_flag(id, &byDayValue);
623 if (ALARM_ERROR_NONE != ret) {
624 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
625 ("Failed to get data: %d (%s)", ret, get_error_message(ret)));
628 picojson::array& array =
629 obj.insert(std::make_pair("second", picojson::value(picojson::array())))
630 .first->second.get<picojson::array>();
632 using namespace util;
633 if (byDayValue & ALARM_WEEK_FLAG_SUNDAY) array.push_back(picojson::value(kSundayShort));
634 if (byDayValue & ALARM_WEEK_FLAG_MONDAY) array.push_back(picojson::value(kMondayShort));
635 if (byDayValue & ALARM_WEEK_FLAG_TUESDAY) array.push_back(picojson::value(kTuesdayShort));
636 if (byDayValue & ALARM_WEEK_FLAG_WEDNESDAY) array.push_back(picojson::value(kWednesdayShort));
637 if (byDayValue & ALARM_WEEK_FLAG_THURSDAY) array.push_back(picojson::value(kThuesdayShort));
638 if (byDayValue & ALARM_WEEK_FLAG_FRIDAY) array.push_back(picojson::value(kFridayShort));
639 if (byDayValue & ALARM_WEEK_FLAG_SATURDAY) array.push_back(picojson::value(kSaturdayShort));
642 obj.insert(std::make_pair("type", picojson::value(kAlarmAbsolute)));
644 } else if (!strcmp(alarm_type, kAlarmTypeValueRelative)) {
647 ret = alarm_get_scheduled_period(id, &interval);
648 if (ALARM_ERROR_NONE != ret) {
649 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
650 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
653 int ret_app = app_control_get_extra_data(app_control, kAlarmRelativeDelayKey, &delay_string);
654 if (APP_CONTROL_ERROR_NONE != ret_app) {
655 return LogAndCreateResult(
656 ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
657 ("Failed to get data: %d (%s)", ret_app, get_error_message(ret_app)));
660 obj.insert(std::make_pair("type", picojson::value(kAlarmRelative)));
661 obj.insert(std::make_pair("delay", picojson::value(delay_string)));
663 // according to documentation interval will not be lower than 600,
664 // thus 0 from native means period wasn't set by user
665 obj.insert(std::make_pair("period", picojson::value(std::to_string(interval))));
668 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.");
671 return PlatformResult(ErrorCode::NO_ERROR);
674 void AlarmManager::Get(const picojson::value& args, picojson::object& out) {
679 if (args.contains("id") && args.get("id").is<double>()) {
680 id = static_cast<int>(args.get("id").get<double>());
683 picojson::value result = picojson::value(picojson::object());
684 picojson::object& result_obj = result.get<picojson::object>();
686 PlatformResult platform_result = GetAlarm(id, result_obj);
688 if (!platform_result) {
689 LogAndReportError(platform_result, &out);
691 ReportSuccess(result, out);
695 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
696 void AlarmManager::GetAlarmNotification(const picojson::value& args, picojson::object& out) {
697 using namespace extension::notification;
701 int ret = ALARM_ERROR_NONE;
702 notification_h notification_handle = nullptr;
703 PlatformResult platform_result = PlatformResult(ErrorCode::NO_ERROR);
706 notification_free(notification_handle);
709 if (args.contains("id") && args.get("id").is<double>()) {
710 alarm_id = static_cast<int>(args.get("id").get<double>());
713 ret = alarm_get_notification(alarm_id, ¬ification_handle);
715 if (ALARM_ERROR_NONE != ret) {
716 if (ALARM_ERROR_INVALID_PARAMETER == ret) {
718 PlatformResult(ErrorCode::NOT_FOUND_ERR, "Alarm with given ID was not found.");
720 platform_result = PlatformResult(ErrorCode::ABORT_ERR, "Failed to get notification.");
722 LogAndReportError(platform_result, &out);
725 app_control_h app_control = nullptr;
726 platform_result = CommonNotification::GetAppControl(notification_handle, &app_control);
728 if (!platform_result) {
729 LogAndReportError(platform_result, &out);
732 picojson::value result = picojson::value(picojson::object());
733 picojson::object& result_obj = result.get<picojson::object>();
735 platform_result = UserNotification::ToJson(-1, notification_handle, app_control, &result_obj);
737 if (ALARM_ERROR_NONE != ret) {
738 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Failed ToJson()."), &out);
741 ReportSuccess(result, out);
744 static bool AlarmIterateCB(int alarm_id, void* user_data) {
747 std::vector<int>* alarm_ids = reinterpret_cast<std::vector<int>*>(user_data);
749 alarm_ids->push_back(alarm_id);
754 void AlarmManager::GetAll(const picojson::value& args, picojson::object& out) {
756 std::vector<int> alarm_ids;
757 int ret = alarm_foreach_registered_alarm(AlarmIterateCB, &alarm_ids);
759 if (ALARM_ERROR_NONE != ret) {
760 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out,
761 ("Platform unknown error: %d (%s)", ret, get_error_message(ret)));
765 picojson::value result_array = picojson::value(picojson::array());
766 picojson::array& array_obj = result_array.get<picojson::array>();
768 for (size_t i = 0; i < alarm_ids.size(); i++) {
769 picojson::value result = picojson::value(picojson::object());
770 picojson::object& obj = result.get<picojson::object>();
772 PlatformResult platform_result = GetAlarm(alarm_ids.at(i), obj);
773 if (!platform_result) {
774 LogAndReportError(platform_result, &out, ("Failed GetAlarm()"));
777 array_obj.push_back(result);
780 ReportSuccess(result_array, out);
783 void AlarmManager::GetRemainingSeconds(const picojson::value& args, picojson::object& out) {
793 if (args.contains("id") && args.get("id").is<double>()) {
794 id = static_cast<int>(args.get("id").get<double>());
797 picojson::value result = picojson::value(picojson::object());
798 picojson::object& result_obj = result.get<picojson::object>();
800 int ret = alarm_get_scheduled_date(id, &date);
801 if (ALARM_ERROR_NONE != ret) {
802 LoggerI("alarm_get_scheduled_date error: %d (%s)", ret, get_error_message(ret));
803 if (ALARM_ERROR_INVALID_PARAMETER == ret || ALARM_ERROR_CONNECTION_FAIL == ret) {
804 result_obj.insert(std::make_pair("seconds", picojson::value()));
805 ReportSuccess(result, out);
808 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out);
813 alarm_get_current_time(¤t);
814 next_time = mktime(&date);
815 current_time = mktime(¤t);
817 long seconds = next_time - current_time;
819 result_obj.insert(std::make_pair("seconds", picojson::value(std::to_string(seconds))));
820 ReportSuccess(result, out);
823 void AlarmManager::GetNextScheduledDate(const picojson::value& args, picojson::object& out) {
827 if (args.contains("id") && args.get("id").is<double>()) {
828 id = static_cast<int>(args.get("id").get<double>());
832 int ret = alarm_get_scheduled_date(id, &date);
834 picojson::value result = picojson::value(picojson::object());
835 picojson::object& result_obj = result.get<picojson::object>();
837 if (ALARM_ERROR_NONE != ret) {
838 result_obj.insert(std::make_pair("year", picojson::value()));
839 ReportSuccess(result, out);
844 ret = alarm_get_current_time(&curr_date);
845 if (ALARM_ERROR_NONE != ret || mktime(&date) < mktime(&curr_date)) {
846 result_obj.insert(std::make_pair("year", picojson::value()));
847 ReportSuccess(result, out);
851 // tm struct contains years since 1900
852 // there is added 1900 to tm_year to return proper date
853 result_obj.insert(std::make_pair("year", picojson::value(std::to_string(date.tm_year + 1900))));
854 result_obj.insert(std::make_pair("month", picojson::value(std::to_string(date.tm_mon))));
855 result_obj.insert(std::make_pair("day", picojson::value(std::to_string(date.tm_mday))));
856 result_obj.insert(std::make_pair("hour", picojson::value(std::to_string(date.tm_hour))));
857 result_obj.insert(std::make_pair("min", picojson::value(std::to_string(date.tm_min))));
858 result_obj.insert(std::make_pair("sec", picojson::value(std::to_string(date.tm_sec))));
860 ReportSuccess(result, out);
864 } // namespace extension