[DONE] Start implement for the monitoring states of instances
authorSung-jae Park <nicesj.park@samsung.com>
Wed, 22 Apr 2015 11:40:46 +0000 (20:40 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Thu, 23 Apr 2015 08:06:34 +0000 (17:06 +0900)
In progress
Add new module - monitor
To multicast events of instances to the service clients.

[model] Redwood,Kiran,B3(Wearable)
[binary_type] AP
[customer] Docomo/Orange/ATT/Open
[issue#] N/A
[problem]
[cause]
[solution]
[team] HomeTF
[request]
[horizontal_expansion]

Change-Id: Icd1222d2bdb3fe9bff095138433dc0edc149c874

CMakeLists.txt
data-provider-master.rule
include/monitor.h [new file with mode: 0644]
src/instance.c
src/monitor.c [new file with mode: 0644]
src/server.c
widget-mgr/src/widget-mgr.c

index bbca47f..470a697 100644 (file)
@@ -126,6 +126,7 @@ IF (LIVEBOX)
                src/event.c
                src/file_service.c
                src/conf.c
+               src/monitor.c
        )
 
        IF (WAYLAND_SUPPORT)
index 726f883..dafbe90 100644 (file)
@@ -8,7 +8,7 @@ data-provider-master::bin tizen::vconf::public::r r----l ------
 data-provider-master::bin data-provider-master::data r-x--- ------
 data-provider-master::bin data-provider-master::share rwx--- ------
 data-provider-master::bin data-provider-master::db rw---- ------
-data-provider-master::bin data-provider-master --x--- ------
+data-provider-master::bin data-provider-master rwx--- ------
 data-provider-master::bin pkgmgr::db rw----- ------
 data-provider-master::bin _ rw---- ------
 data-provider-master::bin security-server::api-privilege-by-pid rw---- ------
diff --git a/include/monitor.h b/include/monitor.h
new file mode 100644 (file)
index 0000000..c08bc2d
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+enum monitor_event_type {
+       MONITOR_EVENT_UNKNOWN = 0x0,
+       MONITOR_EVENT_CREATED = CMD_MONITOR_CREATE,
+       MONITOR_EVENT_DESTROYED = CMD_MONITOR_DESTROY,
+       MONITOR_EVENT_PAUSED = CMD_MONITOR_PAUSE,
+       MONITOR_EVENT_RESUMED = CMD_MONITOR_RESUME
+};
+
+struct monitor_client;
+
+extern struct monitor_client *monitor_create_client(const char *widget_id, pid_t pid, int handle);
+extern int monitor_destroy_client(struct monitor_client *monitor);
+
+extern struct monitor_client *monitor_find_client_by_pid(const char *widget_id, pid_t pid);
+extern struct monitor_client *monitor_find_client_by_handle(const char *widget_id, int handle);
+
+extern int monitor_multicast_state_change_event(const char *widget_id, enum monitor_event_type event, const char *instance_id, const char *content_info);
+
+/* End of a file */
index bc9d324..387485c 100644 (file)
@@ -45,6 +45,7 @@
 #include "script_handler.h"
 #include "buffer_handler.h"
 #include "setting.h"
+#include "monitor.h"
 
 int errno;
 
@@ -501,6 +502,7 @@ static int instance_broadcast_created_event(struct inst_info *inst)
        const char *widget_file;
        const char *gbar_file;
        unsigned int cmd = CMD_CREATED;
+       int ret;
 
        widget_type = package_widget_type(inst->info);
        gbar_type = package_gbar_type(inst->info);
@@ -572,7 +574,11 @@ static int instance_broadcast_created_event(struct inst_info *inst)
                owner_packet = NULL;
        }
 
-       return client_send_event(inst, packet, owner_packet);
+       ret = client_send_event(inst, packet, owner_packet);
+
+       monitor_multicast_state_change_event(package_name(inst->info), MONITOR_EVENT_CREATED, instance_id(inst), instance_content(inst));
+
+       return ret;
 }
 
 HAPI int instance_unicast_deleted_event(struct inst_info *inst, struct client_node *client, int reason)
@@ -617,6 +623,8 @@ static int instance_broadcast_deleted_event(struct inst_info *inst, int reason)
                instance_del_client(inst, client);
        }
 
+       monitor_multicast_state_change_event(package_name(inst->info), MONITOR_EVENT_DESTROYED, instance_id(inst), instance_content(inst));
+
        return ret;
 }
 
@@ -2653,6 +2661,7 @@ HAPI int instance_set_visible_state(struct inst_info *inst, enum widget_visible_
                } else {
                        inst->visible = state;
                }
+               monitor_multicast_state_change_event(package_name(inst->info), MONITOR_EVENT_RESUMED, instance_id(inst), instance_content(inst));
                break;
 
        case WIDGET_HIDE_WITH_PAUSE:
@@ -2661,6 +2670,7 @@ HAPI int instance_set_visible_state(struct inst_info *inst, enum widget_visible_
                }
 
                instance_freeze_updator(inst);
+               monitor_multicast_state_change_event(package_name(inst->info), MONITOR_EVENT_PAUSED, instance_id(inst), instance_content(inst));
                break;
 
        default:
diff --git a/src/monitor.c b/src/monitor.c
new file mode 100644 (file)
index 0000000..3160105
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <Eina.h>
+#include <dlog.h>
+
+#include <widget_errno.h>
+#include <widget_cmd_list.h>
+#include <packet.h>
+#include <com-core_packet.h>
+
+#include "debug.h"
+#include "dead_monitor.h"
+#include "monitor.h"
+#include "util.h"
+
+int errno;
+
+struct monitor_client {
+       char *widget_id;
+       pid_t pid;
+       int handle;
+};
+
+static struct info {
+       Eina_List *monitor_list;
+} s_info = {
+       .monitor_list = NULL,
+};
+
+static void monitor_disconnected_cb(int handle, void *data)
+{
+       struct monitor_client *monitor = data;
+
+       DbgPrint("monitor: %d is deleted (%s)\n", monitor->handle, monitor->widget_id);
+       s_info.monitor_list = eina_list_remove(s_info.monitor_list, monitor);
+       DbgFree(monitor);
+}
+
+HAPI struct monitor_client *monitor_create_client(const char *widget_id, pid_t pid, int handle)
+{
+       struct monitor_client *monitor;
+
+       monitor = calloc(1, sizeof(*monitor));
+       if (!monitor) {
+               ErrPrint("calloc: %d\n", errno);
+               return NULL;
+       }
+
+       if (widget_id) {
+               monitor->widget_id = strdup(widget_id);
+               if (!monitor->widget_id) {
+                       ErrPrint("strdup: %s, %d\n", widget_id, errno);
+                       DbgFree(monitor);
+                       return NULL;
+               }
+       }
+       monitor->pid = pid;
+       monitor->handle = handle;
+
+       if (dead_callback_add(handle, monitor_disconnected_cb, monitor) < 0) {
+               ErrPrint("Failed to register the disconnected callback\n");
+               DbgFree(monitor);
+               return NULL;
+       }
+
+       s_info.monitor_list = eina_list_append(s_info.monitor_list, monitor);
+
+       return monitor;
+}
+
+HAPI int monitor_destroy_client(struct monitor_client *monitor)
+{
+       if (dead_callback_del(monitor->handle, monitor_disconnected_cb) != monitor) {
+               ErrPrint("Registered monitor object is not valid\n");
+       }
+
+       s_info.monitor_list = eina_list_remove(s_info.monitor_list, monitor);
+       DbgFree(monitor->widget_id);
+       DbgFree(monitor);
+       return WIDGET_ERROR_NONE;
+}
+
+HAPI struct monitor_client *monitor_find_client_by_pid(const char *widget_id, pid_t pid)
+{
+       Eina_List *l;
+       struct monitor_client *monitor;
+
+       monitor = NULL;
+       EINA_LIST_FOREACH(s_info.monitor_list, l, monitor) {
+               if (monitor->pid == pid) {
+                       if (monitor->widget_id && widget_id) {
+                               if (!strcmp(monitor->widget_id, widget_id)) {
+                                       break;
+                               }
+                       } else if (monitor->widget_id == widget_id) {
+                               break;
+                       }
+               }
+
+               monitor = NULL;
+       }
+
+       return monitor;
+}
+
+HAPI struct monitor_client *monitor_find_client_by_handle(const char *widget_id, int handle)
+{
+       Eina_List *l;
+       struct monitor_client *monitor;
+
+       monitor = NULL;
+       EINA_LIST_FOREACH(s_info.monitor_list, l, monitor) {
+               if (monitor->handle == handle) {
+                       if (monitor->widget_id && widget_id) {
+                               if (!strcmp(monitor->widget_id, widget_id)) {
+                                       break;
+                               }
+                       } else if (monitor->widget_id == widget_id) {
+                               break;
+                       }
+               }
+
+               monitor = NULL;
+       }
+
+       return monitor;
+}
+
+HAPI int monitor_multicast_state_change_event(const char *widget_id, enum monitor_event_type event, const char *instance_id, const char *content_info)
+{
+       struct monitor_client *monitor;
+       Eina_List *l;
+       int cnt;
+       unsigned int cmd;
+       struct packet *packet;
+
+       cmd = (unsigned int)event;
+
+       packet = packet_create_noack((const char *)&cmd, "dsss", util_timestamp(), widget_id, instance_id, content_info);
+       if (!packet) {
+               ErrPrint("Failed to create a packet\n");
+               return WIDGET_ERROR_FAULT;
+       }
+
+       cnt = 0;
+       EINA_LIST_FOREACH(s_info.monitor_list, l, monitor) {
+               if (widget_id && monitor->widget_id) {
+                       if (!strcmp(widget_id, monitor->widget_id)) {
+                               com_core_packet_send_only(monitor->handle, packet);
+                       }
+               } else if (monitor->widget_id == NULL) {
+                       com_core_packet_send_only(monitor->handle, packet);
+               }
+       }
+
+       packet_destroy(packet);
+
+       DbgPrint("%d events are multicasted\n", cnt);
+       return cnt;
+}
+
+/* End of a file */
index 9a3fec7..fdb46ab 100644 (file)
@@ -55,6 +55,7 @@
 #include "io.h"
 #include "event.h"
 #include "dead_monitor.h"
+#include "monitor.h"
 
 #define GBAR_OPEN_MONITOR_TAG "gbar,open,monitor"
 #define GBAR_RESIZE_MONITOR_TAG "gbar,resize,monitor"
@@ -8397,6 +8398,158 @@ out:
        return result;
 }
 
+static struct packet *service_get_content(pid_t pid, int handle, const struct packet *packet)
+{
+       const char *inst_id;
+       const char *widget_id;
+       struct inst_info *inst;
+       struct packet *result;
+
+       if (packet_get(packet, "ss", &widget_id, &inst_id) != 1) {
+               ErrPrint("Invalid parameter\n");
+               return NULL;
+       }
+
+       inst = package_find_instance_by_id(widget_id, inst_id);
+       if (!inst) {
+               result = packet_create_reply(packet, "is", WIDGET_ERROR_NOT_EXIST, "?");
+       } else {
+               result = packet_create_reply(packet, "is", WIDGET_ERROR_NONE, instance_content(inst));
+       }
+
+       if (!result) {
+               ErrPrint("Failed to create a result packet\n");
+       }
+
+       return result;
+}
+
+static struct packet *service_get_inst_list(pid_t pid, int handle, const struct packet *packet)
+{
+       const char *widget_id;
+       struct pkg_info *pkg;
+       struct packet *result;
+
+       if (packet_get(packet, "s", &widget_id) != 1) {
+               ErrPrint("Invalid parameter\n");
+               return NULL;
+       }
+
+       pkg = package_find(widget_id);
+       if (!pkg) {
+               result = packet_create_reply(packet, "iis", WIDGET_ERROR_NOT_EXIST, 0, NULL);
+       } else {
+               Eina_List *inst_list;
+
+               inst_list = package_instance_list(pkg);
+               if (!inst_list) {
+                       result = packet_create_reply(packet, "iis", WIDGET_ERROR_NOT_EXIST, 0, NULL);
+               } else {
+                       char *id_buffer;
+                       int size = sysconf(_SC_PAGESIZE);
+                       Eina_List *l;
+                       struct inst_info *inst;
+                       int offset;
+                       int len;
+                       int cnt = 0;
+
+                       id_buffer = malloc(size);
+                       if (!id_buffer) {
+                               result = packet_create_reply(packet, "iis", WIDGET_ERROR_OUT_OF_MEMORY, 0, NULL);
+                               goto out;
+                       }
+
+                       offset = 0;
+                       EINA_LIST_FOREACH(inst_list, l, inst) {
+                               len = strlen(instance_id(inst));
+                               if (offset + len > size) {
+                                       /* Expanding the ID_BUFFER */
+                                       char *resized_buffer;
+                                       size += sysconf(_SC_PAGESIZE);
+
+                                       DbgPrint("Expanding heap to %d\n", size);
+
+                                       resized_buffer = realloc(id_buffer, size);
+                                       if (!resized_buffer) {
+                                               ErrPrint("realloc: %d\n", errno);
+                                               DbgFree(id_buffer);
+                                               result = packet_create_reply(packet, "iis", WIDGET_ERROR_OUT_OF_MEMORY, 0, NULL);
+                                               goto out;
+                                       }
+
+                                       id_buffer = resized_buffer;
+                                       cnt++;
+                               }
+
+                               strcpy(id_buffer + offset, instance_id(inst));
+                               /* Replace last NULL with NEW_LINE */
+                               id_buffer[offset + len] = '\n';
+                               offset += (len + 1);
+                       }
+
+                       id_buffer[offset] = '\0';
+                       result = packet_create_reply(packet, "iis", WIDGET_ERROR_NONE, cnt, id_buffer);
+                       DbgFree(id_buffer);
+               }
+       }
+
+out:
+       return result;
+}
+
+static struct packet *monitor_register(pid_t pid, int handle, const struct packet *packet)
+{
+       const char *widget_id;
+
+       if (packet_get(packet, "s", &widget_id) != 1) {
+               ErrPrint("Invalid parameter\n");
+               goto out;
+       }
+
+       if (widget_id[0] == '*' && widget_id[1] == '\0') {
+               widget_id = NULL;
+       }
+
+       DbgPrint("Register monitor target for [%s]\n", widget_id);
+
+       if (monitor_find_client_by_pid(widget_id, pid)) {
+               ErrPrint("Already registered: [%s], %d\n", widget_id, pid);
+       } else {
+               if (monitor_create_client(widget_id, pid, handle) == NULL) {
+                       ErrPrint("Failed to create a new monitor client\n");
+               }
+       }
+
+out:
+       return NULL;
+}
+
+static struct packet *monitor_unregister(pid_t pid, int handle, const struct packet *packet)
+{
+       const char *widget_id;
+       struct monitor_client *monitor;
+
+       if (packet_get(packet, "s", &widget_id) != 1) {
+               ErrPrint("Invalid parameter\n");
+               goto out;
+       }
+
+       if (widget_id[0] == '*' && widget_id[1] == '\0') {
+               widget_id = NULL;
+       }
+
+       monitor = monitor_find_client_by_pid(widget_id, pid);
+       if (monitor) {
+               DbgPrint("Unregister monitor target: %s\n", widget_id);
+               monitor_destroy_client(monitor);
+       } else {
+               ErrPrint("Monitor for %s is not exists(%d)\n", widget_id, pid);
+       }
+
+out:
+       return NULL;
+}
+
 static struct packet *service_change_period(pid_t pid, int handle, const struct packet *packet)
 {
        struct inst_info *inst;
@@ -9403,6 +9556,22 @@ static struct method s_service_table[] = {
                .handler = service_instance_count,
        },
        {
+               .cmd = CMD_STR_MONITOR_REGISTER,
+               .handler = monitor_register,
+       },
+       {
+               .cmd = CMD_STR_MONITOR_UNREGISTER,
+               .handler = monitor_unregister,
+       },
+       {
+               .cmd = CMD_STR_SERVICE_GET_CONTENT,
+               .handler = service_get_content,
+       },
+       {
+               .cmd = CMD_STR_SERVICE_GET_INST_LIST,
+               .handler = service_get_inst_list,
+       },
+       {
                .cmd = NULL,
                .handler = NULL,
        },
index ad06a2e..74764e9 100644 (file)
@@ -41,6 +41,7 @@
 #include <com-core_packet.h>
 #include <com-core.h>
 
+#include <widget_errno.h>
 #include <widget_service.h>
 #include <widget_service_internal.h>
 
@@ -152,6 +153,13 @@ int opterr;
 
 static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler);
 
+static inline const char *trim_cmd(const char *cmd)
+{
+       while (*cmd && *cmd == ' ') cmd++;
+
+       return cmd;
+}
+
 static Eina_Bool process_line_cb(void *data)
 {
        input_cb(NULL, NULL);
@@ -665,9 +673,7 @@ static inline int do_stat(const char *cmd)
                ROOT,
        } type;
 
-       cmd += 5;
-       while (*cmd && *cmd == ' ') cmd++;
-
+       cmd = trim_cmd(cmd + 5);
        if (!*cmd){
                printf("Invalid argument\n");
                return -EINVAL;
@@ -769,11 +775,7 @@ static int do_set(const char *cmd)
        cmd += 4;
        i = get_token(cmd, variable);
 
-       cmd += i;
-       while (*cmd && *cmd == ' ') {
-               cmd++;
-       }
-
+       cmd = trim_cmd(cmd + i);
        if (!i || !*cmd) {
                printf("Invalid argument(%s): set [VAR] [VAL]\n", cmd);
                return -EINVAL;
@@ -785,9 +787,7 @@ static int do_set(const char *cmd)
 
 static inline int do_get(const char *cmd)
 {
-       cmd += 4;
-
-       while (*cmd && *cmd == ' ') cmd++;
+       cmd = trim_cmd(cmd + 4);
        if (!*cmd) {
                printf("Invalid argument(%s): get [VAR]\n", cmd);
                return -EINVAL;
@@ -802,11 +802,7 @@ static inline int do_ls(const char *cmd)
        const char *name;
        struct node *parent;
 
-       cmd += 2;
-
-       while (*cmd && *cmd == ' ') {
-               cmd++;
-       }
+       cmd = trim_cmd(cmd + 2);
 
        s_info.targetdir = *cmd ? update_target_dir(cmd) : s_info.curdir;
        if (!s_info.targetdir) {
@@ -854,12 +850,7 @@ static inline int do_ls(const char *cmd)
 
 static inline int do_cd(const char *cmd)
 {
-       cmd += 2;
-
-       while (*cmd && *cmd == ' ') {
-               cmd++;
-       }
-
+       cmd = trim_cmd(cmd + 2);
        if (!*cmd) {
                return -1;
        }
@@ -891,8 +882,7 @@ static inline int do_cd(const char *cmd)
 
 static inline int do_rm(const char *cmd)
 {
-       cmd += 2;
-       while (*cmd && *cmd == ' ') cmd++;
+       cmd = trim_cmd(cmd + 2);
        if (!*cmd) {
                return -1;
        }
@@ -919,8 +909,7 @@ static inline int do_rm(const char *cmd)
 
 static inline int do_fault(const char *cmd)
 {
-       cmd += 5;
-       while (*cmd && *cmd == ' ') cmd++;
+       cmd = trim_cmd(cmd + 5);
        if (!*cmd) {
                return -1;
        }
@@ -953,12 +942,7 @@ static void do_sh(const char *cmd)
 {
        pid_t pid;
 
-       cmd += 3;
-
-       while (*cmd && *cmd == ' ') {
-               cmd++;
-       }
-
+       cmd = trim_cmd(cmd + 3);
        if (!*cmd) {
                return;
        }
@@ -1110,6 +1094,37 @@ static inline int do_capture(Display *disp, Pixmap id, const char *filename)
        return 0;
 }
 
+static int widget_lifecycle_event(const char *widget_id, widget_lifecycle_event_e ev, const char *instance_id, void *data)
+{
+       printf("[%s] [%s] [STATE: 0x%X]\n", widget_id, instance_id, (unsigned int)ev);
+       return WIDGET_ERROR_NONE;
+}
+
+static void do_monitor(const char *cmd)
+{
+       cmd = trim_cmd(cmd + strlen("monitor"));
+
+       if (!*cmd) {
+               /* Monitor all instances */
+       } else {
+               /* Monitor one */
+               printf("Instance = [%s]\n", cmd);
+       }
+
+       widget_service_set_lifecycle_event_cb(*cmd ? cmd : NULL, widget_lifecycle_event, NULL);
+}
+
+static void do_demonitor(const char *cmd)
+{
+       cmd = trim_cmd(cmd + strlen("demonitor"));
+       if (!*cmd) {
+       } else {
+               printf("Instance = [%s]\n", cmd);
+       }
+
+       widget_service_unset_lifecycle_event_cb(*cmd ? cmd : NULL, NULL);
+}
+
 static void do_dump(const char *cmd)
 {
        char path[256];
@@ -1118,12 +1133,7 @@ static void do_dump(const char *cmd)
        struct node *curdir;
        struct node *target;
 
-       cmd += 5;
-
-       while (*cmd && *cmd == ' ') {
-               cmd++;
-       }
-
+       cmd = trim_cmd(cmd + 5);
        if (!*cmd) {
                return;
        }
@@ -1210,12 +1220,7 @@ static void do_x(const char *cmd)
 {
        Display *disp;
 
-       cmd += 2;
-
-       while (*cmd && *cmd == ' ') {
-               cmd++;
-       }
-
+       cmd = trim_cmd(cmd + 2);
        if (!*cmd) {
                return;
        }
@@ -1337,9 +1342,7 @@ static inline const char *get_command(int idx)
 static void do_command(const char *cmd)
 {
        /* Skip the first spaces */
-       while (*cmd && *cmd == ' ') {
-               cmd++;
-       }
+       cmd = trim_cmd(cmd);
 
        if (strlen(cmd) && *cmd != '#') {
                if (!strncasecmp(cmd, "exit", 4) || !strncasecmp(cmd, "quit", 4)) {
@@ -1370,12 +1373,16 @@ static void do_command(const char *cmd)
                        if (do_fault(cmd) == 0) {
                                return;
                        }
-               } else if (!strncasecmp(cmd, "sh ", 3)) {
+               } else if (!strncasecmp(cmd, "sh ", strlen("sh "))) {
                        do_sh(cmd);
-               } else if (!strncasecmp(cmd, "x ", 2)) {
+               } else if (!strncasecmp(cmd, "x ", strlen("x "))) {
                        do_x(cmd);
-               } else if (!strncasecmp(cmd, "dump", 4)) {
+               } else if (!strncasecmp(cmd, "dump", strlen("dump"))) {
                        do_dump(cmd);
+               } else if (!strncasecmp(cmd, "monitor", strlen("monitor"))) {
+                       do_monitor(cmd);
+               } else if (!strncasecmp(cmd, "demonitor", strlen("demonitor"))) {
+                       do_demonitor(cmd);
                } else {
                        help();
                }