2 * This file is part of TimedSilencer.
4 * TimedSilencer is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * TimedSilencer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with TimedSilencer. If not, see <http://www.gnu.org/licenses/>.
18 #ifndef ALARMD_TALKER_H
19 #define ALARMD_TALKER_H
25 #include <alarmd/libalarm.h>
26 #include <dbus-1.0/dbus/dbus-protocol.h>
29 #include "phone_profile.h"
30 #include "dbus_backend.h"
31 #include "profileevent.h"
33 // Alarmd documentation found at:
34 // http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Using_Generic_Platform_Components/Alarm_Framework
35 class AlarmdBackend : public QObject {
38 static time_t toTime_t(const QTime &t) {
39 int time_diff = QTime::currentTime().secsTo(t);
44 qDebug("time diff: %d", time_diff);
45 return (time_t) time(0) + time_diff;
48 static uint32_t daysToMask(QList<int> days) {
50 foreach(const int& d, days) {
53 mask |= ALARM_RECUR_WDAY_MON;
56 mask |= ALARM_RECUR_WDAY_TUE;
59 mask |= ALARM_RECUR_WDAY_WED;
62 mask |= ALARM_RECUR_WDAY_THU;
65 mask |= ALARM_RECUR_WDAY_FRI;
68 mask |= ALARM_RECUR_WDAY_SAT;
71 mask |= ALARM_RECUR_WDAY_SUN;
74 Q_ASSERT(0); // Should never go here
75 mask |= ALARM_RECUR_WDAY_ALL;
83 // Is only called on program uninstall
84 static void deleteAllEvents() {
85 QSettings settings("TimedSilencer", "TimedSilencer");
86 QHash<QString, QVariant> events = settings.value("events").toHash();
87 foreach(QVariant var_ev, events) {
88 ProfileEvent *pe = ProfileEvent::load(var_ev);
89 foreach(const long &cookie, pe->alarmd_cookies) {
90 qDebug("Unregistering event with cookie %ld", cookie);
91 alarmd_event_del(cookie);
95 // Delete possible orphan events
96 cookie_t *orphan_cookies = alarmd_event_query(0,0,0,0, "TimedSilencer");
98 while(orphan_cookies && orphan_cookies[i] != 0) {
99 alarmd_event_del(orphan_cookies[i]);
104 settings.setValue("events", events);
107 static void deleteOrphanEvents(QList<long> known_cookies) {
108 cookie_t *orphan_cookies = alarmd_event_query(0,0,0,0, "TimedSilencer");
110 while(orphan_cookies && orphan_cookies[i] != 0) {
111 if(!known_cookies.contains(orphan_cookies[i]))
112 alarmd_event_del(orphan_cookies[i]);
117 static void deleteEvents(QByteArray event_id) {
118 deleteEvents(ProfileEvent::findByID(event_id));
121 static void deleteEvents(ProfileEvent *pe) {
122 // unregistering events
123 foreach(const long &cookie, pe->alarmd_cookies) {
124 qDebug("Unregistering event with cookie %ld", cookie);
125 alarmd_event_del(cookie);
127 pe->alarmd_cookies.clear();
128 ProfileEvent::clearCookies(pe->getID());
131 static void setProfileEvents(QByteArray event_id) {
132 setProfileEvents(ProfileEvent::findByID(event_id));
135 static bool checkIfStillActive(ProfileEvent *pe) {
136 Q_ASSERT(pe->activated);
137 foreach(const long &cookie, pe->alarmd_cookies) {
138 alarm_event_t *eve = 0;
139 if((eve = alarmd_event_get(cookie)) != 0) {
140 // Free all dynamic memory associated with the alarm event
141 alarm_event_delete(eve);
148 static void setProfileEvents(ProfileEvent *pe) {
149 Q_ASSERT(pe->activated);
150 // First clear old alarmd events
151 foreach(const long &cookie, pe->alarmd_cookies) {
152 qDebug("Unregistering event with cookie %ld", cookie);
153 alarmd_event_del(cookie);
155 pe->alarmd_cookies.clear();
156 // Then setting new events
157 long c1 = newProfileEvent(SILENT, pe->from_time, pe->days);
160 pe->alarmd_cookies << c1;
161 long c2 = newProfileEvent(GENERAL, pe->to_time, pe->days);
164 pe->alarmd_cookies << c2;
166 ProfileEvent::setCookies(pe->getID(), pe->alarmd_cookies);
167 // Set Profile to SILENT if we are currently in the silent time slot
168 if(pe->affectsCurrentTime())
169 DBusBackend::setProfile(SILENT);
173 static long newProfileEvent(Profile p, const QTime &event_time, QList<int> days) {
174 Q_ASSERT(!days.empty());
175 qDebug("Registering an event");
176 if(days.empty()) days << NEVER;
177 // Create the default alarm struct.
178 alarm_event_t *newEvent = alarm_event_create();
180 alarm_event_set_alarm_appid(newEvent, "TimedSilencer");
183 alarm_event_set_title(newEvent, "silent_profile");
185 alarm_event_set_title(newEvent, "general_profile");
187 if(days.first() == EVERY_DAY) {
188 newEvent->recur_secs = 86400; // 24 hours
189 newEvent->recur_count = -1; // Reoccur infinitely
190 newEvent->alarm_time = toTime_t(event_time); // Set event time
192 if(days.first() == NEVER) {
193 newEvent->alarm_time = toTime_t(event_time); // Set event time
195 qDebug("Using the new recurrence API");
196 newEvent->recur_count = -1;
197 newEvent->recur_secs = 0; // We re not using this way for recurrence
198 alarm_recur_t* recur = alarm_event_add_recurrences(newEvent, 1);
200 recur->special = ALARM_RECUR_SPECIAL_NONE;
201 recur->mask_mon = ALARM_RECUR_MON_ALL;
202 recur->mask_mday = ALARM_RECUR_MDAY_ALL;
203 recur->mask_hour = (1ul << event_time.hour());
204 recur->mask_min = (1ull << event_time.minute());
205 recur->mask_wday = daysToMask(days);
206 Q_ASSERT(newEvent->recurrence_cnt == 1);
209 //Add 1 action to our alarm event, and assign it to the "act" variable
210 alarm_action_t *act = alarm_event_add_actions(newEvent, 1);
211 // Actions are documented here:
212 // http://maemo.org/api_refs/5.0/5.0-final/libalarm/libalarm_8h.html#cc8e6f439d134448001132132476683c910f7626ec85a4170659b53fa2f0abc7
213 //Setup this action to be an "DBus command" one; also set it up to use DBUS auto-activation.
214 act->flags = ALARM_ACTION_WHEN_TRIGGERED | ALARM_ACTION_DBUS_USE_ACTIVATION | ALARM_ACTION_TYPE_DBUS;
216 //Setup the DBus params for this action
217 alarm_action_set_dbus_interface(act, "com.nokia.profiled");
218 alarm_action_set_dbus_service(act, "com.nokia.profiled");
219 alarm_action_set_dbus_path(act, "/com/nokia/profiled");
220 alarm_action_set_dbus_name(act, "set_profile");
223 const char* param = "silent";
224 alarm_action_set_dbus_args(act, DBUS_TYPE_STRING, ¶m, DBUS_TYPE_INVALID);
226 const char* param = "general";
227 alarm_action_set_dbus_args(act, DBUS_TYPE_STRING, ¶m, DBUS_TYPE_INVALID);
230 // Finally with everything setup, try to add your event to the alarm queue
231 long cookie = alarmd_event_add(newEvent);
232 // Free all dynamic memory associated with the alarm event
233 alarm_event_delete(newEvent);
238 #endif // ALARMD_TALKER_H