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