From a2a6cdb2a9081a5335234d0ff4aaefe58f7ee162 Mon Sep 17 00:00:00 2001 From: Eugene Kurzberg Date: Mon, 20 Feb 2017 10:15:59 +0200 Subject: TizenRefApp-8027 Implement snooze functionality in Model Change-Id: I2977e5ffb8f984fa5845a8fb4a26ca2fb5f26ec3 Signed-off-by: Eugene Kurzberg --- alarm-app/src/Alert/AlertView.cpp | 18 ++-- alarm-svc/src/AlarmService.cpp | 42 ++++++--- lib-common/inc/Common/Model/Alarm.h | 38 +++++++- lib-common/inc/Common/Model/AlarmDb.h | 12 ++- lib-common/src/Common/Model/Alarm.cpp | 129 +++++++++++++++++--------- lib-common/src/Common/Model/AlarmBuilder.cpp | 8 ++ lib-common/src/Common/Model/AlarmConsumer.cpp | 4 +- 7 files changed, 175 insertions(+), 76 deletions(-) diff --git a/alarm-app/src/Alert/AlertView.cpp b/alarm-app/src/Alert/AlertView.cpp index bbeb7cb..6ecc380 100644 --- a/alarm-app/src/Alert/AlertView.cpp +++ b/alarm-app/src/Alert/AlertView.cpp @@ -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(); } diff --git a/alarm-svc/src/AlarmService.cpp b/alarm-svc/src/AlarmService.cpp index 1ae5769..f83d270 100755 --- a/alarm-svc/src/AlarmService.cpp +++ b/alarm-svc/src/AlarmService.cpp @@ -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); } diff --git a/lib-common/inc/Common/Model/Alarm.h b/lib-common/inc/Common/Model/Alarm.h index a6ddd5e..8c62520 100644 --- a/lib-common/inc/Common/Model/Alarm.h +++ b/lib-common/inc/Common/Model/Alarm.h @@ -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; }; } diff --git a/lib-common/inc/Common/Model/AlarmDb.h b/lib-common/inc/Common/Model/AlarmDb.h index a0c8beb..213d7fc 100644 --- a/lib-common/inc/Common/Model/AlarmDb.h +++ b/lib-common/inc/Common/Model/AlarmDb.h @@ -20,9 +20,13 @@ #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 */ diff --git a/lib-common/src/Common/Model/Alarm.cpp b/lib-common/src/Common/Model/Alarm.cpp index 3c9fa17..282a0db 100644 --- a/lib-common/src/Common/Model/Alarm.cpp +++ b/lib-common/src/Common/Model/Alarm.cpp @@ -22,13 +22,17 @@ #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; } diff --git a/lib-common/src/Common/Model/AlarmBuilder.cpp b/lib-common/src/Common/Model/AlarmBuilder.cpp index 0e31353..205fab7 100644 --- a/lib-common/src/Common/Model/AlarmBuilder.cpp +++ b/lib-common/src/Common/Model/AlarmBuilder.cpp @@ -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; } } diff --git a/lib-common/src/Common/Model/AlarmConsumer.cpp b/lib-common/src/Common/Model/AlarmConsumer.cpp index a3d8c53..7ed7228 100644 --- a/lib-common/src/Common/Model/AlarmConsumer.cpp +++ b/lib-common/src/Common/Model/AlarmConsumer.cpp @@ -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; -- cgit v1.2.3