Add watch_app_set_ambient_tick_type 00/83100/8 accepted/tizen/3.0/ivi/20161011.053530 accepted/tizen/3.0/mobile/20161015.032443 accepted/tizen/3.0/tv/20161016.003343 accepted/tizen/3.0/wearable/20161015.080441 accepted/tizen/common/20160830.150010 accepted/tizen/ivi/20160830.061238 accepted/tizen/mobile/20160830.061107 accepted/tizen/tv/20160830.061150 accepted/tizen/wearable/20160830.061233 submit/tizen/20160829.073018 submit/tizen_3.0_common/20161104.104000 submit/tizen_3.0_ivi/20161010.000000 submit/tizen_3.0_ivi/20161010.000010 submit/tizen_3.0_mobile/20161015.000000 submit/tizen_3.0_tv/20161015.000000 submit/tizen_3.0_wearable/20161015.000000
authorHyunho Kang <hhstark.kang@samsung.com>
Tue, 9 Aug 2016 07:18:24 +0000 (16:18 +0900)
committerHyunho Kang <hhstark.kang@samsung.com>
Thu, 18 Aug 2016 04:53:49 +0000 (13:53 +0900)
Change-Id: I75f3fe7a84487da12818060ac3f882d14d4a3613
Signed-off-by: Hyunho Kang <hhstark.kang@samsung.com>
Signed-off-by: Semun Lee <sm79.lee@samsung.com>
include/appcore-watch.h
include/watch_app.h
src/appcore-watch.c
src/watch_app_main.c

index 2aa6f3e..9c274fa 100755 (executable)
@@ -21,6 +21,8 @@
 #include <bundle.h>
 
 #include "app_control.h"
+#include "watch_app.h"
+
 
 #ifdef __cplusplus
 extern "C" {
@@ -69,6 +71,8 @@ int watch_core_set_event_callback(enum watch_core_event event,
 const char *watch_core_get_appid();
 void watch_core_get_timeinfo(struct watch_time_s *timeinfo);
 bool watch_core_get_24h_mode(void);
+int watch_core_set_ambient_tick_type(watch_app_ambient_tick_type_e type);
+int watch_core_get_ambient_tick_type(watch_app_ambient_tick_type_e *type);
 
 #ifdef __cplusplus
 }
index ff2562b..4f1a73b 100755 (executable)
@@ -126,10 +126,12 @@ typedef void (*watch_app_time_tick_cb) (watch_time_h watch_time, void *user_data
  * @brief Called at each minute when the device in the ambient mode.
  * @since_tizen 2.3.1
  *
- * @remarks You should not do a job that takes long time in this callback. You should update the UI as fast as possible in this callback. The platform might make the device to sleep in short time after the ambient tick expires.
+ * @remarks You should not do a job that takes long time in this callback. You should update the UI as fast as possible in this callback. The platform might make the device to sleep in short time after the ambient tick expires. Since 2.3.2, you can control when this callback is called by watch_app_set_ambient_tick_type()
  *
  * @param[in] watch_time The watch time handle. watch_time will not be available after returning this callback. It will be freed by the framework.
  * @param[in] user_data The user data to be passed to the callback functions
+ *
+ * @see watch_app_set_ambient_tick_type()
  */
 typedef void (*watch_app_ambient_tick_cb) (watch_time_h watch_time, void *user_data);
 
@@ -168,7 +170,7 @@ typedef struct {
        watch_app_resume_cb resume; /**< This callback function is called each time the application becomes visible to the user. */
        watch_app_terminate_cb terminate; /**< This callback function is called before the application exits. */
        watch_app_time_tick_cb time_tick; /**< This callback function is called at each second. */
-       watch_app_ambient_tick_cb ambient_tick; /**< This callback function is called at each minute in ambient mode. */
+       watch_app_ambient_tick_cb ambient_tick; /**< This callback function is called at each minute in ambient mode. Since 2.3.2, you can change the period of ambient tick by calling watch_app_set_ambient_tick_type()*/
        watch_app_ambient_changed_cb ambient_changed; /**< This callback function is called when the device enters or exits ambient mode. */
 } watch_app_lifecycle_callback_s;
 
@@ -183,7 +185,7 @@ typedef struct {
  * @param[in] user_data The user data to be passed to the callback function
  *
  * @return 0 on success, otherwise a negative error value
- * @retval #APP_ERROR_NONE Successfull
+ * @retval #APP_ERROR_NONE Successful
  * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter
  * @retval #APP_ERROR_OUT_OF_MEMORY Out of memory
  *
@@ -201,7 +203,7 @@ int watch_app_add_event_handler(app_event_handler_h *handler, app_event_type_e e
  * @param[in] event_handler The event handler
  *
  * @return 0 on success, otherwise a negative error value
- * @retval #APP_ERROR_NONE Successfull
+ * @retval #APP_ERROR_NONE Successful
  * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter
  *
  * @see watch_app_add_event_handler
@@ -252,6 +254,104 @@ int watch_app_main(int argc, char **argv, watch_app_lifecycle_callback_s *callba
 void watch_app_exit(void);
 
 /**
+ * @brief Enumeration for periodic ambient tick type.
+ * @since_tizen 2.3.2
+ */
+typedef enum {
+       /**
+        * No periodic ambient tick.
+        * watch_app_ambient_tick_cb() will be called once when it enters the ambient mode.
+        */
+       WATCH_APP_AMBIENT_TICK_NO_TICK,
+
+       /**
+        * watch_app_ambient_tick_cb() will be called every minute.
+        */
+       WATCH_APP_AMBIENT_TICK_EVERY_MINUTE,
+
+       /**
+        * watch_app_ambient_tick_cb() will be called every 5 minutes.
+        * It will be called at 12:00 AM, 12:05 AM, 12:10 AM ...
+        */
+       WATCH_APP_AMBIENT_TICK_EVERY_FIVE_MINUTES,
+
+       /**
+        * watch_app_ambient_tick_cb() will be called every 15 minutes.
+        * It will be called at 12:00 AM, 12:15 AM, 12:30 AM ...
+        */
+       WATCH_APP_AMBIENT_TICK_EVERY_FIFTEEN_MINUTES,
+
+       /**
+        * watch_app_ambient_tick_cb() will be called every 30 minutes.
+        * It will be called at 12:00 AM, 12:30 AM, 1:00 AM ...
+        */
+       WATCH_APP_AMBIENT_TICK_EVERY_THIRTY_MINUTES,
+
+       /**
+        * watch_app_ambient_tick_cb() will be called every hour.
+        * It will be called at 12:00 AM, 1:00 AM, 2:00 AM ...
+        */
+       WATCH_APP_AMBIENT_TICK_EVERY_HOUR,
+
+       /**
+        * watch_app_ambient_tick_cb() will be called every 3 hours.
+        * It will be called at 12:00 AM, 3:00 AM, 6:00 AM ...
+        */
+       WATCH_APP_AMBIENT_TICK_EVERY_THREE_HOURS,
+
+       /**
+        * watch_app_ambient_tick_cb() will be called every 6 hours.
+        * It will be called at 12:00 AM, 6:00 AM, 12:00 PM, 6:00 PM ...
+        */
+       WATCH_APP_AMBIENT_TICK_EVERY_SIX_HOURS,
+
+       /**
+        * watch_app_ambient_tick_cb() will be called every 12 hours.
+        * It will be called at 12:00 AM, 12:00 PM
+        */
+       WATCH_APP_AMBIENT_TICK_EVERY_TWELVE_HOURS,
+
+       /**
+        * watch_app_ambient_tick_cb() will be called at the start of the day.
+        * It will be called at 12:00 AM
+        */
+       WATCH_APP_AMBIENT_TICK_EVERY_DAY
+} watch_app_ambient_tick_type_e;
+
+/**
+ * @brief Sets the type of periodic ambient tick.
+ * @since_tizen 2.3.2
+ *
+ * @remarks If you do not set specific tick type with this function, the watch_app_ambient_tick_cb() will be called every minute by default.
+ *
+ * @param[in] type The type of periodic ambient tick
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #APP_ERROR_INVALID_PARAMETER Invalid Parameter
+ * @retval #APP_ERROR_NONE Successful
+ *
+ * @see watch_app_ambient_tick_cb()
+ */
+int watch_app_set_ambient_tick_type(watch_app_ambient_tick_type_e type);
+
+/**
+ * @brief Gets the type of periodic ambient tick.
+ * @since_tizen 2.3.2
+ *
+ * @remarks If you do not set specific tick type with watch_app_set_ambient_tick_type(), this function will set @a type to #WATCH_APP_AMBIENT_TICK_EVERY_MINUTE.
+ *
+ * @param[out] type The type of periodic ambient tick
+ *
+ * @return 0 on success, otherwise a negative error value
+ * @retval #APP_ERROR_INVALID_PARAMETER Invalid Parameter
+ * @retval #APP_ERROR_NONE Successful
+ *
+ * @see watch_app_ambient_tick_cb()
+ * @see watch_app_set_ambient_tick_type()
+ */
+int watch_app_get_ambient_tick_type(watch_app_ambient_tick_type_e *type);
+
+/**
  * @brief Gets the current time.
  * @since_tizen 2.3.1
  *
index 576cc5c..95a1946 100755 (executable)
 #define APPID_BUFFER_MAX 255
 #define TIMEZONE_BUFFER_MAX 1024
 #define LOCAL_TIME_PATH "/opt/etc/localtime"
-#define ONE_SECOND  1000
-#define ONE_MINUTE  60
-#define ONE_HOUR    60
+#define ONE_SECOND             1000
+#define ONE_MINUTE_IN_SEC      60
+#define ONE_HOUR_IN_SEC                3600
+#define ONE_DAY_IN_SEC         86400
 
 static Ecore_Timer *watch_tick = NULL;
 static alarm_id_t alarm_id = 0;
+static watch_app_ambient_tick_type_e ambient_tick_type
+                                       = WATCH_APP_AMBIENT_TICK_EVERY_MINUTE;
 
 /**
  * Appcore internal system event
@@ -220,10 +223,28 @@ static int __widget_destroy(const char *id, widget_app_destroy_type_e reason,
                void *data);
 static int __widget_pause(const char *id, void *data);
 static int __widget_resume(const char *id, void *data);
+static void __get_timeinfo(struct watch_time_s *timeinfo);
 
 extern int app_control_create_event(bundle *data,
                struct app_control_s **app_control);
 
+static struct ambient_tick_type_info {
+       int interval;
+       int minute_base;
+       int hour_base;
+} ambient_tick_type_infos[] = {
+       {0, 0, 0},
+       {ONE_MINUTE_IN_SEC, 1, 0},
+       {ONE_MINUTE_IN_SEC * 5, 5, 0},
+       {ONE_MINUTE_IN_SEC * 15, 15, 0},
+       {ONE_MINUTE_IN_SEC * 30, 30, 0},
+       {ONE_HOUR_IN_SEC, 0, 1},
+       {ONE_HOUR_IN_SEC * 3, 0, 3},
+       {ONE_HOUR_IN_SEC * 6, 0, 6},
+       {ONE_HOUR_IN_SEC * 12, 0, 12},
+       {ONE_DAY_IN_SEC, 0, 12}
+};
+
 static void __exit_loop(void *data)
 {
        ecore_main_loop_quit();
@@ -511,6 +532,60 @@ static void __vconf_do(struct evt_ops *eo, keynode_t * key, void *data)
                eo->vcb_post(data, key);
 }
 
+static int __get_ambient_tick_offset(struct watch_time_s timeinfo, int interval, int minute_base, int hour_base)
+{
+       int remain_hour = 0;
+       int remain_min = 0;
+       int offset_sec = 0;
+
+       if (hour_base != 0) {
+               if (interval == ONE_DAY_IN_SEC) {
+                       remain_hour = hour_base - timeinfo.hour24;
+                       if (remain_hour < 0)
+                               remain_hour += 24;
+                       remain_min = remain_hour * 60 - timeinfo.minute;
+                       offset_sec = remain_min * ONE_MINUTE_IN_SEC - timeinfo.second;
+               } else {
+                       remain_hour = hour_base - (timeinfo.hour24 % hour_base);
+                       remain_min = remain_hour * 60 - timeinfo.minute;
+                       offset_sec = remain_min * ONE_MINUTE_IN_SEC - timeinfo.second;
+               }
+       } else {
+               remain_min = minute_base - (timeinfo.minute % minute_base);
+               offset_sec = remain_min * ONE_MINUTE_IN_SEC - timeinfo.second;
+       }
+       return offset_sec;
+}
+
+static int __set_ambient_tick_cb()
+{
+       int offset_sec = 0;
+       int interval = 0;
+       struct watch_time_s timeinfo;
+       int r;
+       struct ambient_tick_type_info info;
+
+       __get_timeinfo(&timeinfo);
+       info = ambient_tick_type_infos[ambient_tick_type];
+       interval = info.interval;
+
+       if (interval == 0) {
+               priv.ops->ambient_tick(&timeinfo, priv.ops->data);
+       } else {
+               offset_sec = __get_ambient_tick_offset(timeinfo, info.interval,
+                               info.minute_base, info.hour_base);
+               _D("next time tick: %d", offset_sec);
+
+               /* Set a next alarm */
+               r = alarmmgr_add_alarm_withcb(ALARM_TYPE_VOLATILE, offset_sec, interval,
+                               __watch_core_ambient_tick, NULL, &alarm_id);
+               if (r < 0)
+                       _E("fail to alarmmgr_add_alarm_withcb : error_code : %d",r);
+       }
+
+       return 0;
+}
+
 static void __vconf_cb(keynode_t *key, void *data)
 {
        int i;
@@ -526,8 +601,13 @@ static void __vconf_cb(keynode_t *key, void *data)
        /* Check the time changed event */
        if (!strcmp(name, VCONFKEY_SYSTEM_TIME_CHANGED)) {
                _D("ambient_mode: %d", watch_data->ambient_mode);
-               if (watch_data->ambient_mode)
-                       __watch_core_ambient_tick(0, NULL);
+               if (watch_data->ambient_mode) {
+                       if (alarm_id) {
+                               alarmmgr_remove_alarm(alarm_id);
+                               alarm_id = 0;
+                       }
+                       __set_ambient_tick_cb();
+               }
 
                return;
        }
@@ -921,10 +1001,6 @@ static int __widget_resume(const char *id, void *data)
 /* LCOV_EXCL_START */
 static int __signal_alpm_handler(int ambient, void *data)
 {
-       struct watch_time_s timeinfo;
-       int sec;
-       int r;
-
        _D("_signal_alpm_handler: ambient: %d, state: %d", ambient, priv.state);
 
        if (priv.ambient_mode == ambient) {
@@ -944,22 +1020,8 @@ static int __signal_alpm_handler(int ambient, void *data)
                priv.ambient_mode = 1;
                __do_app(WE_AMBIENT, &priv, NULL);
 
-               if (priv.ops && priv.ops->ambient_tick) {
-                       __get_timeinfo(&timeinfo);
-                       sec = ONE_MINUTE - timeinfo.second;
-
-                       _D("next time tick: %d", sec);
-
-                       /* Set a next alarm */
-                       r = alarmmgr_add_alarm_withcb(ALARM_TYPE_VOLATILE, sec,
-                                       60, __watch_core_ambient_tick, data,
-                                       &alarm_id);
-                       if (r < 0)
-                               _E("fail to alarmmgr_add_alarm_withcb : "
-                                               "error_code : %d", r);
-
-                       priv.ops->ambient_tick(&timeinfo, priv.ops->data);
-               }
+               if (priv.ops && priv.ops->ambient_tick)
+                       __set_ambient_tick_cb();
 
                /* Send a update done signal */
                _watch_core_send_alpm_update_done();
@@ -1174,3 +1236,21 @@ EXPORT_API const char *watch_core_get_appid()
        return priv.appid;
 }
 
+EXPORT_API int watch_core_set_ambient_tick_type(watch_app_ambient_tick_type_e type)
+{
+       _D("set ambient tick type : %d", type);
+       ambient_tick_type = type;
+
+       if (alarm_id) {
+               alarmmgr_remove_alarm(alarm_id);
+               alarm_id = 0;
+               __set_ambient_tick_cb();
+       }
+       return 0;
+}
+
+EXPORT_API int watch_core_get_ambient_tick_type(watch_app_ambient_tick_type_e *type)
+{
+       *type = ambient_tick_type;
+       return 0;
+}
index 9b1a2ec..4fc3351 100755 (executable)
@@ -696,3 +696,16 @@ EXPORT_API int watch_app_get_elm_win(Evas_Object **win)
        return APP_ERROR_NONE;
 }
 
+EXPORT_API int watch_app_set_ambient_tick_type(watch_app_ambient_tick_type_e type)
+{
+       if (type < WATCH_APP_AMBIENT_TICK_NO_TICK || type > WATCH_APP_AMBIENT_TICK_EVERY_DAY)
+               return APP_ERROR_INVALID_PARAMETER;
+       return watch_core_set_ambient_tick_type(type);
+}
+
+EXPORT_API int watch_app_get_ambient_tick_type(watch_app_ambient_tick_type_e *type)
+{
+       if (type == NULL)
+               return APP_ERROR_INVALID_PARAMETER;
+       return watch_core_get_ambient_tick_type(type);
+}
\ No newline at end of file