TizenRefApp-8027 Implement snooze functionality in Model 28/115528/2
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Mon, 20 Feb 2017 08:15:59 +0000 (10:15 +0200)
committerAleksandr Sapozhnik <a.sapozhnik@samsung.com>
Mon, 20 Feb 2017 14:02:59 +0000 (06:02 -0800)
Change-Id: I2977e5ffb8f984fa5845a8fb4a26ca2fb5f26ec3
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
alarm-app/src/Alert/AlertView.cpp
alarm-svc/src/AlarmService.cpp
lib-common/inc/Common/Model/Alarm.h
lib-common/inc/Common/Model/AlarmDb.h
lib-common/src/Common/Model/Alarm.cpp
lib-common/src/Common/Model/AlarmBuilder.cpp
lib-common/src/Common/Model/AlarmConsumer.cpp

index bbeb7cb3dd86207098b6453ea61fb2a3c4a4ed3a..6ecc38077dd6b251529e373b303e153147c4eac0 100644 (file)
@@ -37,10 +37,12 @@ Evas_Object *AlertView::onCreate(Evas_Object *parent)
        elm_layout_file_set(layout, App::getResourcePath(PATH_ALERT_LAYOUT).c_str(), LAYOUT_ALERT);
        eext_rotary_object_event_callback_add(layout, makeCallback(&AlertView::onRotaryEvent), this);
 
-       elm_object_part_text_set(layout, PART_TIME, formatTime(m_Alarm.getDate(), TIME_TEXT_SIZE));
-       /* TODO: set original time if snoozed
-        * elm_object_part_text_set(layout, PART_ORIG_TIME, formatTime(m_Alarm.getDate(), ORIG_TIME_TEXT_SIZE));
-        */
+       if (m_Alarm.getSnoozeCount() > 0) {
+               elm_object_part_text_set(layout, PART_TIME, formatTime(m_Alarm.getSnoozeDate(), TIME_TEXT_SIZE));
+               elm_object_part_text_set(layout, PART_ORIG_TIME, formatTime(m_Alarm.getDate(), ORIG_TIME_TEXT_SIZE));
+       } else {
+               elm_object_part_text_set(layout, PART_TIME, formatTime(m_Alarm.getDate(), TIME_TEXT_SIZE));
+       }
 
        m_DismissButton = createButton(layout, PATH_ICON_DISMISS, { COLOR_BUTTON_DISMISS },
                        SIGNAL_SNOOZE_HIDE, SIGNAL_SNOOZE_SHOW);
@@ -103,14 +105,14 @@ Eina_Bool AlertView::onRotaryEvent(Evas_Object *obj, Eext_Rotary_Event_Info *eve
 
 void AlertView::onDismissClicked(Evas_Object *button, void *eventInfo)
 {
-       if (!m_Alarm.getRepeat()) {
-               m_Alarm.setEnabled(false);
-               AlarmConsumer::getInstance().updateAlarm(m_Alarm, nullptr);
-       }
+       m_Alarm.dismiss();
+       AlarmConsumer::getInstance().updateAlarm(m_Alarm, nullptr);
        getPage()->close();
 }
 void AlertView::onSnoozeClicked(Evas_Object *button, void *eventInfo)
 {
+       m_Alarm.snooze();
+       AlarmConsumer::getInstance().updateAlarm(m_Alarm, nullptr);
        getPage()->close();
 }
 
index 1ae57696ece8f351640f8234de1014e839930aaf..f83d2707ec67fd5e74e72b51672a339604f58cd1 100755 (executable)
@@ -30,9 +30,9 @@
 #define FUNCTION_SET_ALARM "set_alarm"
 #define FUNCTION_UNSET_ALARM "unset_alarm"
 
-#define STATEMENT_SET_ALARM(column_alarm_id) \
+#define STATEMENT_SET_ALARM(column_alarm_id, column_date) \
        "UPDATE " TABLE_ALARMS " SET " column_alarm_id " = " \
-       FUNCTION_SET_ALARM "(new." COLUMN_ID ", new." COLUMN_DATE ", new." COLUMN_REPEAT ") " \
+       FUNCTION_SET_ALARM "(new." COLUMN_ID ", new." column_date ") " \
        "WHERE " COLUMN_ID " = new." COLUMN_ID ";"
 
 #define STATEMENT_UNSET_ALARM(column_alarm_id) \
@@ -50,20 +50,23 @@ namespace
                        COLUMN_ALARM_ID     " INTEGER,"
                        COLUMN_DATE         " INTEGER,"
                        COLUMN_REPEAT       " INTEGER,"
-                       COLUMN_ENABLED      " INTEGER);"
+                       COLUMN_ENABLED      " INTEGER,"
+                       COLUMN_SNOOZE_ID    " INTEGER,"
+                       COLUMN_SNOOZE_DATE  " INTEGER,"
+                       COLUMN_SNOOZE_COUNT " INTEGER);"
 
                "CREATE TRIGGER alarm_inserted "
                        "AFTER INSERT ON " TABLE_ALARMS " "
                        "WHEN new." COLUMN_ENABLED " <> 0 "
                        "BEGIN "
-                               STATEMENT_SET_ALARM(COLUMN_ALARM_ID)
+                               STATEMENT_SET_ALARM(COLUMN_ALARM_ID, COLUMN_DATE)
                        "END;"
 
                "CREATE TRIGGER alarm_enabled "
                        "AFTER UPDATE ON " TABLE_ALARMS " "
                        "WHEN old." COLUMN_ENABLED " <> new." COLUMN_ENABLED " AND new." COLUMN_ENABLED " <> 0 "
                        "BEGIN "
-                               STATEMENT_SET_ALARM(COLUMN_ALARM_ID)
+                               STATEMENT_SET_ALARM(COLUMN_ALARM_ID, COLUMN_DATE)
                        "END;"
 
                "CREATE TRIGGER alarm_disabled "
@@ -73,13 +76,27 @@ namespace
                                STATEMENT_UNSET_ALARM(COLUMN_ALARM_ID)
                        "END;"
 
+               "CREATE TRIGGER alarm_snoozed "
+                       "AFTER UPDATE ON " TABLE_ALARMS " "
+                       "WHEN old." COLUMN_SNOOZE_DATE " <> new." COLUMN_SNOOZE_DATE " AND new." COLUMN_SNOOZE_DATE " > 0 "
+                       "BEGIN "
+                               STATEMENT_SET_ALARM(COLUMN_SNOOZE_ID, COLUMN_SNOOZE_DATE)
+                       "END;"
+
+               "CREATE TRIGGER alarm_unsnoozed "
+                       "AFTER UPDATE ON " TABLE_ALARMS " "
+                       "WHEN old." COLUMN_SNOOZE_DATE " <> new." COLUMN_SNOOZE_DATE " AND new." COLUMN_SNOOZE_DATE " <= 0 "
+                       "BEGIN "
+                               STATEMENT_UNSET_ALARM(COLUMN_SNOOZE_ID)
+                       "END;"
+
                "CREATE TRIGGER alarm_updated "
                        "AFTER UPDATE ON " TABLE_ALARMS " "
                        "WHEN old." COLUMN_ENABLED " <> 0 AND new." COLUMN_ENABLED " <> 0 "
                        "AND (old." COLUMN_DATE " <> new." COLUMN_DATE " OR old." COLUMN_REPEAT " <> new." COLUMN_REPEAT ") "
                        "BEGIN "
                                "SELECT " FUNCTION_UNSET_ALARM "(old." COLUMN_ALARM_ID ");"
-                               STATEMENT_SET_ALARM(COLUMN_ALARM_ID)
+                               STATEMENT_SET_ALARM(COLUMN_ALARM_ID, COLUMN_DATE)
                        "END;"
 
                "CREATE TRIGGER alarm_deleted "
@@ -87,6 +104,7 @@ namespace
                        "WHEN old." COLUMN_ENABLED " <> 0 "
                        "BEGIN "
                                "SELECT " FUNCTION_UNSET_ALARM "(old." COLUMN_ALARM_ID ");"
+                               "SELECT " FUNCTION_UNSET_ALARM "(old." COLUMN_SNOOZE_ID ");"
                        "END;";
 }
 
@@ -202,7 +220,7 @@ sqlite3 *AlarmService::initDatabase()
                }
        }
 
-       sqlite3_create_function(db, FUNCTION_SET_ALARM, 3, SQLITE_UTF8,
+       sqlite3_create_function(db, FUNCTION_SET_ALARM, 2, SQLITE_UTF8,
                        this, &AlarmService::setAlarm, nullptr, nullptr);
        sqlite3_create_function(db, FUNCTION_UNSET_ALARM, 1, SQLITE_UTF8,
                        this, &AlarmService::unsetAlarm, nullptr, nullptr);
@@ -239,7 +257,6 @@ void AlarmService::setAlarm(sqlite3_context *context, int argc, sqlite3_value **
 {
        int id = sqlite3_value_int(argv[0]);
        time_t time = sqlite3_value_int(argv[1]);
-       int repeat = sqlite3_value_int(argv[2]);
        tm date = *localtime(&time);
 
        auto request = App::AppControl("org.tizen.alarm.alert");
@@ -247,13 +264,8 @@ void AlarmService::setAlarm(sqlite3_context *context, int argc, sqlite3_value **
        request.addExtra(APP_CONTROL_DATA_ID, std::to_string(id).c_str());
 
        int alarmId = 0;
-       if (repeat) {
-               int err = alarm_schedule_with_recurrence_week_flag(request.getHandle(), &date, repeat, &alarmId);
-               WARN_IF_ERR(err, "alarm_schedule_with_recurrence_week_flag() failed.");
-       } else {
-               int err = alarm_schedule_once_at_date(request.getHandle(), &date, &alarmId);
-               WARN_IF_ERR(err, "alarm_schedule_once_at_date() failed.");
-       }
+       int err = alarm_schedule_once_at_date(request.getHandle(), &date, &alarmId);
+       WARN_IF_ERR(err, "alarm_schedule_once_at_date() failed.");
 
        sqlite3_result_int(context, alarmId);
 }
index a6ddd5e5f327172b0b1a7269b56fc2ac72d77e51..8c62520122b90a693ed371d0a0763c443d3bf4cd 100644 (file)
@@ -40,10 +40,8 @@ namespace Common
 
                        Alarm();
                        virtual ~Alarm() override;
-                       Alarm(const Alarm &other);
-                       Alarm &operator=(const Alarm &other);
-                       Alarm(Alarm &&other);
-                       Alarm &operator=(Alarm &&other);
+                       Alarm(const Alarm &that);
+                       Alarm &operator=(const Alarm &that);
 
                        /**
                         * @return Database ID.
@@ -65,6 +63,16 @@ namespace Common
                         */
                        bool isEnabled() const;
 
+                       /**
+                        * @return Snooze alarm time and date.
+                        */
+                       const tm &getSnoozeDate() const;
+
+                       /**
+                        * @return How many times alarm has been snoozed in the row.
+                        */
+                       int getSnoozeCount() const;
+
                        /**
                         * @brief Set alarm time.
                         * @param[in]   hour    Hours
@@ -84,6 +92,20 @@ namespace Common
                         */
                        void setEnabled(bool isEnabled);
 
+                       /**
+                        * @brief Snooze the alarm.
+                        * @details Schedules another alarm 5 min later.
+                        * @remark Alarm should be updated via AlarmConsumer for snooze to take effect.
+                        */
+                       void snooze();
+
+                       /**
+                        * @brief Dismiss the alarm.
+                        * @details Disables or reschedules the alarm depending on repeat value.
+                        * @remark Alarm should be updated via AlarmConsumer for dismiss to take effect.
+                        */
+                       void dismiss();
+
                        /**
                         * @brief Compare alarms by time.
                         * @param[in]   that    Alarm to compare with
@@ -93,6 +115,9 @@ namespace Common
 
                private:
                        friend class AlarmBuilder;
+                       void updateTime();
+                       void resetSnooze();
+
                        virtual void onStandalone(bool isStandalone) override;
                        virtual int onUpdate(void *data) override;
                        void onDataChanged(data_control_h provider,
@@ -104,6 +129,11 @@ namespace Common
                        tm m_Date;
                        int m_Repeat;
                        bool m_IsEnabled;
+
+                       tm m_SnoozeDate;
+                       int m_SnoozeCount;
+                       bool m_IsSnoozed;
+
                        int m_ChangeCallbackId;
                };
        }
index a0c8beb1b8e9b2d32e1c8b1936d6534d323e7e1e..213d7fc15954f9775b929e3571ac4bd968e51842 100644 (file)
 #define TABLE_ALARMS        "alarms"
 
 #define COLUMN_ID           "id"
-#define COLUMN_ALARM_ID     "alarm_id"  /**< Alarm API ID */
-#define COLUMN_DATE         "date"      /**< Time and date */
-#define COLUMN_REPEAT       "repeat"    /**< Weekly repeat mask */
-#define COLUMN_ENABLED      "enabled"   /**< Whether alarm is enabled */
+#define COLUMN_ALARM_ID     "alarm_id"      /**< Alarm API ID */
+#define COLUMN_SNOOZE_ID    "snooze_id"     /**< Alarm API ID for snoozed alarm */
+#define COLUMN_SNOOZE_COUNT "snooze_count"  /**< How many times alarm has been snoozed in the row */
+#define COLUMN_SNOOZE_DATE  "snooze_date"   /**< Snooze time and date */
+#define COLUMN_TIME         "time"          /**< Time without date in minutes */
+#define COLUMN_DATE         "date"          /**< Time and date */
+#define COLUMN_REPEAT       "repeat"        /**< Weekly repeat mask */
+#define COLUMN_ENABLED      "enabled"       /**< Whether alarm is enabled */
 
 #endif /* COMMON_MODEL_ALARM_DB_H */
index 3c9fa1774da44a915cd8343f8d46bb87bef8acd5..282a0db5993aa774cf9ef8e01defb1aed562d578 100644 (file)
 #include "Utils/Logger.h"
 
 #define DEFAULT_TIME 6, 0
+#define SNOOZE_TIME 5 * 60
+
 #define DAY_COUNT 7
 #define DAY_SECONDS 60 * 60 * 24
 
 using namespace Common::Model;
 
 Alarm::Alarm()
-       : m_Id(0), m_Repeat(0), m_IsEnabled(true), m_ChangeCallbackId(0)
+       : m_Id(0), m_Repeat(0), m_IsEnabled(true),
+         m_SnoozeDate{0}, m_SnoozeCount(0), m_IsSnoozed(false),
+         m_ChangeCallbackId(0)
 {
        setTime(DEFAULT_TIME);
 }
@@ -38,44 +42,23 @@ Alarm::~Alarm()
        data_control_remove_data_change_cb(AlarmConsumer::getInstance().getProvider(), m_ChangeCallbackId);
 }
 
-Alarm::Alarm(const Alarm &other)
-       : m_Id(other.m_Id),
-         m_Date(other.m_Date),
-         m_Repeat(other.m_Repeat),
-         m_IsEnabled(other.m_IsEnabled)
+Alarm::Alarm(const Alarm &that)
 {
-       setStandalone(other.isStandalone());
-}
-
-Alarm &Alarm::operator=(const Alarm &other)
-{
-       if (this != &other) {
-               m_Id = other.m_Id;
-               m_Date = other.m_Date;
-               m_Repeat = other.m_Repeat;
-               m_IsEnabled = other.m_IsEnabled;
-               setStandalone(other.isStandalone());
-       }
-       return *this;
+       *this = that;
 }
 
-Alarm::Alarm(Alarm &&other)
-       : m_Id(other.m_Id),
-         m_Date(other.m_Date),
-         m_Repeat(other.m_Repeat),
-         m_IsEnabled(other.m_IsEnabled)
+Alarm &Alarm::operator=(const Alarm &that)
 {
-       setStandalone(other.isStandalone());
-}
+       if (this != &that) {
+               m_Id = that.m_Id;
+               m_Date = that.m_Date;
+               m_Repeat = that.m_Repeat;
+               m_IsEnabled = that.m_IsEnabled;
 
-Alarm &Alarm::operator=(Alarm &&other)
-{
-       if (this != &other) {
-               m_Id = other.m_Id;
-               m_Date = other.m_Date;
-               m_Repeat = other.m_Repeat;
-               m_IsEnabled = other.m_IsEnabled;
-               setStandalone(other.isStandalone());
+               m_SnoozeDate = that.m_SnoozeDate;
+               m_SnoozeCount = that.m_SnoozeCount;
+               m_IsSnoozed = that.m_IsSnoozed;
+               setStandalone(that.isStandalone());
        }
        return *this;
 }
@@ -100,6 +83,16 @@ bool Alarm::isEnabled() const
        return m_IsEnabled;
 }
 
+const tm &Alarm::getSnoozeDate() const
+{
+       return m_SnoozeDate;
+}
+
+int Alarm::getSnoozeCount() const
+{
+       return m_SnoozeCount;
+}
+
 void Alarm::setTime(int hour, int min)
 {
        time_t currentTime = time(nullptr);
@@ -124,22 +117,50 @@ void Alarm::setTime(int hour, int min)
                alarmTime += (wday - m_Date.tm_wday) * DAY_SECONDS;
                m_Date = *localtime(&alarmTime);
        }
+
+       resetSnooze();
 }
 
 void Alarm::setRepeat(int value)
 {
-       m_Repeat = value;
-       setTime(m_Date.tm_hour, m_Date.tm_min);
+       if (m_Repeat != value) {
+               m_Repeat = value;
+               updateTime();
+       }
 }
 
 void Alarm::setEnabled(bool isEnabled)
 {
-       m_IsEnabled = isEnabled;
-       if (m_IsEnabled) {
-               setTime(m_Date.tm_hour, m_Date.tm_min);
+       if (m_IsEnabled != isEnabled) {
+               m_IsEnabled = isEnabled;
+               if (m_IsEnabled) {
+                       updateTime();
+               } else {
+                       resetSnooze();
+               }
+       }
+}
+
+void Alarm::snooze()
+{
+       if (!m_IsSnoozed) {
+               time_t snoozeTime = mktime(&m_Date) + (++m_SnoozeCount) * SNOOZE_TIME;
+               m_SnoozeDate = *localtime(&snoozeTime);
+               m_IsSnoozed = true;
        }
 }
 
+void Alarm::dismiss()
+{
+       if (m_Repeat) {
+               updateTime();
+       } else {
+               m_IsEnabled = false;
+       }
+
+       resetSnooze();
+}
+
 bool Alarm::operator<(const Alarm &that) const
 {
        if (m_Date.tm_hour != that.m_Date.tm_hour) {
@@ -148,13 +169,31 @@ bool Alarm::operator<(const Alarm &that) const
        return m_Date.tm_min < that.m_Date.tm_min;
 }
 
+void Alarm::updateTime()
+{
+       setTime(m_Date.tm_hour, m_Date.tm_min);
+}
+
+void Alarm::resetSnooze()
+{
+       m_SnoozeDate = { 0 };
+       m_SnoozeCount = 0;
+       m_IsSnoozed = false;
+}
+
 void Alarm::onStandalone(bool isStandalone)
 {
-       int err = data_control_add_data_change_cb(AlarmConsumer::getInstance().getProvider(),
-                       makeCallbackWithLastParam(&Alarm::onDataChanged), this,
-                       makeCallbackWithLastParam(&Alarm::onDataCallbackAdded), this,
-                       &m_ChangeCallbackId);
-       WARN_IF_ERR(err, "data_control_add_data_change_cb() failed.");
+       data_control_h provider = AlarmConsumer::getInstance().getProvider();
+       if (isStandalone) {
+               int err = data_control_add_data_change_cb(provider,
+                               makeCallbackWithLastParam(&Alarm::onDataChanged), this,
+                               makeCallbackWithLastParam(&Alarm::onDataCallbackAdded), this,
+                               &m_ChangeCallbackId);
+               WARN_IF_ERR(err, "data_control_add_data_change_cb() failed.");
+       } else {
+               data_control_remove_data_change_cb(provider, m_ChangeCallbackId);
+               m_ChangeCallbackId = 0;
+       }
 }
 
 void Alarm::onDataChanged(data_control_h provider,
@@ -198,5 +237,7 @@ int Alarm::onUpdate(void *data)
                changes |= ChangedEnabled;
        }
 
+       m_SnoozeDate = that.m_SnoozeDate;
+       m_SnoozeCount = that.m_SnoozeCount;
        return changes;
 }
index 0e31353eccc38f6c6cf67baa2d276b2c1b33a2e2..205fab79a1274afb3a7b5fda434614d084d994ff 100644 (file)
@@ -29,9 +29,13 @@ Bundle AlarmBuilder::createBundle(const Alarm &alarm)
 {
        Bundle bundle;
        tm date = alarm.getDate();
+       tm snoozeDate = alarm.getSnoozeDate();
+
        bundle.addStr(COLUMN_DATE, std::to_string(mktime(&date)).c_str());
        bundle.addStr(COLUMN_REPEAT, std::to_string(alarm.getRepeat()).c_str());
        bundle.addStr(COLUMN_ENABLED, std::to_string((int) alarm.isEnabled()).c_str());
+       bundle.addStr(COLUMN_SNOOZE_DATE, std::to_string(mktime(&snoozeDate)).c_str());
+       bundle.addStr(COLUMN_SNOOZE_COUNT, std::to_string(alarm.getSnoozeCount()).c_str());
        return bundle;
 }
 
@@ -55,6 +59,10 @@ Alarm *AlarmBuilder::createAlarm(result_set_cursor cursor)
                        alarm->m_Repeat = value;
                } else if (strcmp(name, COLUMN_ENABLED) == 0) {
                        alarm->m_IsEnabled = value;
+               } else if (strcmp(name, COLUMN_SNOOZE_DATE) == 0) {
+                       alarm->m_SnoozeDate = *localtime((time_t *) &value);
+               } else if (strcmp(name, COLUMN_SNOOZE_COUNT) == 0) {
+                       alarm->m_SnoozeCount = value;
                }
        }
 
index a3d8c53dfa9db297d237fe861323d24979186231..7ed72286ef03cc14a36f9a68a416777a5e7c43cc 100644 (file)
@@ -84,7 +84,9 @@ void AlarmConsumer::getAlarm(int id, GetCallback callback)
                COLUMN_ID,
                COLUMN_DATE,
                COLUMN_REPEAT,
-               COLUMN_ENABLED
+               COLUMN_ENABLED,
+               COLUMN_SNOOZE_DATE,
+               COLUMN_SNOOZE_COUNT
        };
 
        std::string where;