Handling the force option for trigerring updates
authorSung-jae Park <nicesj.park@samsung.com>
Wed, 4 Dec 2013 07:42:41 +0000 (16:42 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Wed, 4 Dec 2013 07:43:15 +0000 (16:43 +0900)
Change-Id: I4e2ce43516aacfcff74fc41664c1a4eb80781c72

include/lb.h
packaging/com.samsung.data-provider-slave.spec
src/client.c
src/lb.c

index 1579457..9864481 100644 (file)
@@ -26,8 +26,8 @@ extern int lb_clicked(const char *pkgname, const char *id, const char *event, do
 extern int lb_script_event(const char *pkgname, const char *id, const char *emission, const char *source, struct event_info *event_info);
 extern int lb_change_group(const char *pkgname, const char *id, const char *cluster, const char *category);
 
-extern int lb_update(const char *pkgname, const char *id);
-extern int lb_update_all(const char *pkgname, const char *cluster, const char *category);
+extern int lb_update(const char *pkgname, const char *id, int force);
+extern int lb_update_all(const char *pkgname, const char *cluster, const char *category, int force);
 extern void lb_pause_all(void);
 extern void lb_resume_all(void);
 extern int lb_set_period(const char *pkgname, const char *id, double period);
index 4cd249a..7a7f974 100644 (file)
@@ -2,7 +2,7 @@
 
 Name: com.samsung.data-provider-slave
 Summary: Plugin type livebox service provider
-Version: 0.12.21
+Version: 0.12.22
 Release: 1
 Group: HomeTF/Livebox
 License: Flora
index 9e31c30..c33e82f 100644 (file)
@@ -259,10 +259,10 @@ static int method_update_content(struct event_arg *arg, void *data)
 
        if (!arg->id || !strlen(arg->id)) {
                DbgPrint("pkgname[%s] cluster[%s] category[%s]\n", arg->pkgname, arg->info.update_content.cluster, arg->info.update_content.category);
-               ret = lb_update_all(arg->pkgname, arg->info.update_content.cluster, arg->info.update_content.category);
+               ret = lb_update_all(arg->pkgname, arg->info.update_content.cluster, arg->info.update_content.category, arg->info.update_content.force);
        } else {
                DbgPrint("Update [%s]\n", arg->id);
-               ret = lb_update(arg->pkgname, arg->id);
+               ret = lb_update(arg->pkgname, arg->id, arg->info.update_content.force);
        }
 
        return ret;
index 9ccfb91..a610b37 100644 (file)
--- a/src/lb.c
+++ b/src/lb.c
@@ -52,6 +52,12 @@ int errno;
 #define UPDATE_INVOKED         (-2)
 #define UPDATE_NOT_INVOKED     (0)
 
+enum pd_open_state {
+       PD_IS_OPENED_BUT_NOT_MINE = -1,
+       PD_IS_NOT_OPENED = 0,
+       PD_IS_OPENED = 1,
+};
+
 struct item {
        Ecore_Timer *timer;
        struct instance *inst;
@@ -84,6 +90,7 @@ static struct info {
        Eina_List *pd_list;
        int secured;
        int pending_timer_freezed;
+       int force_timer_freezed;
 } s_info  = {
        .item_list = NULL,
        .force_update_list = NULL,
@@ -98,15 +105,23 @@ static struct info {
        .pd_list = NULL,
        .secured = 0,
        .pending_timer_freezed = 0,
+       .force_timer_freezed = 0,
 };
 
 static Eina_Bool updator_cb(void *data);
 static inline void update_monitor_del(const char *id, struct item *item);
+static int append_force_update_list(struct item *item);
+static void reset_lb_updated_flag(struct item *item);
+static int append_pending_list(struct item *item);
 
 static void pending_timer_freeze(void)
 {
        DbgPrint("Freezed Count: %d\n", s_info.pending_timer_freezed);
-       if (s_info.pending_timer && !s_info.pending_timer_freezed) {
+       if (!s_info.pending_timer) {
+               return;
+       }
+
+       if (!s_info.pending_timer_freezed) {
                DbgPrint("Freeze the pending timer\n");
                ecore_timer_freeze(s_info.pending_timer);
        }
@@ -121,19 +136,58 @@ static void pending_timer_thaw(void)
                return;
        }
 
+       if (!s_info.pending_timer) {
+               s_info.pending_timer_freezed = 0;
+               return;
+       }
+
        s_info.pending_timer_freezed--;
-       if (s_info.pending_timer && !s_info.pending_timer_freezed) {
+       if (!s_info.pending_timer_freezed) {
                DbgPrint("Thaw the pending timer\n");
                ecore_timer_thaw(s_info.pending_timer);
        }
 }
 
+static void force_timer_freeze(void)
+{
+       DbgPrint("Freeze force timer: %d\n", s_info.force_timer_freezed);
+       if (!s_info.force_update_timer) {
+               return;
+       }
+
+       if (!s_info.force_timer_freezed) {
+               DbgPrint("Force timer freezed\n");
+               ecore_timer_freeze(s_info.force_update_timer);
+       }
+
+       s_info.force_timer_freezed++;
+}
+
+static void force_timer_thaw(void)
+{
+       DbgPrint("Freezed force count: %d\n", s_info.force_timer_freezed);
+       if (!s_info.force_timer_freezed) {
+               return;
+       }
+
+       if (!s_info.force_update_timer) {
+               s_info.force_timer_freezed = 0;
+               return;
+       }
+
+       s_info.force_timer_freezed--;
+       if (!s_info.force_timer_freezed) {
+               DbgPrint("Thaw the force timer\n");
+               ecore_timer_thaw(s_info.force_update_timer);
+       }
+}
+
 /*
  * -1 : PD is opened, but not mine
  *  0 : PD is not opened
  *  1 : my PD is opened
  */
-static inline int pd_is_opened(const char *pkgname)
+static inline enum pd_open_state pd_is_opened(const char *pkgname)
 {
        int i;
        Eina_List *l;
@@ -142,13 +196,13 @@ static inline int pd_is_opened(const char *pkgname)
        i = 0;
        EINA_LIST_FOREACH(s_info.pd_list, l, inst) {
                if (pkgname && !strcmp(pkgname, inst->item->pkgname)) {
-                       return 1;
+                       return PD_IS_OPENED;
                }
 
                i++;
        }
 
-       return i > 0 ? -1 : 0;
+       return i > 0 ? PD_IS_OPENED_BUT_NOT_MINE : PD_IS_NOT_OPENED;
 }
 
 static Eina_Bool pd_open_pended_cmd_consumer_cb(void *data)
@@ -182,6 +236,169 @@ cleanout:
        return ECORE_CALLBACK_CANCEL;
 }
 
+static Eina_Bool update_timeout_cb(void *data)
+{
+       struct item *item;
+
+       item = data;
+
+       ErrPrint("UPDATE TIMEOUT ========> %s - %s\n", item->inst->item->pkgname, item->inst->id);
+
+       if (!eina_list_data_find(s_info.update_list, item)) {
+               ErrPrint("Updating item is not matched\n");
+       }
+
+       fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
+       fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,timeout", NO_ALARM, DEFAULT_LIFE_TIMER);
+       s_info.update_list = eina_list_remove(s_info.update_list, item);
+
+       exit(ETIME);
+       return ECORE_CALLBACK_CANCEL;
+}
+
+static inline void update_monitor_cnt(struct item *item)
+{
+       double now;
+       double interval;
+
+       now = util_timestamp();
+       interval = now - item->update_interval;
+
+       /*!
+        * \note
+        * If the content update is processed in too short time,
+        * don't increase the monitor counter, instead of it
+        * set the heavy updating flag.
+        * And handling this heavy updating from the
+        * file update callback.
+        */
+       if (interval >= MINIMUM_UPDATE_INTERVAL) {
+               if (eina_list_data_find(s_info.update_list, item)) {
+                       /*!
+                        * \note
+                        * If already in updating mode,
+                        * reset the monitor_cnt to 1,
+                        * all updated event will be merged into A inotify event
+                        */
+                       DbgPrint("While waiting updated event, content is updated [%s]\n", item->inst->id);
+                       item->monitor_cnt = 1;
+               } else {
+                       item->monitor_cnt++;
+               }
+       } else {
+               item->heavy_updating = 1;
+       }
+
+       item->update_interval = now;
+}
+
+static inline void do_force_update(struct item *item)
+{
+       int ret;
+
+       if (item->monitor) { /*!< If this item is already in update process */
+               return;
+       }
+
+       if (!IS_LB_SHOWN(item)) {
+               DbgPrint("%s is not shown yet. it will be added to normal pending list\n", item->inst->item->pkgname);
+               (void)append_force_update_list(item);
+               return;
+       }
+
+       if (item->is_paused) {
+               DbgPrint("Item is paused. but it will be updated forcely(%s)\n", item->inst->item->pkgname);
+       }
+
+       item->updated_in_pause = 0;
+
+       ret = so_is_updated(item->inst);
+       if (ret <= 0) {
+               if (so_need_to_destroy(item->inst) == NEED_TO_DESTROY) {
+                       provider_send_deleted(item->inst->item->pkgname, item->inst->id);
+                       lb_destroy(item->inst->item->pkgname, item->inst->id);
+                       /*!
+                        * \CRITICAL
+                        * Every caller of this, must not access the item from now.
+                        */
+                       return;
+               }
+
+               reset_lb_updated_flag(item);
+               return;
+       }
+
+       /*!
+        * \note
+        * Check the update_list, if you want make serialized update
+        */
+       if (/*s_info.update_list || */pd_is_opened(item->inst->item->pkgname) == PD_IS_OPENED_BUT_NOT_MINE) {
+               DbgPrint("%s is busy, migrate to normal pending list\n", item->inst->id);
+               (void)append_pending_list(item);
+               return;
+       }
+
+       item->monitor = ecore_timer_add(item->inst->item->timeout, update_timeout_cb, item);
+       if (!item->monitor) {
+               ErrPrint("Failed to add update monitor %s(%s):%d\n",
+                                       item->inst->item->pkgname, item->inst->id, item->inst->item->timeout);
+               return;
+       }
+
+       ret = so_update(item->inst);
+       if (ret < 0) {
+               ecore_timer_del(item->monitor);
+               item->monitor = NULL;
+               reset_lb_updated_flag(item);
+               return;
+       }
+
+       /*!
+        * \note
+        * Counter of the event monitor is only used for asynchronous content updating,
+        * So reset it to 1 from here because the async updating is started now,
+        * even if it is accumulated by other event function before this.
+        */
+       item->monitor_cnt = 1;
+
+       /*!
+        * \note
+        * While waiting the Callback function call,
+        * Add this for finding the crash
+        */
+       fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM, DEFAULT_LIFE_TIMER);
+
+       if (ret & NEED_TO_SCHEDULE) {
+               (void)append_pending_list(item);
+       }
+
+       if (ret & FORCE_TO_SCHEDULE) {
+               DbgPrint("%s Return NEED_TO_FORCE_SCHEDULE\n", item->inst->item->pkgname);
+               (void)append_force_update_list(item);
+       }
+
+       if (ret & OUTPUT_UPDATED) {
+               /*!
+                * \NOTE 
+                * In this case, there is potential issue
+                * 1. User added update CALLBACK -> Inotify event (Only once)
+                *    > We have to detect this case. Is it possible to be a user callback called faster than inotify event handler?
+                * 2. Inotify event -> User added update CALLBACK -> Inotify event
+                *    > Okay. What we want is this.
+                */
+               update_monitor_cnt(item);
+       }
+
+       /*
+        * \NOTE
+        * This should be updated after "update_monitor_cnt" function call,
+        * because the update_monitor_cnt function will see the s_info.update variable,
+        */
+       s_info.update_list = eina_list_append(s_info.update_list, item);
+
+       return;
+}
+
 static Eina_Bool force_update_cb(void *data)
 {
        struct item *item;
@@ -191,13 +408,9 @@ static Eina_Bool force_update_cb(void *data)
                goto cleanout;
        }
 
-       if (eina_list_data_find(s_info.update_list, item) || pd_is_opened(item->inst->item->pkgname) < 0) {
-               return ECORE_CALLBACK_RENEW;
-       }
-
        s_info.force_update_list = eina_list_remove(s_info.force_update_list, item);
-       if (updator_cb(item) == ECORE_CALLBACK_CANCEL) {
-       }
+
+       do_force_update(item);
 
        if (s_info.force_update_list) {
                return ECORE_CALLBACK_RENEW;
@@ -246,7 +459,7 @@ static Eina_Bool pended_cmd_consumer_cb(void *data)
                goto cleanout;
        }
 
-       if (eina_list_data_find(s_info.update_list, item) || pd_is_opened(item->inst->item->pkgname) < 0) {
+       if (eina_list_data_find(s_info.update_list, item) || pd_is_opened(item->inst->item->pkgname) == PD_IS_OPENED_BUT_NOT_MINE) {
                return ECORE_CALLBACK_RENEW;
        }
 
@@ -345,6 +558,25 @@ static inline void migrate_to_pd_open_pending_list(const char *pkgname)
                cnt++;
        }
 
+       /*!
+        * These items will be moved to the pending list after the PD is closed.
+        * Force list -> pd open list -> pending list.
+        * So there is no way to go back to the foce update list again.
+        *
+        * \warning
+        * the ITEM must only exists in one list, pending list or force_update_list
+        * It is not accepted to exists in two list at same time.
+        */
+       EINA_LIST_FOREACH_SAFE(s_info.force_update_list, l, n, item) {
+               if (strcmp(pkgname, item->inst->item->pkgname)) {
+                       continue;
+               }
+
+               s_info.force_update_list = eina_list_remove(s_info.force_update_list, item);
+               s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
+               cnt++;
+       }
+
        if (s_info.pd_open_pending_list) {
                activate_pd_open_pending_consumer();
        }
@@ -352,6 +584,10 @@ static inline void migrate_to_pd_open_pending_list(const char *pkgname)
        if (!s_info.pending_list) {
                deactivate_pending_consumer();
        }
+
+       if (!s_info.force_update_list) {
+               deactivate_force_update_consumer();
+       }
 }
 
 static inline void migrate_to_pending_list(const char *pkgname)
@@ -383,7 +619,7 @@ static inline void migrate_to_pending_list(const char *pkgname)
 static inline int is_pended_item(struct item *item)
 {
        struct item *in_item;
-       if (pd_is_opened(item->inst->item->pkgname) == 1) {
+       if (pd_is_opened(item->inst->item->pkgname) == PD_IS_OPENED) {
                in_item = eina_list_data_find(s_info.pd_open_pending_list, item);
        } else {
                in_item = eina_list_data_find(s_info.pending_list, item);
@@ -399,7 +635,12 @@ static int append_pending_list(struct item *item)
                return LB_STATUS_ERROR_BUSY;
        }
 
-       if (pd_is_opened(item->inst->item->pkgname) == 1) {
+       if (eina_list_data_find(s_info.force_update_list, item)) {
+               DbgPrint("Already exists in force list\n");
+               return LB_STATUS_SUCCESS;
+       }
+
+       if (pd_is_opened(item->inst->item->pkgname) == PD_IS_OPENED) {
                if (eina_list_data_find(s_info.pd_open_pending_list, item) == item) {
                        DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
                        return LB_STATUS_ERROR_EXIST;
@@ -432,7 +673,28 @@ static int append_pending_list(struct item *item)
                        s_info.hidden_list = eina_list_append(s_info.hidden_list, item);
                }
        }
-       return 0;
+
+       return LB_STATUS_SUCCESS;
+}
+
+static inline int clear_from_pending_list(struct item *item)
+{
+       Eina_List *l;
+       struct item *tmp;
+
+       EINA_LIST_FOREACH(s_info.pending_list, l, tmp) {
+               if (tmp != item) {
+                       continue;
+               }
+
+               s_info.pending_list = eina_list_remove_list(s_info.pending_list, l);
+               if (!s_info.pending_list) {
+                       deactivate_pending_consumer();
+               }
+               return LB_STATUS_SUCCESS;
+       }
+
+       return LB_STATUS_ERROR_NOT_EXIST;
 }
 
 static int append_force_update_list(struct item *item)
@@ -442,28 +704,47 @@ static int append_force_update_list(struct item *item)
                return LB_STATUS_ERROR_BUSY;
        }
 
-       if (!IS_LB_SHOWN(item)) {
-               if (eina_list_data_find(s_info.hidden_list, item) == item) {
-                       DbgPrint("Already in hidden list - %s\n", item->inst->id);
+       /*!
+        * If the item is already in pending list, remove it.
+        */
+       clear_from_pending_list(item);
+
+       if (pd_is_opened(item->inst->item->pkgname) == PD_IS_OPENED) {
+               if (eina_list_data_find(s_info.pd_open_pending_list, item) == item) {
+                       DbgPrint("Already pended - %s\n", item->inst->item->pkgname);
                        return LB_STATUS_ERROR_EXIST;
                }
 
-               s_info.hidden_list = eina_list_append(s_info.hidden_list, item);
+               if (activate_pd_open_pending_consumer() < 0) {
+                       ErrPrint("Failed to activate PD open pending consumer\n");
+                       return LB_STATUS_ERROR_FAULT;
+               }
 
-               DbgPrint("forced item is moved to hidden_list - %s\n", item->inst->id);
-               return LB_STATUS_SUCCESS;
-       }
+               s_info.pd_open_pending_list = eina_list_append(s_info.pd_open_pending_list, item);
+       } else {
+               if (eina_list_data_find(s_info.force_update_list, item)) {
+                       DbgPrint("Already in force update list\n");
+                       return LB_STATUS_SUCCESS;
+               }
 
-       if (eina_list_data_find(s_info.force_update_list, item)) {
-               DbgPrint("Already in force update list\n");
-               return LB_STATUS_SUCCESS;
-       }
+               if (IS_LB_SHOWN(item)) {
+                       if (activate_force_update_consumer() < 0) {
+                               return LB_STATUS_ERROR_FAULT;
+                       }
 
-       if (activate_force_update_consumer() < 0) {
-               return LB_STATUS_ERROR_FAULT;
+                       s_info.force_update_list = eina_list_append(s_info.force_update_list, item);
+               } else {
+                       if (eina_list_data_find(s_info.hidden_list, item) == item) {
+                               DbgPrint("Already in hidden list - %s\n", item->inst->id);
+                               return LB_STATUS_ERROR_EXIST;
+                       }
+
+                       s_info.hidden_list = eina_list_append(s_info.hidden_list, item);
+
+                       DbgPrint("forced item is moved to hidden_list - %s\n", item->inst->id);
+               }
        }
 
-       s_info.force_update_list = eina_list_append(s_info.force_update_list, item);
        return LB_STATUS_SUCCESS;
 }
 
@@ -498,26 +779,6 @@ static inline void migrate_to_pending_list_from_hidden_list(struct item *item)
        append_pending_list(item);
 }
 
-static inline int clear_from_pending_list(struct item *item)
-{
-       Eina_List *l;
-       struct item *tmp;
-
-       EINA_LIST_FOREACH(s_info.pending_list, l, tmp) {
-               if (tmp != item) {
-                       continue;
-               }
-
-               s_info.pending_list = eina_list_remove_list(s_info.pending_list, l);
-               if (!s_info.pending_list) {
-                       deactivate_pending_consumer();
-               }
-               return LB_STATUS_SUCCESS;
-       }
-
-       return LB_STATUS_ERROR_NOT_EXIST;
-}
-
 /*!
  * \brief
  *   This function can call the update callback
@@ -593,42 +854,6 @@ static void timer_freeze(struct item *item)
 #endif
 }
 
-static inline void update_monitor_cnt(struct item *item)
-{
-       double now;
-       double interval;
-
-       now = util_timestamp();
-       interval = now - item->update_interval;
-
-       /*!
-        * \note
-        * If the content update is processed in too short time,
-        * don't increase the monitor counter, instead of it
-        * set the heavy updating flag.
-        * And handling this heavy updating from the
-        * file update callback.
-        */
-       if (interval >= MINIMUM_UPDATE_INTERVAL) {
-               if (eina_list_data_find(s_info.update_list, item)) {
-                       /*!
-                        * \note
-                        * If already in updating mode,
-                        * reset the monitor_cnt to 1,
-                        * all updated event will be merged into A inotify event
-                        */
-                       DbgPrint("While waiting updated event, content is updated [%s]\n", item->inst->id);
-                       item->monitor_cnt = 1;
-               } else {
-                       item->monitor_cnt++;
-               }
-       } else {
-               item->heavy_updating = 1;
-       }
-
-       item->update_interval = now;
-}
-
 static inline Eina_List *find_item(struct instance *inst)
 {
        Eina_List *l;
@@ -783,26 +1008,6 @@ static inline int clear_from_pd_open_pending_list(struct item *item)
        return LB_STATUS_ERROR_NOT_EXIST;
 }
 
-static Eina_Bool update_timeout_cb(void *data)
-{
-       struct item *item;
-
-       item = data;
-
-       ErrPrint("UPDATE TIMEOUT ========> %s - %s\n", item->inst->item->pkgname, item->inst->id);
-
-       if (!eina_list_data_find(s_info.update_list, item)) {
-               ErrPrint("Updating item is not matched\n");
-       }
-
-       fault_unmark_call(item->inst->item->pkgname, item->inst->id, "update,crashed", NO_ALARM);
-       fault_mark_call(item->inst->item->pkgname, item->inst->id, "update,timeout", NO_ALARM, DEFAULT_LIFE_TIMER);
-       s_info.update_list = eina_list_remove(s_info.update_list, item);
-
-       exit(ETIME);
-       return ECORE_CALLBACK_CANCEL;
-}
-
 /*!
  * \note
  * This must has to return ECORE_CALLBACK_CANCEL, only if the item is deleted.
@@ -853,7 +1058,7 @@ static Eina_Bool updator_cb(void *data)
         * \note
         * Check the update_list, if you want make serialized update
         */
-       if (/*s_info.update_list || */pd_is_opened(item->inst->item->pkgname) < 0) {
+       if (/*s_info.update_list || */pd_is_opened(item->inst->item->pkgname) == PD_IS_OPENED_BUT_NOT_MINE) {
                DbgPrint("%s is busy\n", item->inst->id);
                (void)append_pending_list(item);
                return ECORE_CALLBACK_RENEW;
@@ -1103,6 +1308,12 @@ HAPI int lb_open_pd(const char *pkgname, const char *id)
 
        if (!s_info.pd_list) {
                pending_timer_freeze();
+
+               /*!
+                * \note
+                * Freeze the force timer only in this case.
+                */
+               force_timer_freeze();
        }
 
        s_info.pd_list = eina_list_append(s_info.pd_list, inst);
@@ -1136,6 +1347,7 @@ HAPI int lb_close_pd(const char *pkgname, const char *id)
                s_info.pd_list = eina_list_remove(s_info.pd_list, tmp);
                if (!s_info.pd_list) {
                        pending_timer_thaw();
+                       force_timer_thaw();
                }
 
                /*!
@@ -1295,6 +1507,7 @@ HAPI int lb_destroy(const char *pkgname, const char *id)
                s_info.pd_list = eina_list_remove(s_info.pd_list, tmp);
                if (!s_info.pd_list) {
                        pending_timer_thaw();
+                       force_timer_thaw();
                }
 
                /*!
@@ -1680,7 +1893,7 @@ HAPI int lb_system_event(const char *pkgname, const char *id, int event)
        return lb_sys_event(inst, item, event);
 }
 
-HAPI int lb_update(const char *pkgname, const char *id)
+HAPI int lb_update(const char *pkgname, const char *id, int force)
 {
        Eina_List *l;
        struct instance *inst;
@@ -1699,11 +1912,16 @@ HAPI int lb_update(const char *pkgname, const char *id)
        }
 
        item = eina_list_data_get(l);
-       (void)append_pending_list(item);
+       if (force && pd_is_opened(pkgname) != PD_IS_OPENED) {
+               (void)append_force_update_list(item);
+       } else {
+               (void)append_pending_list(item);
+       }
+
        return LB_STATUS_SUCCESS;
 }
 
-HAPI int lb_update_all(const char *pkgname, const char *cluster, const char *category)
+HAPI int lb_update_all(const char *pkgname, const char *cluster, const char *category, int force)
 {
        Eina_List *l;
        Eina_List *n;
@@ -1725,10 +1943,18 @@ HAPI int lb_update_all(const char *pkgname, const char *cluster, const char *cat
 
                if (pkgname && strlen(pkgname)) {
                        if (!strcmp(item->inst->item->pkgname, pkgname)) {
-                               (void)append_pending_list(item);
+                               if (force && pd_is_opened(pkgname) != PD_IS_OPENED) {
+                                       (void)append_force_update_list(item);
+                               } else {
+                                       (void)append_pending_list(item);
+                               }
                        }
                } else {
-                       (void)append_pending_list(item);
+                       if (force) {
+                               DbgPrint("Update All function doesn't support force update to all liveboxes\n");
+                       } else {
+                               (void)append_pending_list(item);
+                       }
                }
        }
 
@@ -1783,6 +2009,10 @@ HAPI void lb_pause_all(void)
        s_info.paused = 1;
 
        pending_timer_freeze();
+       /*!
+        * \note
+        * force timer will not be freezed
+        */
 
        EINA_LIST_FOREACH(s_info.item_list, l, item) {
                if (item->deleteme) {
@@ -1810,6 +2040,11 @@ HAPI void lb_resume_all(void)
 
        pending_timer_thaw();
 
+       /*!
+        * \note
+        * force timer will not affected by this
+        */
+
        EINA_LIST_FOREACH_SAFE(s_info.item_list, l, n, item) {
                if (item->deleteme) {
                        DbgPrint("Instance %s skip timer resume (deleteme)\n", item->inst->item->pkgname);