2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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.
19 #include <scope_mutex.h>
20 #include <timer_mgr.h>
21 #include "timer_mgr_impl.h"
23 #define IDENTIFIER "contextd"
25 struct listener_info_s {
27 ctx::timer_listener_iface* listener;
31 typedef std::map<alarm_id_t, listener_info_s> listener_map_t;
32 static listener_map_t *listener_map = NULL;
33 static GMutex listener_map_mutex;
35 static int generate_timer_id()
48 static int alarm_expired_cb(alarm_id_t alarm_id, void* cb_data)
51 ctx::timer_listener_iface *listener = NULL;
55 ctx::scope_mutex sm1(&listener_map_mutex);
56 listener_map_t::iterator mit = listener_map->find(alarm_id);
57 IF_FAIL_RETURN_TAG(mit != listener_map->end(), 0, _W, "Unknown Alarm %d", alarm_id);
58 timer_id = mit->second.timer_id;
59 listener = mit->second.listener;
60 user_data = mit->second.user_data;
63 _D("Timer %d expired", timer_id);
64 bool repeat = listener->on_timer_expired(timer_id, user_data);
67 _D("Stop repeating Timer %d (Alarm %d)", timer_id, alarm_id);
68 ctx::scope_mutex sm2(&listener_map_mutex);
69 alarmmgr_remove_alarm(alarm_id);
70 listener_map->erase(alarm_id);
76 ctx::timer_manager_impl::timer_manager_impl()
81 ctx::timer_manager_impl::~timer_manager_impl()
86 bool ctx::timer_manager_impl::init()
88 IF_FAIL_RETURN_TAG(!initialized, true, _W, "Re-initialization");
90 listener_map = new(std::nothrow) listener_map_t;
91 IF_FAIL_RETURN_TAG(listener_map, false, _E, "Memory allocation failed");
93 int result = alarmmgr_init(IDENTIFIER);
94 IF_FAIL_RETURN_TAG(result == ALARMMGR_RESULT_SUCCESS, false, _E, "Alarm manager initialization failed");
96 result = alarmmgr_set_cb(alarm_expired_cb, this);
97 if (result != ALARMMGR_RESULT_SUCCESS) {
99 _E("Alarm callback registration failed");
103 alarmmgr_remove_all();
108 void ctx::timer_manager_impl::release()
111 alarmmgr_remove_all();
119 int ctx::timer_manager_impl::set_for(int interval, timer_listener_iface* listener, void* user_data)
121 IF_FAIL_RETURN_TAG(interval > 0 && listener, false, _E, "Invalid parameter");
127 // Implementation for Tizen 2.3
130 // time_t is in seconds.. It is the POSIX specification.
131 trigger_time += (interval * 60);
133 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, trigger_time, interval * 60, NULL, &alarm_id);
136 result = alarmmgr_add_periodic_alarm_withcb(interval, QUANTUMIZE, alarm_expired_cb, this, &alarm_id);
137 IF_FAIL_RETURN_TAG(result == ALARMMGR_RESULT_SUCCESS, ERR_OPERATION_FAILED, _E, "Alarm initialization failed");
139 ctx::scope_mutex sm(&listener_map_mutex);
141 listener_info_s info;
142 info.timer_id = generate_timer_id();
143 info.listener = listener;
144 info.user_data = user_data;
145 (*listener_map)[alarm_id] = info;
147 _D("Timer %d was set for %dm interval", info.timer_id, interval);
149 return info.timer_id;
152 int ctx::timer_manager_impl::set_at(int hour, int min, int day_of_week, timer_listener_iface* listener, void* user_data)
155 hour < 24 && hour >= 0 &&
156 min < 60 && min >= 0 &&
157 day_of_week > 0 && day_of_week <= timer_manager::EVERYDAY &&
158 listener, false, _E, "Invalid parameter");
161 if (day_of_week & timer_manager::SUN) repeat |= ALARM_WDAY_SUNDAY;
162 if (day_of_week & timer_manager::MON) repeat |= ALARM_WDAY_MONDAY;
163 if (day_of_week & timer_manager::TUE) repeat |= ALARM_WDAY_TUESDAY;
164 if (day_of_week & timer_manager::WED) repeat |= ALARM_WDAY_WEDNESDAY;
165 if (day_of_week & timer_manager::THU) repeat |= ALARM_WDAY_THURSDAY;
166 if (day_of_week & timer_manager::FRI) repeat |= ALARM_WDAY_FRIDAY;
167 if (day_of_week & timer_manager::SAT) repeat |= ALARM_WDAY_SATURDAY;
169 alarm_entry_t *alarm_info = alarmmgr_create_alarm();
170 IF_FAIL_RETURN_TAG(alarm_info, ERR_OPERATION_FAILED, _E, "Memory allocation failed");
173 struct tm current_tm;
176 localtime_r(¤t_time, ¤t_tm);
178 alarm_date_t alarm_time;
179 alarm_time.year = current_tm.tm_year + 1900;
180 alarm_time.month = current_tm.tm_mon + 1;
181 alarm_time.day = current_tm.tm_mday;
182 alarm_time.hour = hour;
183 alarm_time.min = min;
186 alarmmgr_set_time(alarm_info, alarm_time);
187 alarmmgr_set_repeat_mode(alarm_info, ALARM_REPEAT_MODE_WEEKLY, repeat);
188 alarmmgr_set_type(alarm_info, ALARM_TYPE_VOLATILE);
191 int ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
192 alarmmgr_free_alarm(alarm_info);
194 IF_FAIL_RETURN_TAG(ret == ALARMMGR_RESULT_SUCCESS, ERR_OPERATION_FAILED, _E, "Alarm initialization failed");
196 ctx::scope_mutex sm(&listener_map_mutex);
198 listener_info_s info;
199 info.timer_id = generate_timer_id();
200 info.listener = listener;
201 info.user_data = user_data;
203 (*listener_map)[alarm_id] = info;
205 _D("Timer %d was set at %02d:%02d:00 (day of week: %#x)", info.timer_id, hour, min, day_of_week);
207 return info.timer_id;
210 void ctx::timer_manager_impl::remove(int timer_id)
212 ctx::scope_mutex sm(&listener_map_mutex);
214 listener_map_t::iterator it;
215 for (it = listener_map->begin(); it != listener_map->end(); ++it) {
216 if (it->second.timer_id == timer_id) {
217 alarmmgr_remove_alarm(it->first);
218 listener_map->erase(it);
219 _D("Timer %d was removed", timer_id);