change usb control process name to usb-server
[framework/system/system-server.git] / ss_queue.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.tizenopensource.org/license
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17
18 #include <sysman.h>
19 #include <dlfcn.h>
20 #include "include/ss_data.h"
21 #include "ss_core.h"
22 #include "ss_queue.h"
23 #include "ss_log.h"
24
25 #define SS_PREDEFINE_ACT_FUNC_STR               "ss_predefine_action"
26 #define SS_IS_ACCESSABLE_FUNC_STR               "ss_is_accessable"
27 #define SS_UI_VIEWABLE_FUNC_STR                 "ss_ui_viewable"
28
29 static Eina_List *predef_act_list;
30 static Eina_List *run_queue;
31
32 static struct ss_action_entry *ss_action_entry_find(char *type)
33 {
34         Eina_List *tmp;
35         Eina_List *tmp_next;
36         struct ss_action_entry *data;
37
38         EINA_LIST_FOREACH_SAFE(predef_act_list, tmp, tmp_next, data) {
39                 if ((data != NULL) && (!strcmp(data->type, type)))
40                         return data;
41         }
42
43         return NULL;
44 }
45
46 int ss_action_entry_add_internal(char *type,
47                                  int (*predefine_action) (),
48                                  int (*ui_viewable) (),
49                                  int (*is_accessable) (int))
50 {
51         struct ss_action_entry *data;
52
53         data = malloc(sizeof(struct ss_action_entry));
54
55         if (data == NULL) {
56                 PRT_TRACE_ERR("Malloc failed");
57                 return -1;
58         }
59
60         data->type = NULL;
61         if (ss_action_entry_find(type) != NULL)
62                 goto err;
63
64         data->handle = NULL;
65         data->predefine_action = predefine_action;
66         if (data->predefine_action == NULL)
67                 goto err;
68
69         data->is_accessable = is_accessable;
70         data->ui_viewable = ui_viewable;
71         data->owner_pid = getpid();
72         data->type = strdup(type);
73         data->path = strdup("");
74
75         predef_act_list = eina_list_prepend(predef_act_list, data);
76
77         PRT_TRACE_ERR("[SYSMAN] add predefine action entry suceessfully - %s",
78                   data->type);
79         return 0;
80  err:
81         if (data->type != NULL)
82                 PRT_TRACE_ERR("[SYSMAN] add predefine action entry -%s",
83                               data->type);
84         free(data);
85         return -1;
86 }
87
88 int ss_action_entry_add(struct sysnoti *msg)
89 {
90         struct ss_action_entry *data;
91
92         data = malloc(sizeof(struct ss_action_entry));
93
94         if (data == NULL) {
95                 PRT_TRACE_ERR("Malloc failed");
96                 return -1;
97         }
98
99         if (ss_action_entry_find(msg->type) != NULL)
100                 goto err;
101
102         data->handle = dlopen(msg->path, RTLD_LAZY);
103         if (!data->handle) {
104                 PRT_TRACE_ERR("cannot find such library");
105                 goto err;
106         }
107
108         data->predefine_action = dlsym(data->handle, SS_PREDEFINE_ACT_FUNC_STR);
109         if (data->predefine_action == NULL) {
110                 PRT_TRACE_ERR("cannot find predefine_action symbol : %s",
111                               SS_PREDEFINE_ACT_FUNC_STR);
112                 goto err;
113         }
114
115         data->is_accessable = dlsym(data->handle, SS_IS_ACCESSABLE_FUNC_STR);
116         data->ui_viewable = dlsym(data->handle, SS_UI_VIEWABLE_FUNC_STR);
117         data->owner_pid = msg->pid;
118         data->type = strdup(msg->type);
119         data->path = strdup(msg->path);
120
121         predef_act_list = eina_list_prepend(predef_act_list, data);
122
123         PRT_TRACE_ERR("[SYSMAN]add predefine action entry suceessfully - %s",
124                   data->type);
125         return 0;
126  err:
127         PRT_TRACE_ERR("[SYSMAN] FAIL predefine action entry - %s", msg->type);
128         free(data);
129         return -1;
130 }
131
132 int ss_action_entry_call_internal(char *type, int argc, ...)
133 {
134         Eina_List *tmp;
135         Eina_List *tmp_next;
136         struct ss_action_entry *data;
137         va_list argptr;
138         int i;
139         char *args = NULL;
140         char *argv[SYSMAN_MAXARG];
141
142         if (argc > SYSMAN_MAXARG || type == NULL)
143                 return -1;
144
145         EINA_LIST_FOREACH_SAFE(predef_act_list, tmp, tmp_next, data) {
146                 if ((data != NULL) && (!strcmp(data->type, type))) {
147                         va_start(argptr, argc);
148                         for (i = 0; i < argc; i++) {
149                                 args = va_arg(argptr, char *);
150                                 if (args != NULL)
151                                         argv[i] = strdup(args);
152                                 else
153                                         argv[i] = NULL;
154                         }
155                         va_end(argptr);
156
157                         int ret;
158                         ret=ss_run_queue_add(data, argc, argv);
159                         PRT_TRACE_ERR("ss_run_queue_add : %d",ret);
160                         ret=ss_core_action_run();
161                         PRT_TRACE_ERR("ss_core_action_run : %d",ret);
162                         return 0;
163                 }
164         }
165
166         return 0;
167 }
168
169 int ss_action_entry_call(struct sysnoti *msg, int argc, char **argv)
170 {
171         Eina_List *tmp;
172         Eina_List *tmp_next;
173         struct ss_action_entry *data;
174
175         EINA_LIST_FOREACH_SAFE(predef_act_list, tmp, tmp_next, data) {
176                 if ((data != NULL) && (!strcmp(data->type, msg->type))) {
177                         if (data->is_accessable != NULL
178                             && data->is_accessable(msg->pid) == 0) {
179                                 PRT_TRACE_ERR
180                                     ("%d cannot call that predefine module",
181                                      msg->pid);
182                                 return -1;
183                         }
184                         int ret;
185                         ret=ss_run_queue_add(data, argc, argv);
186                         PRT_TRACE_ERR("ss_run_queue_add : %d",ret);
187                         ret=ss_core_action_run();
188                         PRT_TRACE_ERR("ss_core_action_run : %d",ret);
189                         return 0;
190                 }
191         }
192
193         PRT_TRACE_EM("[SYSMAN] cannot found action");
194         return -1;
195 }
196
197 int ss_run_queue_add(struct ss_action_entry *act_entry, int argc, char **argv)
198 {
199         struct ss_run_queue_entry *rq_entry;
200         int i;
201
202         rq_entry = malloc(sizeof(struct ss_run_queue_entry));
203
204         if (rq_entry == NULL) {
205                 PRT_TRACE_ERR("Malloc failed");
206                 return -1;
207         }
208
209         rq_entry->state = SS_STATE_INIT;
210         rq_entry->action_entry = act_entry;
211         rq_entry->forked_pid = 0;
212         rq_entry->argc = argc;
213         for (i = 0; i < argc; i++)
214                 rq_entry->argv[i] = argv[i];
215
216         run_queue = eina_list_prepend(run_queue, rq_entry);
217
218         PRT_TRACE_EM("[SYSMAN] new action called : %s", act_entry->type);
219         return 0;
220 }
221
222 int ss_run_queue_run(enum ss_run_state state,
223                      int (*run_func) (void *, struct ss_run_queue_entry *),
224                      void *user_data)
225 {
226         Eina_List *tmp;
227         Eina_List *tmp_next;
228         struct ss_run_queue_entry *rq_entry;
229
230         EINA_LIST_FOREACH_SAFE(run_queue, tmp, tmp_next, rq_entry) {
231                 if ((rq_entry != NULL) && (rq_entry->state == state))
232                         run_func(user_data, rq_entry);
233         }
234
235         return 0;
236 }
237
238 struct ss_run_queue_entry *ss_run_queue_find_bypid(int pid)
239 {
240         Eina_List *tmp;
241         Eina_List *tmp_next;
242         struct ss_run_queue_entry *rq_entry;
243
244         EINA_LIST_FOREACH_SAFE(run_queue, tmp, tmp_next, rq_entry) {
245                 if ((rq_entry != NULL) && (rq_entry->forked_pid == pid))
246                         return rq_entry;
247         }
248
249         return NULL;
250 }
251
252 int ss_run_queue_del(struct ss_run_queue_entry *entry)
253 {
254         Eina_List *tmp;
255         Eina_List *tmp_next;
256         struct ss_run_queue_entry *rq_entry;
257         int i;
258
259         EINA_LIST_FOREACH_SAFE(run_queue, tmp, tmp_next, rq_entry) {
260                 if ((rq_entry != NULL) && (rq_entry == entry)) {
261                         run_queue = eina_list_remove(run_queue, rq_entry);
262                         PRT_TRACE_EM("[SYSMAN] action deleted : %s",
263                                      rq_entry->action_entry->type);
264                         for (i = 0; i < rq_entry->argc; i++) {
265                                 if (rq_entry->argv[i])
266                                         free(rq_entry->argv[i]);
267                         }
268                         free(rq_entry);
269                 }
270         }
271
272         return 0;
273 }
274
275 int ss_run_queue_del_bypid(int pid)
276 {
277         Eina_List *tmp;
278         Eina_List *tmp_next;
279         struct ss_run_queue_entry *rq_entry;
280         int i;
281
282         EINA_LIST_FOREACH_SAFE(run_queue, tmp, tmp_next, rq_entry) {
283                 if ((rq_entry != NULL) && (rq_entry->forked_pid == pid)) {
284                         run_queue = eina_list_remove(run_queue, rq_entry);
285                         PRT_TRACE_EM("[SYSMAN] action deleted : %s",
286                                      rq_entry->action_entry->type);
287                         for (i = 0; i < rq_entry->argc; i++) {
288                                 if (rq_entry->argv[i])
289                                         free(rq_entry->argv[i]);
290                         }
291                         free(rq_entry);
292                 }
293         }
294
295         return 0;
296 }
297
298 void ss_queue_init()
299 {
300
301 }