Add change_period service handler
authorSung-jae Park <nicesj.park@samsung.com>
Sat, 23 Feb 2013 13:27:29 +0000 (13:27 +0000)
committerSung-jae Park <nicesj.park@samsung.com>
Sat, 23 Feb 2013 15:01:31 +0000 (15:01 +0000)
Revise the client life-cycle management code
service_change_period service handler is added == livebox_service_change_period(pkgname, id, new_period)
Change the trigger_update function. Add "id" field. to specify the update target

Change-Id: I26b8a3b2c5e6deea3919e1649f0af4f51b93ee38

include/client_life.h
include/instance.h
packaging/com.samsung.data-provider-master.spec
src/client_life.c
src/instance.c
src/package.c
src/server.c
src/xmonitor.c

index b577fd3..8a7ceb7 100644 (file)
@@ -15,8 +15,8 @@
  */
 
 enum client_event {
+       CLIENT_EVENT_ACTIVATE,
        CLIENT_EVENT_DEACTIVATE,
-       CLIENT_EVENT_DESTROY,
 };
 
 enum client_global_event {
@@ -32,7 +32,7 @@ struct packet;
  * Create & Destroy
  */
 extern struct client_node *client_create(pid_t pid, int handle);
-extern int client_destroy(struct client_node *client);
+#define client_destroy(client) client_unref(client)
 
 /*!
  * \note
index 69b6d55..30a4aef 100644 (file)
@@ -176,6 +176,7 @@ extern const char * const instance_auto_launch(const struct inst_info *inst);
 extern const int const instance_priority(const struct inst_info *inst);
 extern const struct client_node * const instance_client(const struct inst_info *inst);
 extern const double const instance_period(const struct inst_info *inst);
+extern const int const instance_timeout(const struct inst_info *inst);
 extern const int const instance_lb_width(const struct inst_info *inst);
 extern const int const instance_lb_height(const struct inst_info *inst);
 extern const int const instance_pd_width(const struct inst_info *inst);
index 1e6fffc..dd8b957 100644 (file)
@@ -1,6 +1,6 @@
 Name: com.samsung.data-provider-master
 Summary: Master service provider for liveboxes.
-Version: 0.16.13
+Version: 0.16.14
 Release: 1
 Group: framework/livebox
 License: Flora License
index 585d45c..f795feb 100644 (file)
@@ -74,14 +74,14 @@ struct client_node {
        int paused;
 
        Eina_List *event_deactivate_list;
-       Eina_List *event_destroy_list;
+       Eina_List *event_activate_list;
        Eina_List *data_list;
        Eina_List *subscribe_list;
 
        int faulted;
 };
 
-static inline void invoke_global_destroy_cb(struct client_node *client)
+static inline void invoke_global_destroyed_cb(struct client_node *client)
 {
        Eina_List *l;
        Eina_List *n;
@@ -102,7 +102,7 @@ static inline void invoke_global_destroy_cb(struct client_node *client)
        }
 }
 
-static inline void invoke_global_create_cb(struct client_node *client)
+static inline void invoke_global_created_cb(struct client_node *client)
 {
        Eina_List *l;
        Eina_List *n;
@@ -123,32 +123,55 @@ static inline void invoke_global_create_cb(struct client_node *client)
        }
 }
 
-static inline void destroy_client_data(struct client_node *client)
+static inline void invoke_deactivated_cb(struct client_node *client)
 {
-       struct event_item *event;
-       struct data_item *data;
-       struct subscribe_item *item;
+       struct event_item *item;
        Eina_List *l;
        Eina_List *n;
+       int ret;
 
-       DbgPrint("Client %p is destroyed\n", client);
-
-       invoke_global_destroy_cb(client);
-       client_rpc_fini(client); /*!< Finalize the RPC after invoke destroy callbacks */
-
-       EINA_LIST_FOREACH_SAFE(client->event_destroy_list, l, n, event) {
-               if (!event->cb) {
-                       DbgPrint("Callback function is not valid\n");
-                       continue;
+       client_ref(client); /*!< Prevent from client deletion in the callbacks */
+       EINA_LIST_FOREACH_SAFE(client->event_deactivate_list, l, n, item) {
+               ret = item->cb(client, item->data);
+               if (ret < 0) {
+                       if (eina_list_data_find(client->event_deactivate_list, item)) {
+                               client->event_deactivate_list = eina_list_remove(client->event_deactivate_list, item);
+                               DbgFree(item);
+                       }
                }
+       }
+       client_unref(client);
+}
 
-               (void)event->cb(client, event->data);
+static inline void invoke_activated_cb(struct client_node *client)
+{
+       struct event_item *item;
+       Eina_List *l;
+       Eina_List *n;
+       int ret;
 
-               if (eina_list_data_find(client->event_destroy_list, event)) {
-                       client->event_destroy_list = eina_list_remove(client->event_destroy_list, event);
-                       DbgFree(event);
+       client_ref(client); /*!< Prevent from client deletion in the callbacks */
+       EINA_LIST_FOREACH_SAFE(client->event_activate_list, l, n, item) {
+               ret = item->cb(client, item->data);
+               if (ret < 0) {
+                       if (eina_list_data_find(client->event_activate_list, item)) {
+                               client->event_activate_list = eina_list_remove(client->event_activate_list, item);
+                               DbgFree(item);
+                       }
                }
        }
+}
+
+static inline void destroy_client_data(struct client_node *client)
+{
+       struct event_item *event;
+       struct data_item *data;
+       struct subscribe_item *item;
+
+       DbgPrint("Client %p is destroyed\n", client);
+
+       invoke_global_destroyed_cb(client);
+       client_rpc_fini(client); /*!< Finalize the RPC after invoke destroy callbacks */
 
        EINA_LIST_FREE(client->data_list, data) {
                DbgPrint("Tag is not cleared (%s)\n", data->tag);
@@ -194,15 +217,36 @@ static inline struct client_node *create_client_data(pid_t pid)
        client->refcnt = 1;
 
        s_info.client_list = eina_list_append(s_info.client_list, client);
+
+       /*!
+        * \note
+        * Right after create a client ADT,
+        * We assume that the client is paused.
+        */
+       client_paused(client);
+       xmonitor_handle_state_changes();
        return client;
 }
 
 static Eina_Bool created_cb(void *data)
 {
-       invoke_global_create_cb(data);
+       invoke_global_created_cb(data);
+       invoke_activated_cb(data);
+       /*!
+        * \note
+        * Client PAUSE/RESUME event must has to be sent after created event.
+        */
+       xmonitor_update_state(client_pid(data));
        return ECORE_CALLBACK_CANCEL;
 }
 
+/*!
+ * \note
+ * Noramlly, client ADT is created when it send the "acquire" packet.
+ * It means we have the handle for communicating with the client already,
+ * So we just create its ADT in this function.
+ * And invoke the global created event & activated event callbacks
+ */
 HAPI struct client_node *client_create(pid_t pid, int handle)
 {
        struct client_node *client;
@@ -225,24 +269,20 @@ HAPI struct client_node *client_create(pid_t pid, int handle)
                client = client_unref(client);
                ErrPrint("Failed to initialize the RPC for %d, Destroy client data %p(has to be 0x0)\n", pid, client);
        } else {
+               /*!
+                * \note
+                * To save the time to send reply packet to the client.
+                */
                if (ecore_timer_add(DELAY_TIME, created_cb, client) == NULL) {
                        ErrPrint("Failed to add a timer for client created event\n");
                        client = client_unref(client);
                        return NULL;
                }
-
-               xmonitor_update_state(pid);
        }
 
        return client;
 }
 
-HAPI int client_destroy(struct client_node *client)
-{
-       client_unref(client);
-       return 0;
-}
-
 HAPI struct client_node *client_ref(struct client_node *client)
 {
        if (!client)
@@ -328,26 +368,6 @@ HAPI int client_count(void)
        return eina_list_count(s_info.client_list);
 }
 
-static inline void invoke_deactivated_cb(struct client_node *client)
-{
-       struct event_item *item;
-       Eina_List *l;
-       Eina_List *n;
-       int ret;
-
-       client_ref(client); /*!< Prevent deleting from callback */
-       EINA_LIST_FOREACH_SAFE(client->event_deactivate_list, l, n, item) {
-               ret = item->cb(client, item->data);
-               if (ret < 0) {
-                       if (eina_list_data_find(client->event_deactivate_list, item)) {
-                               client->event_deactivate_list = eina_list_remove(client->event_deactivate_list, item);
-                               DbgFree(item);
-                       }
-               }
-       }
-       client_unref(client);
-}
-
 HAPI int client_deactivated_by_fault(struct client_node *client)
 {
        if (!client || client->faulted)
@@ -358,7 +378,7 @@ HAPI int client_deactivated_by_fault(struct client_node *client)
        client->pid = (pid_t)-1;
 
        invoke_deactivated_cb(client);
-       client_destroy(client);
+       (void)client_destroy(client);
        /*!
         * \todo
         * Who invokes this function has to care the reference counter of a client
@@ -424,8 +444,8 @@ HAPI int client_event_callback_add(struct client_node *client, enum client_event
        case CLIENT_EVENT_DEACTIVATE:
                client->event_deactivate_list = eina_list_prepend(client->event_deactivate_list, item);
                break;
-       case CLIENT_EVENT_DESTROY:
-               client->event_destroy_list = eina_list_prepend(client->event_destroy_list, item);
+       case CLIENT_EVENT_ACTIVATE:
+               client->event_activate_list = eina_list_prepend(client->event_activate_list, item);
                break;
        default:
                DbgFree(item);
@@ -457,10 +477,10 @@ HAPI int client_event_callback_del(struct client_node *client, enum client_event
                }
                break;
 
-       case CLIENT_EVENT_DESTROY:
-               EINA_LIST_FOREACH_SAFE(client->event_destroy_list, l, n, item) {
+       case CLIENT_EVENT_ACTIVATE:
+               EINA_LIST_FOREACH_SAFE(client->event_activate_list, l, n, item) {
                        if (item->cb == cb && item->data == data) {
-                               client->event_destroy_list = eina_list_remove(client->event_destroy_list, item);
+                               client->event_activate_list = eina_list_remove(client->event_activate_list, item);
                                DbgFree(item);
                                return 0;
                        }
@@ -562,7 +582,7 @@ HAPI int client_fini(void)
        Eina_List *n;
 
        EINA_LIST_FOREACH_SAFE(s_info.client_list, l, n, client) {
-               client_destroy(client);
+               (void)client_destroy(client);
        }
 
        EINA_LIST_FREE(s_info.create_event_list, handler) {
index feb3abc..06149c6 100644 (file)
@@ -102,6 +102,8 @@ struct inst_info {
                } canvas;
 
                const char *auto_launch;
+               int timeout;
+               double period;
        } lb;
 
        struct {
@@ -122,9 +124,6 @@ struct inst_info {
                int pended_update_cnt;
        } pd;
 
-       int timeout;
-       double period;
-
        struct client_node *client; /*!< Owner - creator */
        Eina_List *client_list; /*!< Viewer list */
        int refcnt;
@@ -309,7 +308,7 @@ HAPI int instance_unicast_created_event(struct inst_info *inst, struct client_no
                        !!inst->client,
                        package_pinup(inst->info),
                        lb_type, pd_type,
-                       inst->period, inst->title,
+                       inst->lb.period, inst->title,
                        inst->is_pinned_up);
        if (!packet) {
                ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
@@ -371,7 +370,7 @@ static int instance_broadcast_created_event(struct inst_info *inst)
                        !!inst->client,
                        package_pinup(inst->info),
                        lb_type, pd_type,
-                       inst->period, inst->title,
+                       inst->lb.period, inst->title,
                        inst->is_pinned_up);
        if (!packet) {
                ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
@@ -537,14 +536,14 @@ static inline int fork_package(struct inst_info *inst, const char *pkgname)
 
        instance_set_pd_info(inst, package_pd_width(info), package_pd_height(info));
 
-       inst->timeout = package_timeout(info);
-       inst->period = package_period(info);
+       inst->lb.timeout = package_timeout(info);
+       inst->lb.period = package_period(info);
 
        inst->info = info;
 
        if (package_secured(info)) {
                DbgPrint("Register the update timer for secured livebox [%s]\n", package_name(info));
-               inst->update_timer = util_timer_add(inst->period, update_timer_cb, inst);
+               inst->update_timer = util_timer_add(inst->lb.period, update_timer_cb, inst);
                if (!inst->update_timer)
                        ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
                else
@@ -986,7 +985,7 @@ static void activate_cb(struct slave_node *slave, const struct packet *packet, v
                        struct inst_info *new_inst;
                        new_inst = instance_create(inst->client, util_timestamp(), package_name(inst->info),
                                                        inst->content, inst->cluster, inst->category,
-                                                       inst->period, 0, 0);
+                                                       inst->lb.period, 0, 0);
                        if (!new_inst)
                                ErrPrint("Failed to create a new instance\n");
                } else {
@@ -1266,9 +1265,9 @@ HAPI int instance_reactivate(struct inst_info *inst)
                        package_name(inst->info),
                        inst->id,
                        inst->content,
-                       inst->timeout,
+                       inst->lb.timeout,
                        !!package_lb_path(inst->info),
-                       inst->period,
+                       inst->lb.period,
                        inst->cluster,
                        inst->category,
                        inst->lb.width, inst->lb.height,
@@ -1330,9 +1329,9 @@ HAPI int instance_activate(struct inst_info *inst)
                        package_name(inst->info),
                        inst->id,
                        inst->content,
-                       inst->timeout,
+                       inst->lb.timeout,
                        !!package_lb_path(inst->info),
-                       inst->period,
+                       inst->lb.period,
                        inst->cluster,
                        inst->category,
                        !!inst->client,
@@ -1790,12 +1789,12 @@ static void set_period_cb(struct slave_node *slave, const struct packet *packet,
        }
 
        if (ret == 0)
-               cbdata->inst->period = cbdata->period;
+               cbdata->inst->lb.period = cbdata->period;
        else
                ErrPrint("Failed to set period %d\n", ret);
 
 out:
-       result = packet_create_noack("period_changed", "idss", ret, cbdata->inst->period, package_name(cbdata->inst->info), cbdata->inst->id);
+       result = packet_create_noack("period_changed", "idss", ret, cbdata->inst->lb.period, package_name(cbdata->inst->info), cbdata->inst->id);
        if (result)
                (void)CLIENT_SEND_EVENT(cbdata->inst, result);
        else
@@ -1817,25 +1816,25 @@ static Eina_Bool timer_updator_cb(void *data)
        inst = cbdata->inst;
        DbgFree(cbdata);
 
-       DbgPrint("Update period is changed to %lf from %lf\n", period, inst->period);
+       DbgPrint("Update period is changed to %lf from %lf\n", period, inst->lb.period);
 
-       inst->period = period;
+       inst->lb.period = period;
        if (inst->update_timer) {
-               if (inst->period == 0.0f) {
+               if (inst->lb.period == 0.0f) {
                        ecore_timer_del(inst->update_timer);
                        inst->update_timer = NULL;
                } else {
-                       util_timer_interval_set(inst->update_timer, inst->period);
+                       util_timer_interval_set(inst->update_timer, inst->lb.period);
                }
-       } else if (inst->period > 0.0f) {
-               inst->update_timer = util_timer_add(inst->period, update_timer_cb, inst);
+       } else if (inst->lb.period > 0.0f) {
+               inst->update_timer = util_timer_add(inst->lb.period, update_timer_cb, inst);
                if (!inst->update_timer)
                        ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
                else
                        timer_freeze(inst); /* Freeze the update timer as default */
        }
 
-       result = packet_create_noack("period_changed", "idss", 0, inst->period, package_name(inst->info), inst->id);
+       result = packet_create_noack("period_changed", "idss", 0, inst->lb.period, package_name(inst->info), inst->id);
        if (result)
                (void)CLIENT_SEND_EVENT(inst, result);
        else
@@ -2092,9 +2091,14 @@ HAPI const struct client_node *const instance_client(const struct inst_info *ins
        return inst->client;
 }
 
+HAPI const int const instance_timeout(const struct inst_info *inst)
+{
+       return inst->lb.timeout;
+}
+
 HAPI const double const instance_period(const struct inst_info *inst)
 {
-       return inst->period;
+       return inst->lb.period;
 }
 
 HAPI const int const instance_lb_width(const struct inst_info *inst)
index a345c68..5b76c64 100644 (file)
@@ -82,6 +82,9 @@ struct pkg_info {
                unsigned int size_list;
                char *auto_launch;
                int pinup;
+               int timeout;
+               double period;
+               char *libexec;
        } lb;
 
        struct {
@@ -107,12 +110,9 @@ struct pkg_info {
        } pd;
 
        int network;
-       int timeout;
-       double period;
        int secured;
        char *script; /* script type: edje, ... */
        char *abi;
-       char *libexec;
 
        int fault_count;
        struct fault_info *fault_info;
@@ -288,7 +288,7 @@ static inline void destroy_package(struct pkg_info *info)
        DbgFree(info->script);
        DbgFree(info->abi);
        DbgFree(info->pkgname);
-       DbgFree(info->libexec);
+       DbgFree(info->lb.libexec);
        DbgFree(info->lb.auto_launch);
 
        DbgFree(info);
@@ -428,14 +428,14 @@ static inline int load_conf(struct pkg_info *info)
                return -ENOMEM;
        }
 
-       info->timeout = parser_timeout(parser);
+       info->lb.timeout = parser_timeout(parser);
        info->network = parser_network(parser);
 
-       info->period = parser_period(parser);
-       if (info->period < 0.0f)
-               info->period = 0.0f;
-       else if (info->period > 0.0f && info->period < MINIMUM_PERIOD)
-               info->period = MINIMUM_PERIOD;
+       info->lb.period = parser_period(parser);
+       if (info->lb.period < 0.0f)
+               info->lb.period = 0.0f;
+       else if (info->lb.period > 0.0f && info->lb.period < MINIMUM_PERIOD)
+               info->lb.period = MINIMUM_PERIOD;
 
        info->lb.size_list = parser_size(parser);
 
@@ -707,22 +707,22 @@ HAPI struct slave_node * const package_slave(const struct pkg_info *info)
 
 HAPI const int const package_timeout(const struct pkg_info *info)
 {
-       return info->timeout;
+       return info->lb.timeout;
 }
 
 HAPI void package_set_timeout(struct pkg_info *info, int timeout)
 {
-       info->timeout = timeout;
+       info->lb.timeout = timeout;
 }
 
 HAPI const double const package_period(const struct pkg_info *info)
 {
-       return info->period;
+       return info->lb.period;
 }
 
 HAPI void package_set_period(struct pkg_info *info, double period)
 {
-       info->period = period;
+       info->lb.period = period;
 }
 
 HAPI const int const package_secured(const struct pkg_info *info)
@@ -974,7 +974,7 @@ HAPI void package_set_lb_type(struct pkg_info *info, enum lb_type type)
 
 HAPI const char * const package_libexec(struct pkg_info *info)
 {
-       return info->libexec;
+       return info->lb.libexec;
 }
 
 HAPI int package_set_libexec(struct pkg_info *info, const char *libexec)
@@ -987,8 +987,8 @@ HAPI int package_set_libexec(struct pkg_info *info, const char *libexec)
                return -ENOMEM;
        }
 
-       DbgFree(info->libexec);
-       info->libexec = tmp;
+       DbgFree(info->lb.libexec);
+       info->lb.libexec = tmp;
        return 0;
 }
 
index b48b580..b0351d4 100644 (file)
@@ -4704,17 +4704,73 @@ out:
        return result;
 }
 
+static struct packet *service_change_period(pid_t pid, int handle, const struct packet *packet)
+{
+       struct inst_info *inst;
+       struct packet *result;
+       const char *pkgname;
+       const char *id;
+       double period;
+       int ret;
+
+       ret = packet_get(packet, "ssd", &pkgname, &id, &period);
+       if (ret != 3) {
+               ErrPrint("Invalid packet\n");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!strlen(id)) {
+               struct pkg_info *pkg;
+
+               pkg = package_find(pkgname);
+               if (!pkg) {
+                       ret = -ENOENT;
+               } else if (package_is_fault(pkg)) {
+                       ret = -EFAULT;
+               } else {
+                       Eina_List *inst_list;
+                       Eina_List *l;
+
+                       inst_list = package_instance_list(pkg);
+                       EINA_LIST_FOREACH(inst_list, l, inst) {
+                               ret = instance_set_period(inst, period);
+                               if (ret < 0)
+                                       DbgPrint("Failed to change the period of %s to (%lf)\n", instance_id(inst), period);
+                       }
+               }
+       } else {
+               inst = package_find_instance_by_id(pkgname, id);
+               if (!inst)
+                       ret = -ENOENT;
+               else if (package_is_fault(instance_package(inst)))
+                       ret = -EFAULT;
+               else
+                       ret = instance_set_period(inst, period);
+       }
+
+       DbgPrint("Change the update period: %s(%s), %lf : %d\n", pkgname, id, period, ret);
+out:
+       result = packet_create_reply(packet, "i", ret);
+       if (!result)
+               ErrPrint("Failed to create a packet\n");
+
+       return result;
+}
+
 static struct packet *service_update(pid_t pid, int handle, const struct packet *packet)
 {
+       struct pkg_info *pkg;
        struct packet *result;
        const char *pkgname;
+       const char *id;
        const char *cluster;
        const char *category;
        char *lb_pkgname;
        int ret;
 
-       ret = packet_get(packet, "sss", &pkgname, &cluster, &category);
-       if (ret != 3) {
+       ret = packet_get(packet, "ssss", &pkgname, &id, &cluster, &category);
+       if (ret != 4) {
                ErrPrint("Invalid Packet\n");
                ret = -EINVAL;
                goto out;
@@ -4727,11 +4783,22 @@ static struct packet *service_update(pid_t pid, int handle, const struct packet
                goto out;
        }
 
+       pkg = package_find(lb_pkgname);
+       if (!pkg) {
+               ret = -ENOENT;
+               goto out;
+       }
+
+       if (package_is_fault(pkg)) {
+               ret = -EFAULT;
+               goto out;
+       }
+
        /*!
         * \TODO
         * Validate the update requstor.
         */
-       slave_rpc_request_update(lb_pkgname, "", cluster, category);
+       slave_rpc_request_update(lb_pkgname, id, cluster, category);
        DbgFree(lb_pkgname);
        ret = 0;
 
@@ -5310,6 +5377,10 @@ static struct method s_service_table[] = {
                .handler = service_update,
        },
        {
+               .cmd = "service_change_period",
+               .handler = service_change_period,
+       },
+       {
                .cmd = NULL,
                .handler = NULL,
        },
index ef89efd..2260133 100644 (file)
@@ -161,6 +161,9 @@ HAPI int xmonitor_update_state(int target_pid)
        struct client_node *client;
        int pid;
 
+       if (!USE_XMONITOR)
+               return 0;
+
        win = ecore_x_window_focus_get();
 
        pid = get_pid(win);