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);
147 app_control_add_extra_data(app_control, kAlarmRelativeDelayKey, delay_str.c_str());
148 if (APP_CONTROL_ERROR_NONE != ret_app) {
150 PlatformResult(ErrorCode::UNKNOWN_ERR, "Fail to add data from app_control."), &out,
151 ("Fail to add data from app_control: %d (%s)", ret_app, get_error_message(ret_app)));
155 int ret = ALARM_ERROR_NONE;
157 ret = alarm_schedule_once_after_delay(app_control, delay, &alarm_id);
159 ret = alarm_schedule_after_delay(app_control, delay, period, &alarm_id);
161 if (ALARM_ERROR_NONE != ret) {
162 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while add alarm to server."),
164 ("Error while add alarm to server: %d (%s)", ret, get_error_message(ret)));
168 ret = alarm_get_scheduled_period(alarm_id, &period);
169 if (ALARM_ERROR_NONE != ret) {
170 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out,
171 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
175 result_obj.insert(std::make_pair("period", picojson::value(std::to_string(period))));
178 app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueAbsolute);
180 const auto it_period = alarm.find("period");
181 const auto it_daysOfTheWeek = alarm.find("daysOfTheWeek");
183 long long int seconds = 0;
184 if (args.contains("seconds")) {
185 seconds = atoll(args.get("seconds").get<std::string>().c_str());
188 time_t second = seconds / 1000;
189 struct tm start_date = {0};
192 if (nullptr == localtime_r(&second, &start_date)) {
193 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Invalid date."), &out);
199 char str_date[kDateSize];
201 snprintf(str_date, sizeof(str_date), "%d %d %d %d %d %d %d", start_date.tm_year,
202 start_date.tm_mon, start_date.tm_mday, start_date.tm_hour, start_date.tm_min,
203 start_date.tm_sec, start_date.tm_isdst);
205 app_control_add_extra_data(app_control, kAlarmAbsoluteDateKey, str_date);
208 if (alarm.end() != it_period && it_period->second.is<double>()) {
209 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
210 kAlarmAbsoluteReccurrenceTypeInterval);
211 period = static_cast<int>(it_period->second.get<double>());
212 ret = alarm_schedule_at_date(app_control, &start_date, period, &alarm_id);
213 if (ALARM_ERROR_NONE != ret) {
214 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Adding alarm to server failed."),
216 ("Adding alarm to server failed: %d (%s)", ret, get_error_message(ret)));
220 ret = alarm_get_scheduled_period(alarm_id, &period);
221 result_obj.insert(std::make_pair("period", picojson::value(std::to_string(period))));
222 } else if (alarm.end() != it_daysOfTheWeek && it_daysOfTheWeek->second.is<picojson::array>() &&
223 !(it_daysOfTheWeek->second.get<picojson::array>()).empty()) {
224 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
225 kAlarmAbsoluteReccurrenceTypeByDayValue);
226 const picojson::array& days_of_the_week = it_daysOfTheWeek->second.get<picojson::array>();
227 int repeat_value = 0;
228 PlatformResult result = util::ArrayDaysToMask(days_of_the_week, &repeat_value);
230 LogAndReportError(PlatformResult(result.error_code(), result.message()), &out);
233 ret = alarm_schedule_with_recurrence_week_flag(app_control, &start_date, repeat_value,
236 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
237 kAlarmAbsoluteRecurrenceTypeNone);
238 ret = alarm_schedule_at_date(app_control, &start_date, 0, &alarm_id);
241 if (ALARM_ERROR_NONE != ret) {
242 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Adding alarm to server failed."),
244 ("Adding alarm to server failed: %d (%s)", ret, get_error_message(ret)));
249 result_obj.insert(std::make_pair("id", picojson::value(std::to_string(alarm_id))));
250 ReportSuccess(result, out);
253 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
254 void AlarmManager::AddAlarmNotification(const picojson::value& args, picojson::object& out) {
255 using namespace extension::notification;
257 CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
258 CHECK_PRIVILEGE_ACCESS(kPrivilegeNotification, &out);
260 if (!args.contains("alarm") || !args.contains("notification")) {
261 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
266 const picojson::object& alarm = args.get("alarm").get<picojson::object>();
268 std::string alarm_type;
269 if (args.contains("type")) {
270 alarm_type = args.get("type").get<std::string>();
273 notification_h notification_handle = nullptr;
274 app_control_h app_control = nullptr;
277 notification_free(notification_handle);
278 app_control_destroy(app_control);
281 using namespace std::placeholders;
282 GetHandleFromJsonFun impl{};
283 if (args.contains("newImpl") && args.get("newImpl").is<bool>() &&
284 args.get("newImpl").get<bool>()) {
285 LoggerD("New implementation");
286 impl = std::bind(&UserNotification::GetNotiHandleFromJson, _1, _2, _3);
288 LoggerW("Deprecated object used");
289 impl = std::bind(&StatusNotification::GetNotiHandleFromJson, _1, _2, _3);
292 PlatformResult platform_result = impl(args.get("notification"), false, ¬ification_handle);
293 if (!platform_result) {
294 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, platform_result.message().c_str()),
297 platform_result = CommonNotification::GetAppControl(notification_handle, &app_control);
299 if (!platform_result) {
301 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
307 if (kAlarmRelative == alarm_type) {
308 ret = app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueRelative);
309 if (ret != APP_CONTROL_ERROR_NONE) {
311 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
312 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
316 const auto it_period = alarm.find("period");
317 const auto it_delay = alarm.find("delay");
319 if (alarm.end() == it_delay || alarm.end() == it_period || !it_delay->second.is<double>()) {
320 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
325 int delay = static_cast<int>(it_delay->second.get<double>());
327 std::string delay_str = std::to_string(delay);
328 ret = app_control_add_extra_data(app_control, kAlarmRelativeDelayKey, delay_str.c_str());
329 if (APP_CONTROL_ERROR_NONE != ret) {
331 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
332 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
336 platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
338 if (!platform_result) {
340 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
344 if (it_period->second.is<double>()) {
345 period = static_cast<int>(it_period->second.get<double>());
348 bool isPeriodSet = false;
349 if (args.contains("isPeriodSet")) {
350 isPeriodSet = args.get("isPeriodSet").get<bool>();
354 ret = alarm_schedule_noti_once_after_delay(notification_handle, delay, &alarm_id);
356 ret = alarm_schedule_noti_after_delay(notification_handle, delay, period, &alarm_id);
359 if (alarm.find("period")->second.is<double>()) {
360 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR,
361 "AlarmAbsolute constructed by deprecated constructor."),
366 ret = app_control_add_extra_data(app_control, kAlarmKeyType, kAlarmTypeValueAbsolute);
367 if (APP_CONTROL_ERROR_NONE != ret) {
369 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
370 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
374 const auto it_daysOfTheWeek = alarm.find("daysOfTheWeek");
375 long long int milliseconds = 0;
377 if (args.contains("milliseconds")) {
378 milliseconds = strtoll(args.get("milliseconds").get<std::string>().c_str(), nullptr, 10);
381 time_t second = milliseconds / 1000;
382 struct tm start_date = {0};
385 if (nullptr == localtime_r(&second, &start_date)) {
386 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Invalid date."), &out);
392 char str_date[kDateSize];
394 snprintf(str_date, sizeof(str_date), "%d %d %d %d %d %d %d", start_date.tm_year,
395 start_date.tm_mon, start_date.tm_mday, start_date.tm_hour, start_date.tm_min,
396 start_date.tm_sec, start_date.tm_isdst);
398 ret = app_control_add_extra_data(app_control, kAlarmAbsoluteDateKey, str_date);
399 if (APP_CONTROL_ERROR_NONE != ret) {
401 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
402 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
406 if (alarm.end() != it_daysOfTheWeek && it_daysOfTheWeek->second.is<picojson::array>() &&
407 !(it_daysOfTheWeek->second.get<picojson::array>()).empty()) {
408 app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
409 kAlarmAbsoluteReccurrenceTypeByDayValue);
411 const picojson::array& days_of_the_week = it_daysOfTheWeek->second.get<picojson::array>();
412 int repeat_value = 0;
413 util::ArrayDaysToMask(days_of_the_week, &repeat_value);
415 platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
416 if (!platform_result) {
418 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
421 ret = alarm_schedule_noti_with_recurrence_week_flag(notification_handle, &start_date,
422 repeat_value, &alarm_id);
424 ret = app_control_add_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey,
425 kAlarmAbsoluteRecurrenceTypeNone);
426 if (APP_CONTROL_ERROR_NONE != ret) {
428 PlatformResult(ErrorCode::ABORT_ERR, "Fail to add data from app_control."), &out,
429 ("Fail to add data from app_control: %d (%s)", ret, get_error_message(ret)));
433 platform_result = CommonNotification::SetAppControl(notification_handle, app_control);
434 if (!platform_result) {
436 PlatformResult(platform_result.error_code(), platform_result.message().c_str()), &out);
439 ret = alarm_schedule_noti_once_at_date(notification_handle, &start_date, &alarm_id);
443 if (ALARM_ERROR_NONE != ret) {
444 if (ALARM_ERROR_INVALID_TIME == ret || ALARM_ERROR_INVALID_DATE == ret ||
445 ALARM_ERROR_INVALID_PARAMETER == ret) {
446 platform_result = PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid data.");
448 platform_result = PlatformResult(ErrorCode::ABORT_ERR, "Error while adding alarm to server.");
451 LogAndReportError(platform_result, &out,
452 ("Error while add alarm to server: %d (%s)", ret, get_error_message(ret)));
456 picojson::value result = picojson::value(picojson::object());
457 picojson::object& result_obj = result.get<picojson::object>();
459 if (alarm_type == kAlarmRelative) {
461 ret = alarm_get_scheduled_period(alarm_id, &period);
462 if (ALARM_ERROR_NONE != ret) {
463 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out,
464 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
468 result_obj.insert(std::make_pair("period", picojson::value(std::to_string(period))));
472 result_obj.insert(std::make_pair("id", picojson::value(std::to_string(alarm_id))));
473 ReportSuccess(result, out);
477 void AlarmManager::Remove(const picojson::value& args, picojson::object& out) {
479 CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
483 if (args.contains("id") && args.get("id").is<double>()) {
484 id = static_cast<int>(args.get("id").get<double>());
488 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid id."), &out,
489 ("id is wrong: %d", id));
493 int ret = alarm_cancel(id);
494 if (ALARM_ERROR_NONE == ret) {
496 } else if (ALARM_ERROR_INVALID_PARAMETER == ret) {
497 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Alarm not found."), &out);
499 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out,
500 ("Platform unknown error: %d (%s)", ret, get_error_message(ret)));
504 void AlarmManager::RemoveAll(const picojson::value& args, picojson::object& out) {
506 CHECK_PRIVILEGE_ACCESS(kPrivilegeAlarm, &out);
508 int ret = alarm_cancel_all();
509 if (ALARM_ERROR_NONE != ret) {
510 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out,
511 ("Platform unknown error: %d (%s)", ret, get_error_message(ret)));
518 PlatformResult AlarmManager::GetAlarm(int id, picojson::object& obj) {
522 return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid id.",
523 ("id is wrong: %d", id));
526 int ret = ALARM_ERROR_NONE;
527 app_control_h app_control = nullptr;
528 char* alarm_type = nullptr;
529 char* date_string = nullptr;
530 char* delay_string = nullptr;
531 notification_h notification_handle = nullptr;
534 app_control_destroy(app_control);
538 notification_free(notification_handle);
541 if (ALARM_ERROR_NONE != alarm_get_app_control(id, &app_control)) {
542 if (ALARM_ERROR_NONE != alarm_get_notification(id, ¬ification_handle)) {
543 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Alarm not found.",
544 ("Alarm not found: %d (%s)", ret, get_error_message(ret)));
546 PlatformResult platform_result = extension::notification::CommonNotification::GetAppControl(
547 notification_handle, &app_control);
548 if (!platform_result) {
549 return LogAndCreateResult(
550 platform_result.error_code(), platform_result.message().c_str(),
551 ("Failed to get AppControl: %d (%s)", static_cast<int>(platform_result.error_code()),
552 platform_result.message().c_str()));
557 obj.insert(std::make_pair("id", picojson::value(std::to_string(id))));
559 ret = app_control_get_extra_data(app_control, kAlarmKeyType, &alarm_type);
560 if (APP_CONTROL_ERROR_NONE != ret) {
561 // This is not always an error.
562 // Sometimes an application adds an alarm without alarm type set in appcontrol's extra data
563 // (possibly, when the alarm is set by a C service app, which doesn't set this value in extra
564 // data). In such cases, we return the alarm as an "Alarm" JS object, having only ID
565 LoggerW("Getting extra data (%s) failed: [%d](%s)", kAlarmKeyType, ret, get_error_message(ret));
566 return PlatformResult(ErrorCode::NO_ERROR);
569 if (!strcmp(alarm_type, kAlarmTypeValueAbsolute)) {
571 memset(&date, 0, sizeof(tm));
573 ret = app_control_get_extra_data(app_control, kAlarmAbsoluteDateKey, &date_string);
575 if (APP_CONTROL_ERROR_NONE != ret) {
576 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
577 ("Failed to get data: %d (%s)", ret, get_error_message(ret)));
580 sscanf(date_string, "%5d %5d %5d %5d %5d %5d %5d", &date.tm_year, &date.tm_mon, &date.tm_mday,
581 &date.tm_hour, &date.tm_min, &date.tm_sec, &date.tm_isdst);
584 obj.insert(std::make_pair("year", picojson::value(std::to_string(date.tm_year + 1900))));
585 obj.insert(std::make_pair("month", picojson::value(std::to_string(date.tm_mon))));
586 obj.insert(std::make_pair("day", picojson::value(std::to_string(date.tm_mday))));
587 obj.insert(std::make_pair("hour", picojson::value(std::to_string(date.tm_hour))));
588 obj.insert(std::make_pair("min", picojson::value(std::to_string(date.tm_min))));
589 obj.insert(std::make_pair("sec", picojson::value(std::to_string(date.tm_sec))));
593 ret = app_control_get_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey, &alarm_type);
594 if (APP_CONTROL_ERROR_NONE != ret) {
595 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
596 ("Getting data failed: %d (%s)", ret, get_error_message(ret)));
599 if (!strcmp(alarm_type, kAlarmAbsoluteReccurrenceTypeInterval)) {
600 ret = alarm_get_scheduled_period(id, &interval);
601 if (ALARM_ERROR_NONE != ret) {
602 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
603 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
606 obj.insert(std::make_pair("second", picojson::value(std::to_string(interval))));
607 } else if (!strcmp(alarm_type, kAlarmAbsoluteReccurrenceTypeByDayValue)) {
610 ret = alarm_get_scheduled_recurrence_week_flag(id, &byDayValue);
611 if (ALARM_ERROR_NONE != ret) {
612 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
613 ("Failed to get data: %d (%s)", ret, get_error_message(ret)));
616 picojson::array& array =
617 obj.insert(std::make_pair("second", picojson::value(picojson::array())))
618 .first->second.get<picojson::array>();
620 using namespace util;
621 if (byDayValue & ALARM_WEEK_FLAG_SUNDAY) array.push_back(picojson::value(kSundayShort));
622 if (byDayValue & ALARM_WEEK_FLAG_MONDAY) array.push_back(picojson::value(kMondayShort));
623 if (byDayValue & ALARM_WEEK_FLAG_TUESDAY) array.push_back(picojson::value(kTuesdayShort));
624 if (byDayValue & ALARM_WEEK_FLAG_WEDNESDAY) array.push_back(picojson::value(kWednesdayShort));
625 if (byDayValue & ALARM_WEEK_FLAG_THURSDAY) array.push_back(picojson::value(kThuesdayShort));
626 if (byDayValue & ALARM_WEEK_FLAG_FRIDAY) array.push_back(picojson::value(kFridayShort));
627 if (byDayValue & ALARM_WEEK_FLAG_SATURDAY) array.push_back(picojson::value(kSaturdayShort));
630 obj.insert(std::make_pair("type", picojson::value(kAlarmAbsolute)));
632 } else if (!strcmp(alarm_type, kAlarmTypeValueRelative)) {
635 ret = alarm_get_scheduled_period(id, &interval);
636 if (ALARM_ERROR_NONE != ret) {
637 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
638 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
641 int ret_app = app_control_get_extra_data(app_control, kAlarmRelativeDelayKey, &delay_string);
642 if (APP_CONTROL_ERROR_NONE != ret_app) {
643 return LogAndCreateResult(
644 ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
645 ("Failed to get data: %d (%s)", ret_app, get_error_message(ret_app)));
648 obj.insert(std::make_pair("type", picojson::value(kAlarmRelative)));
649 obj.insert(std::make_pair("delay", picojson::value(delay_string)));
651 // according to documentation interval will not be lower than 600,
652 // thus 0 from native means period wasn't set by user
653 obj.insert(std::make_pair("period", picojson::value(std::to_string(interval))));
656 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.");
659 return PlatformResult(ErrorCode::NO_ERROR);
662 void AlarmManager::Get(const picojson::value& args, picojson::object& out) {
667 if (args.contains("id") && args.get("id").is<double>()) {
668 id = static_cast<int>(args.get("id").get<double>());
671 picojson::value result = picojson::value(picojson::object());
672 picojson::object& result_obj = result.get<picojson::object>();
674 PlatformResult platform_result = GetAlarm(id, result_obj);
676 if (!platform_result) {
677 LogAndReportError(platform_result, &out);
679 ReportSuccess(result, out);
683 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
684 void AlarmManager::GetAlarmNotification(const picojson::value& args, picojson::object& out) {
685 using namespace extension::notification;
689 int ret = ALARM_ERROR_NONE;
690 notification_h notification_handle = nullptr;
691 PlatformResult platform_result = PlatformResult(ErrorCode::NO_ERROR);
694 notification_free(notification_handle);
697 if (args.contains("id") && args.get("id").is<double>()) {
698 alarm_id = static_cast<int>(args.get("id").get<double>());
701 ret = alarm_get_notification(alarm_id, ¬ification_handle);
703 if (ALARM_ERROR_NONE != ret) {
704 if (ALARM_ERROR_INVALID_PARAMETER == ret) {
706 PlatformResult(ErrorCode::NOT_FOUND_ERR, "Alarm with given ID was not found.");
708 platform_result = PlatformResult(ErrorCode::ABORT_ERR, "Failed to get notification.");
710 LogAndReportError(platform_result, &out);
713 app_control_h app_control = nullptr;
714 platform_result = CommonNotification::GetAppControl(notification_handle, &app_control);
716 if (!platform_result) {
717 LogAndReportError(platform_result, &out);
720 picojson::value result = picojson::value(picojson::object());
721 picojson::object& result_obj = result.get<picojson::object>();
723 platform_result = UserNotification::ToJson(-1, notification_handle, app_control, &result_obj);
725 if (ALARM_ERROR_NONE != ret) {
726 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Failed ToJson()."), &out);
729 ReportSuccess(result, out);
732 static bool AlarmIterateCB(int alarm_id, void* user_data) {
735 std::vector<int>* alarm_ids = reinterpret_cast<std::vector<int>*>(user_data);
737 alarm_ids->push_back(alarm_id);
742 void AlarmManager::GetAll(const picojson::value& args, picojson::object& out) {
744 std::vector<int> alarm_ids;
745 int ret = alarm_foreach_registered_alarm(AlarmIterateCB, &alarm_ids);
747 if (ALARM_ERROR_NONE != ret) {
748 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out,
749 ("Platform unknown error: %d (%s)", ret, get_error_message(ret)));
753 picojson::value result_array = picojson::value(picojson::array());
754 picojson::array& array_obj = result_array.get<picojson::array>();
756 for (size_t i = 0; i < alarm_ids.size(); i++) {
757 picojson::value result = picojson::value(picojson::object());
758 picojson::object& obj = result.get<picojson::object>();
760 PlatformResult platform_result = GetAlarm(alarm_ids.at(i), obj);
761 if (!platform_result) {
762 LogAndReportError(platform_result, &out, ("Failed GetAlarm()"));
765 array_obj.push_back(result);
768 ReportSuccess(result_array, out);
771 void AlarmManager::GetRemainingSeconds(const picojson::value& args, picojson::object& out) {
781 if (args.contains("id") && args.get("id").is<double>()) {
782 id = static_cast<int>(args.get("id").get<double>());
785 picojson::value result = picojson::value(picojson::object());
786 picojson::object& result_obj = result.get<picojson::object>();
788 int ret = alarm_get_scheduled_date(id, &date);
789 if (ALARM_ERROR_NONE != ret) {
790 LoggerI("alarm_get_scheduled_date error: %d (%s)", ret, get_error_message(ret));
791 if (ALARM_ERROR_INVALID_PARAMETER == ret || ALARM_ERROR_CONNECTION_FAIL == ret) {
792 result_obj.insert(std::make_pair("seconds", picojson::value()));
793 ReportSuccess(result, out);
796 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out);
801 alarm_get_current_time(¤t);
802 next_time = mktime(&date);
803 current_time = mktime(¤t);
805 long seconds = next_time - current_time;
807 result_obj.insert(std::make_pair("seconds", picojson::value(std::to_string(seconds))));
808 ReportSuccess(result, out);
811 void AlarmManager::GetNextScheduledDate(const picojson::value& args, picojson::object& out) {
815 if (args.contains("id") && args.get("id").is<double>()) {
816 id = static_cast<int>(args.get("id").get<double>());
820 int ret = alarm_get_scheduled_date(id, &date);
822 picojson::value result = picojson::value(picojson::object());
823 picojson::object& result_obj = result.get<picojson::object>();
825 if (ALARM_ERROR_NONE != ret) {
826 result_obj.insert(std::make_pair("year", picojson::value()));
827 ReportSuccess(result, out);
832 ret = alarm_get_current_time(&curr_date);
833 if (ALARM_ERROR_NONE != ret || mktime(&date) < mktime(&curr_date)) {
834 result_obj.insert(std::make_pair("year", picojson::value()));
835 ReportSuccess(result, out);
839 // tm struct contains years since 1900
840 // there is added 1900 to tm_year to return proper date
841 result_obj.insert(std::make_pair("year", picojson::value(std::to_string(date.tm_year + 1900))));
842 result_obj.insert(std::make_pair("month", picojson::value(std::to_string(date.tm_mon))));
843 result_obj.insert(std::make_pair("day", picojson::value(std::to_string(date.tm_mday))));
844 result_obj.insert(std::make_pair("hour", picojson::value(std::to_string(date.tm_hour))));
845 result_obj.insert(std::make_pair("min", picojson::value(std::to_string(date.tm_min))));
846 result_obj.insert(std::make_pair("sec", picojson::value(std::to_string(date.tm_sec))));
848 ReportSuccess(result, out);
852 } // namespace extension