Major new release: Several events can now be defined and one can set events to occur...
[timedsilencer] / alarmd_backend.h
index 68b7fe9..8d8746b 100644 (file)
 #include <QTime>
 #include <QString>
 #include <QSettings>
+#include <QPair>
 #include <alarmd/libalarm.h>
 #include <dbus-1.0/dbus/dbus-protocol.h>
 #include <time.h>
 
 #include "phone_profile.h"
+#include "dbus_backend.h"
+#include "profileevent.h"
 
 // Alarmd documentation found at:
 // http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Using_Generic_Platform_Components/Alarm_Framework
@@ -42,45 +45,117 @@ private:
     return (time_t) time(0) + time_diff;
   }
 
+  static uint32_t daysToMask(QList<int> days) {
+    uint32_t mask = 0;
+    foreach(const int& d, days) {
+      switch(d) {
+      case MON:
+        mask |= ALARM_RECUR_WDAY_MON;
+        break;
+      case TUE:
+        mask |= ALARM_RECUR_WDAY_TUE;
+        break;
+      case WED:
+        mask |= ALARM_RECUR_WDAY_WED;
+        break;
+      case THU:
+        mask |= ALARM_RECUR_WDAY_THU;
+        break;
+      case FRI:
+        mask |= ALARM_RECUR_WDAY_FRI;
+        break;
+      case SAT:
+        mask |= ALARM_RECUR_WDAY_SAT;
+        break;
+      case SUN:
+        mask |= ALARM_RECUR_WDAY_SUN;
+        break;
+      default:
+        Q_ASSERT(0); // Should never go here
+        mask |= ALARM_RECUR_WDAY_ALL;
+        break;
+      }
+    }
+    return mask;
+  }
+
 public:
-  static void deleteEvents() {
-    // Get events cookies
+  // Is only called on program uninstall
+  static void deleteAllEvents() {
     QSettings settings("TimedSilencer", "TimedSilencer");
-    const cookie_t silent_cookie = settings.value("silencing_cookie", 0).toLongLong();
-    if(silent_cookie != 0) {
-      qDebug("Deleting silent profile event with cookie %ld", (long) silent_cookie);
-      alarmd_event_del(silent_cookie);
+    QHash<QString, QVariant> events = settings.value("events").toHash();
+    foreach(QVariant var_ev, events) {
+      ProfileEvent *pe = ProfileEvent::load(var_ev);
+      foreach(const long &cookie, pe->alarmd_cookies) {
+        qDebug("Unregistering event with cookie %ld", cookie);
+        alarmd_event_del(cookie);
+      }
+      delete pe;
     }
-    const cookie_t general_cookie = settings.value("unsilencing_cookie", 0).toLongLong();
-    if(general_cookie != 0) {
-      qDebug("Deleting general profile event with cookie %ld", (long) general_cookie);
-      alarmd_event_del(general_cookie);
+    // Save in QSettings
+    events.clear();
+    settings.setValue("events", events);
+  }
+
+  static void deleteEvents(QByteArray event_id) {
+    deleteEvents(ProfileEvent::findByID(event_id));
+  }
+
+  static void deleteEvents(ProfileEvent *pe) {
+    // unregistering events
+    foreach(const long &cookie, pe->alarmd_cookies) {
+      qDebug("Unregistering event with cookie %ld", cookie);
+      alarmd_event_del(cookie);
     }
+    pe->alarmd_cookies.clear();
+    ProfileEvent::clearCookies(pe->getID());
   }
 
-  static void setProfileEvent(Profile p, const QTime &event_time) {
-    // Get event cookie
-    QSettings settings("TimedSilencer", "TimedSilencer");
-    cookie_t cookie;
-    if(p == SILENT)
-      cookie = settings.value("silencing_cookie", 0).toLongLong();
-    else
-      cookie = settings.value("unsilencing_cookie", 0).toLongLong();
-    alarm_event_t *eve = 0;
-    if(cookie == 0 || (eve = alarmd_event_get(cookie)) == 0) {
-      qDebug("Profile event does not exist yet, creating it...");
-      // The event does not exist yet
-      newProfileEvent(p, event_time);
-      return;
+  static void setProfileEvents(QByteArray event_id) {
+    setProfileEvents(ProfileEvent::findByID(event_id));
+  }
+
+  static bool checkIfStillActive(ProfileEvent *pe) {
+    Q_ASSERT(pe->activated);
+    foreach(const long &cookie, pe->alarmd_cookies) {
+      alarm_event_t *eve = 0;
+      if((eve = alarmd_event_get(cookie)) != 0) {
+        // Free all dynamic memory associated with the alarm event
+        alarm_event_delete(eve);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  static void setProfileEvents(ProfileEvent *pe) {
+    Q_ASSERT(pe->activated);
+    // First clear old alarmd events
+    foreach(const long &cookie, pe->alarmd_cookies) {
+      qDebug("Unregistering event with cookie %ld", cookie);
+      alarmd_event_del(cookie);
     }
-    // Update existing event
-    qDebug("Updating profile event with cookie %ld", (long)cookie);
-    eve->alarm_time = toTime_t(event_time);
-    alarmd_event_update(eve);
+    pe->alarmd_cookies.clear();
+    // Then setting new events
+    long c1 = newProfileEvent(SILENT, pe->from_time, pe->days);
+    Q_ASSERT(c1 > 0);
+    if(c1 > 0)
+      pe->alarmd_cookies << c1;
+    long c2 = newProfileEvent(GENERAL, pe->to_time, pe->days);
+    Q_ASSERT(c2 > 0);
+    if(c2 > 0)
+      pe->alarmd_cookies << c2;
+    // Save in QSettings
+    ProfileEvent::setCookies(pe->getID(), pe->alarmd_cookies);
+    // Set Profile to SILENT if we are currently in the silent time slot
+    if(pe->affectsCurrentTime())
+      DBusBackend::setProfile(SILENT);
   }
 
 protected:
-  static void newProfileEvent(Profile p, const QTime &event_time) {
+  static long newProfileEvent(Profile p, const QTime &event_time, QList<int> days) {
+    Q_ASSERT(!days.empty());
+    if(days.empty()) days << NEVER;
     // Create the default alarm struct.
     alarm_event_t *newEvent = alarm_event_create();
     // Set the APP ID
@@ -91,9 +166,22 @@ protected:
     else
       alarm_event_set_title(newEvent, "general_profile");
     // Timing
-    newEvent->recur_secs = 86400; // 24 hours interval
-    newEvent->recur_count = -1; // Reoccur infinitely
-    newEvent->alarm_time = toTime_t(event_time);
+    if(days.first() == EVERY_DAY) {
+      newEvent->recur_secs = 86400; // 24 hours
+      newEvent->recur_count = -1; // Reoccur infinitely
+      newEvent->alarm_time = toTime_t(event_time); // Set event time
+    } else {
+      if(days.first() == NEVER) {
+        newEvent->alarm_time = toTime_t(event_time); // Set event time
+      } else {
+        newEvent->recur_secs = 0; // We re not using this way for recurrence
+        alarm_recur_t* recur = alarm_event_add_recurrences(newEvent, 1);
+        // Set event time
+        recur->mask_hour |= (1ul << event_time.hour());
+        recur->mask_min |= (1ull << event_time.minute());
+        recur->mask_wday |= daysToMask(days);
+      }
+    }
     //Add 1 action to our alarm event, and assign it to the "act" variable
     alarm_action_t *act = alarm_event_add_actions(newEvent, 1);
     // Actions are documented here:
@@ -116,20 +204,10 @@ protected:
     }
 
     // Finally with everything setup, try to add your event to the alarm queue
-    const cookie_t &cookie = alarmd_event_add(newEvent);
-    if(cookie != 0) {
-      // Save cookie
-      QSettings settings("TimedSilencer", "TimedSilencer");
-      if(p == SILENT) {
-        qDebug("Saving silent profile event cookie: %ld", (long)cookie);
-        settings.setValue("silencing_cookie", static_cast<const qlonglong>(cookie));
-      } else {
-        qDebug("Saving silent general event cookie: %ld", (long)cookie);
-        settings.setValue("unsilencing_cookie", static_cast<const qlonglong>(cookie));
-      }
-      return;
-    }
-    qDebug("ERROR: Failed to add profile event to the queue!");
+    long cookie = alarmd_event_add(newEvent);
+    // Free all dynamic memory associated with the alarm event
+    alarm_event_delete(newEvent);
+    return cookie;
   }
 };