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) || defined(TIZEN_COMMON)
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) || defined(TIZEN_COMMON)
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 obj.insert(std::make_pair("id", picojson::value(std::to_string(id))));
575 ret = app_control_get_extra_data(app_control, kAlarmKeyType, &alarm_type);
576 if (APP_CONTROL_ERROR_NONE != ret) {
577 // This is not always an error.
578 // Sometimes an application adds an alarm without alarm type set in appcontrol's extra data
579 // (possibly, when the alarm is set by a C service app, which doesn't set this value in extra
580 // data). In such cases, we return the alarm as an "Alarm" JS object, having only ID
581 LoggerW("Getting extra data (%s) failed: [%d](%s)", kAlarmKeyType, ret, get_error_message(ret));
582 return PlatformResult(ErrorCode::NO_ERROR);
585 if (!strcmp(alarm_type, kAlarmTypeValueAbsolute)) {
587 memset(&date, 0, sizeof(tm));
589 ret = app_control_get_extra_data(app_control, kAlarmAbsoluteDateKey, &date_string);
591 if (APP_CONTROL_ERROR_NONE != ret) {
592 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
593 ("Failed to get data: %d (%s)", ret, get_error_message(ret)));
596 sscanf(date_string, "%5d %5d %5d %5d %5d %5d %5d", &date.tm_year, &date.tm_mon, &date.tm_mday,
597 &date.tm_hour, &date.tm_min, &date.tm_sec, &date.tm_isdst);
600 obj.insert(std::make_pair("year", picojson::value(std::to_string(date.tm_year + 1900))));
601 obj.insert(std::make_pair("month", picojson::value(std::to_string(date.tm_mon))));
602 obj.insert(std::make_pair("day", picojson::value(std::to_string(date.tm_mday))));
603 obj.insert(std::make_pair("hour", picojson::value(std::to_string(date.tm_hour))));
604 obj.insert(std::make_pair("min", picojson::value(std::to_string(date.tm_min))));
605 obj.insert(std::make_pair("sec", picojson::value(std::to_string(date.tm_sec))));
609 ret = app_control_get_extra_data(app_control, kAlarmAbsoluteRecurrenceTypeKey, &alarm_type);
610 if (APP_CONTROL_ERROR_NONE != ret) {
611 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
612 ("Getting data failed: %d (%s)", ret, get_error_message(ret)));
615 if (!strcmp(alarm_type, kAlarmAbsoluteReccurrenceTypeInterval)) {
616 ret = alarm_get_scheduled_period(id, &interval);
617 if (ALARM_ERROR_NONE != ret) {
618 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
619 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
622 obj.insert(std::make_pair("second", picojson::value(std::to_string(interval))));
623 } else if (!strcmp(alarm_type, kAlarmAbsoluteReccurrenceTypeByDayValue)) {
626 ret = alarm_get_scheduled_recurrence_week_flag(id, &byDayValue);
627 if (ALARM_ERROR_NONE != ret) {
628 return LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
629 ("Failed to get data: %d (%s)", ret, get_error_message(ret)));
632 picojson::array& array =
633 obj.insert(std::make_pair("second", picojson::value(picojson::array())))
634 .first->second.get<picojson::array>();
636 using namespace util;
637 if (byDayValue & ALARM_WEEK_FLAG_SUNDAY) array.push_back(picojson::value(kSundayShort));
638 if (byDayValue & ALARM_WEEK_FLAG_MONDAY) array.push_back(picojson::value(kMondayShort));
639 if (byDayValue & ALARM_WEEK_FLAG_TUESDAY) array.push_back(picojson::value(kTuesdayShort));
640 if (byDayValue & ALARM_WEEK_FLAG_WEDNESDAY) array.push_back(picojson::value(kWednesdayShort));
641 if (byDayValue & ALARM_WEEK_FLAG_THURSDAY) array.push_back(picojson::value(kThuesdayShort));
642 if (byDayValue & ALARM_WEEK_FLAG_FRIDAY) array.push_back(picojson::value(kFridayShort));
643 if (byDayValue & ALARM_WEEK_FLAG_SATURDAY) array.push_back(picojson::value(kSaturdayShort));
646 obj.insert(std::make_pair("type", picojson::value(kAlarmAbsolute)));
648 } else if (!strcmp(alarm_type, kAlarmTypeValueRelative)) {
651 ret = alarm_get_scheduled_period(id, &interval);
652 if (ALARM_ERROR_NONE != ret) {
653 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.",
654 ("Unknown error occurred: %d (%s)", ret, get_error_message(ret)));
657 int ret_app = app_control_get_extra_data(app_control, kAlarmRelativeDelayKey, &delay_string);
658 if (APP_CONTROL_ERROR_NONE != ret_app) {
659 return LogAndCreateResult(
660 ErrorCode::NOT_FOUND_ERR, "Failed to get data.",
661 ("Failed to get data: %d (%s)", ret_app, get_error_message(ret_app)));
664 obj.insert(std::make_pair("type", picojson::value(kAlarmRelative)));
665 obj.insert(std::make_pair("delay", picojson::value(delay_string)));
667 // according to documentation interval will not be lower than 600,
668 // thus 0 from native means period wasn't set by user
669 obj.insert(std::make_pair("period", picojson::value(std::to_string(interval))));
672 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.");
675 return PlatformResult(ErrorCode::NO_ERROR);
678 void AlarmManager::Get(const picojson::value& args, picojson::object& out) {
683 if (args.contains("id") && args.get("id").is<double>()) {
684 id = static_cast<int>(args.get("id").get<double>());
687 picojson::value result = picojson::value(picojson::object());
688 picojson::object& result_obj = result.get<picojson::object>();
690 PlatformResult platform_result = GetAlarm(id, result_obj);
692 if (!platform_result) {
693 LogAndReportError(platform_result, &out);
695 ReportSuccess(result, out);
699 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE) || defined(TIZEN_COMMON)
700 void AlarmManager::GetAlarmNotification(const picojson::value& args, picojson::object& out) {
701 using namespace extension::notification;
705 int ret = ALARM_ERROR_NONE;
706 notification_h notification_handle = nullptr;
707 PlatformResult platform_result = PlatformResult(ErrorCode::NO_ERROR);
710 notification_free(notification_handle);
713 if (args.contains("id") && args.get("id").is<double>()) {
714 alarm_id = static_cast<int>(args.get("id").get<double>());
717 ret = alarm_get_notification(alarm_id, ¬ification_handle);
719 if (ALARM_ERROR_NONE != ret) {
720 if (ALARM_ERROR_INVALID_PARAMETER == ret) {
722 PlatformResult(ErrorCode::NOT_FOUND_ERR, "Alarm with given ID was not found.");
724 platform_result = PlatformResult(ErrorCode::ABORT_ERR, "Failed to get notification.");
726 LogAndReportError(platform_result, &out);
729 app_control_h app_control = nullptr;
730 platform_result = CommonNotification::GetAppControl(notification_handle, &app_control);
732 if (!platform_result) {
733 LogAndReportError(platform_result, &out);
736 picojson::value result = picojson::value(picojson::object());
737 picojson::object& result_obj = result.get<picojson::object>();
739 platform_result = UserNotification::ToJson(-1, notification_handle, app_control, &result_obj);
741 if (ALARM_ERROR_NONE != ret) {
742 LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Failed ToJson()."), &out);
745 ReportSuccess(result, out);
748 static bool AlarmIterateCB(int alarm_id, void* user_data) {
751 std::vector<int>* alarm_ids = reinterpret_cast<std::vector<int>*>(user_data);
753 alarm_ids->push_back(alarm_id);
758 void AlarmManager::GetAll(const picojson::value& args, picojson::object& out) {
760 std::vector<int> alarm_ids;
761 int ret = alarm_foreach_registered_alarm(AlarmIterateCB, &alarm_ids);
763 if (ALARM_ERROR_NONE != ret) {
764 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out,
765 ("Platform unknown error: %d (%s)", ret, get_error_message(ret)));
769 picojson::value result_array = picojson::value(picojson::array());
770 picojson::array& array_obj = result_array.get<picojson::array>();
772 for (size_t i = 0; i < alarm_ids.size(); i++) {
773 picojson::value result = picojson::value(picojson::object());
774 picojson::object& obj = result.get<picojson::object>();
776 PlatformResult platform_result = GetAlarm(alarm_ids.at(i), obj);
777 if (!platform_result) {
778 LogAndReportError(platform_result, &out, ("Failed GetAlarm()"));
781 array_obj.push_back(result);
784 ReportSuccess(result_array, out);
787 void AlarmManager::GetRemainingSeconds(const picojson::value& args, picojson::object& out) {
797 if (args.contains("id") && args.get("id").is<double>()) {
798 id = static_cast<int>(args.get("id").get<double>());
801 picojson::value result = picojson::value(picojson::object());
802 picojson::object& result_obj = result.get<picojson::object>();
804 int ret = alarm_get_scheduled_date(id, &date);
805 if (ALARM_ERROR_NONE != ret) {
806 LoggerI("alarm_get_scheduled_date error: %d (%s)", ret, get_error_message(ret));
807 if (ALARM_ERROR_INVALID_PARAMETER == ret || ALARM_ERROR_CONNECTION_FAIL == ret) {
808 result_obj.insert(std::make_pair("seconds", picojson::value()));
809 ReportSuccess(result, out);
812 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform unknown error."), &out);
817 alarm_get_current_time(¤t);
818 next_time = mktime(&date);
819 current_time = mktime(¤t);
821 long seconds = next_time - current_time;
823 result_obj.insert(std::make_pair("seconds", picojson::value(std::to_string(seconds))));
824 ReportSuccess(result, out);
827 void AlarmManager::GetNextScheduledDate(const picojson::value& args, picojson::object& out) {
831 if (args.contains("id") && args.get("id").is<double>()) {
832 id = static_cast<int>(args.get("id").get<double>());
836 int ret = alarm_get_scheduled_date(id, &date);
838 picojson::value result = picojson::value(picojson::object());
839 picojson::object& result_obj = result.get<picojson::object>();
841 if (ALARM_ERROR_NONE != ret) {
842 result_obj.insert(std::make_pair("year", picojson::value()));
843 ReportSuccess(result, out);
848 ret = alarm_get_current_time(&curr_date);
849 if (ALARM_ERROR_NONE != ret || mktime(&date) < mktime(&curr_date)) {
850 result_obj.insert(std::make_pair("year", picojson::value()));
851 ReportSuccess(result, out);
855 // tm struct contains years since 1900
856 // there is added 1900 to tm_year to return proper date
857 result_obj.insert(std::make_pair("year", picojson::value(std::to_string(date.tm_year + 1900))));
858 result_obj.insert(std::make_pair("month", picojson::value(std::to_string(date.tm_mon))));
859 result_obj.insert(std::make_pair("day", picojson::value(std::to_string(date.tm_mday))));
860 result_obj.insert(std::make_pair("hour", picojson::value(std::to_string(date.tm_hour))));
861 result_obj.insert(std::make_pair("min", picojson::value(std::to_string(date.tm_min))));
862 result_obj.insert(std::make_pair("sec", picojson::value(std::to_string(date.tm_sec))));
864 ReportSuccess(result, out);
868 } // namespace extension