refactor getsize sync function
[platform/core/appfw/pkgmgr-server.git] / src / request.c
1 #include <stdlib.h>
2 #include <sys/types.h>
3 #include <sys/time.h>
4
5 #include <glib.h>
6 #include <gio/gio.h>
7 #include <gum/gum-user.h>
8 #include <gum/common/gum-user-types.h>
9
10 #include "queue.h"
11 #include "pkgmgr-server.h"
12 #include "package-manager.h"
13
14 #define RETRY_MAX 5
15 #define RETRY_WAIT_USEC (1000000 / 2) /* 0.5 sec */
16 #define PKGMGR_DBUS_SERVICE "org.tizen.pkgmgr"
17 #define PKGMGR_DBUS_OBJECT_PATH "/org/tizen/pkgmgr"
18
19 static const char instropection_xml[] =
20         "<node>"
21         "  <interface name='org.tizen.pkgmgr'>"
22         "    <method name='install'>"
23         "      <arg type='u' name='uid' direction='in'/>"
24         "      <arg type='s' name='pkgtype' direction='in'/>"
25         "      <arg type='s' name='pkgpath' direction='in'/>"
26         "      <arg type='as' name='args' direction='in'/>"
27         "      <arg type='i' name='ret' direction='out'/>"
28         "      <arg type='s' name='reqkey' direction='out'/>"
29         "    </method>"
30         "    <method name='reinstall'>"
31         "      <arg type='u' name='uid' direction='in'/>"
32         "      <arg type='s' name='pkgid' direction='in'/>"
33         "      <arg type='i' name='ret' direction='out'/>"
34         "      <arg type='s' name='reqkey' direction='out'/>"
35         "    </method>"
36         "    <method name='mount_install'>"
37         "      <arg type='u' name='uid' direction='in'/>"
38         "      <arg type='s' name='pkgtype' direction='in'/>"
39         "      <arg type='s' name='pkgpath' direction='in'/>"
40         "      <arg type='as' name='args' direction='in'/>"
41         "      <arg type='i' name='ret' direction='out'/>"
42         "      <arg type='s' name='reqkey' direction='out'/>"
43         "    </method>"
44         "    <method name='uninstall'>"
45         "      <arg type='u' name='uid' direction='in'/>"
46         "      <arg type='s' name='pkgid' direction='in'/>"
47         "      <arg type='i' name='ret' direction='out'/>"
48         "      <arg type='s' name='reqkey' direction='out'/>"
49         "    </method>"
50         "    <method name='move'>"
51         "      <arg type='u' name='uid' direction='in'/>"
52         "      <arg type='s' name='pkgid' direction='in'/>"
53         "      <arg type='i' name='movetype' direction='in'/>"
54         "      <arg type='i' name='ret' direction='out'/>"
55         "      <arg type='s' name='reqkey' direction='out'/>"
56         "    </method>"
57         "    <method name='enable_pkgs'>"
58         "      <arg type='u' name='uid' direction='in'/>"
59         "      <arg type='as' name='pkgids' direction='in'/>"
60         "      <arg type='i' name='ret' direction='out'/>"
61         "      <arg type='s' name='reqkey' direction='out'/>"
62         "    </method>"
63         "    <method name='disable_pkgs'>"
64         "      <arg type='u' name='uid' direction='in'/>"
65         "      <arg type='as' name='pkgids' direction='in'/>"
66         "      <arg type='i' name='ret' direction='out'/>"
67         "      <arg type='s' name='reqkey' direction='out'/>"
68         "    </method>"
69         "    <method name='enable_app'>"
70         "      <arg type='u' name='uid' direction='in'/>"
71         "      <arg type='s' name='appid' direction='in'/>"
72         "      <arg type='i' name='ret' direction='out'/>"
73         "      <arg type='s' name='reqkey' direction='out'/>"
74         "    </method>"
75         "    <method name='disable_app'>"
76         "      <arg type='u' name='uid' direction='in'/>"
77         "      <arg type='s' name='appid' direction='in'/>"
78         "      <arg type='i' name='ret' direction='out'/>"
79         "      <arg type='s' name='reqkey' direction='out'/>"
80         "    </method>"
81         "    <method name='enable_global_app_for_uid'>"
82         "      <arg type='u' name='uid' direction='in'/>"
83         "      <arg type='s' name='appid' direction='in'/>"
84         "      <arg type='i' name='ret' direction='out'/>"
85         "      <arg type='s' name='reqkey' direction='out'/>"
86         "    </method>"
87         "    <method name='disable_global_app_for_uid'>"
88         "      <arg type='u' name='uid' direction='in'/>"
89         "      <arg type='s' name='appid' direction='in'/>"
90         "      <arg type='i' name='ret' direction='out'/>"
91         "      <arg type='s' name='reqkey' direction='out'/>"
92         "    </method>"
93         "    <method name='getsize'>"
94         "      <arg type='u' name='uid' direction='in'/>"
95         "      <arg type='s' name='pkgid' direction='in'/>"
96         "      <arg type='i' name='get_type' direction='in'/>"
97         "      <arg type='i' name='ret' direction='out'/>"
98         "      <arg type='s' name='reqkey' direction='out'/>"
99         "    </method>"
100         "    <method name='getsize_sync'>"
101         "      <arg type='u' name='uid' direction='in'/>"
102         "      <arg type='s' name='pkgid' direction='in'/>"
103         "      <arg type='i' name='get_type' direction='in'/>"
104         "      <arg type='i' name='ret' direction='out'/>"
105         "      <arg type='x' name='size_info' direction='out'/>"
106         "    </method>"
107         "    <method name='cleardata'>"
108         "      <arg type='u' name='uid' direction='in'/>"
109         "      <arg type='s' name='pkgid' direction='in'/>"
110         "      <arg type='i' name='ret' direction='out'/>"
111         "    </method>"
112         "    <method name='clearcache'>"
113         "      <arg type='u' name='uid' direction='in'/>"
114         "      <arg type='s' name='pkgid' direction='in'/>"
115         "      <arg type='i' name='ret' direction='out'/>"
116         "    </method>"
117         "    <method name='kill'>"
118         "      <arg type='u' name='uid' direction='in'/>"
119         "      <arg type='s' name='pkgid' direction='in'/>"
120         "      <arg type='i' name='ret' direction='out'/>"
121         "      <arg type='i' name='pid' direction='out'/>"
122         "    </method>"
123         "    <method name='check'>"
124         "      <arg type='u' name='uid' direction='in'/>"
125         "      <arg type='s' name='pkgid' direction='in'/>"
126         "      <arg type='i' name='ret' direction='out'/>"
127         "      <arg type='i' name='pid' direction='out'/>"
128         "    </method>"
129         "    <method name='generate_license_request'>"
130         "      <arg type='s' name='resp_data' direction='in'/>"
131         "      <arg type='i' name='ret' direction='out'/>"
132         "      <arg type='s' name='req_data' direction='out'/>"
133         "      <arg type='s' name='license_url' direction='out'/>"
134         "    </method>"
135         "    <method name='register_license'>"
136         "      <arg type='s' name='resp_data' direction='in'/>"
137         "      <arg type='i' name='ret' direction='out'/>"
138         "    </method>"
139         "    <method name='decrypt_package'>"
140         "      <arg type='s' name='drm_file_path' direction='in'/>"
141         "      <arg type='s' name='decrypted_file_path' direction='in'/>"
142         "      <arg type='i' name='ret' direction='out'/>"
143         "    </method>"
144         "    <method name='enable_app_splash_screen'>"
145         "      <arg type='u' name='uid' direction='in'/>"
146         "      <arg type='s' name='appid' direction='in'/>"
147         "      <arg type='i' name='ret' direction='out'/>"
148         "    </method>"
149         "    <method name='disable_app_splash_screen'>"
150         "      <arg type='u' name='uid' direction='in'/>"
151         "      <arg type='s' name='appid' direction='in'/>"
152         "      <arg type='i' name='ret' direction='out'/>"
153         "    </method>"
154         "    <method name='set_restriction_mode'>"
155         "      <arg type='u' name='uid' direction='in'/>"
156         "      <arg type='s' name='pkgid' direction='in'/>"
157         "      <arg type='i' name='mode' direction='in'/>"
158         "      <arg type='i' name='ret' direction='out'/>"
159         "    </method>"
160         "    <method name='unset_restriction_mode'>"
161         "      <arg type='u' name='uid' direction='in'/>"
162         "      <arg type='s' name='pkgid' direction='in'/>"
163         "      <arg type='i' name='mode' direction='in'/>"
164         "      <arg type='i' name='ret' direction='out'/>"
165         "    </method>"
166         "    <method name='get_restriction_mode'>"
167         "      <arg type='u' name='uid' direction='in'/>"
168         "      <arg type='s' name='pkgid' direction='in'/>"
169         "      <arg type='i' name='result' direction='out'/>"
170         "      <arg type='i' name='ret' direction='out'/>"
171         "    </method>"
172         "    <method name='set_app_label'>"
173         "      <arg type='u' name='uid' direction='in'/>"
174         "      <arg type='s' name='appid' direction='in'/>"
175         "      <arg type='s' name='label' direction='in'/>"
176         "      <arg type='i' name='ret' direction='out'/>"
177         "    </method>"
178         "  </interface>"
179         "</node>";
180 static GDBusNodeInfo *instropection_data;
181 static guint reg_id;
182 static guint owner_id;
183 static GHashTable *req_table;
184
185 static char *__generate_reqkey(const char *pkgid)
186 {
187         struct timeval tv;
188         long curtime;
189         char timestr[MAX_PKG_ARGS_LEN];
190         char *str_req_key;
191         int size;
192
193         gettimeofday(&tv, NULL);
194         curtime = tv.tv_sec * 1000000 + tv.tv_usec;
195         snprintf(timestr, sizeof(timestr), "%ld", curtime);
196
197         size = strlen(pkgid) + strlen(timestr) + 2;
198         str_req_key = (char *)calloc(size, sizeof(char));
199         if (str_req_key == NULL) {
200                 DBG("calloc failed");
201                 return NULL;
202         }
203         snprintf(str_req_key, size, "%s_%s", pkgid, timestr);
204
205         return str_req_key;
206 }
207
208 static int __is_admin_user(uid_t uid)
209 {
210         GumUser *guser;
211         GumUserType ut = GUM_USERTYPE_NONE;
212         int retry_cnt = 0;
213
214         do {
215                 guser = gum_user_get_sync(uid, FALSE);
216                 if (guser == NULL) {
217                         ERR("cannot get user information from gumd, retry");
218                         retry_cnt++;
219                         usleep(RETRY_WAIT_USEC);
220                         continue;
221                 }
222                 break;
223         } while (retry_cnt <= RETRY_MAX);
224
225         if (guser == NULL) {
226                 ERR("cannot get user information from gumd, failed");
227                 return -1;
228         }
229
230         g_object_get(G_OBJECT(guser), "usertype", &ut, NULL);
231         if (ut == GUM_USERTYPE_NONE) {
232                 ERR("cannot get user type");
233                 g_object_unref(guser);
234                 return -1;
235         } else if (ut != GUM_USERTYPE_ADMIN) {
236                 g_object_unref(guser);
237                 return 0;
238         }
239
240         g_object_unref(guser);
241
242         return 1;
243 }
244
245 static int __check_caller_permission(uid_t uid,
246                 GDBusMethodInvocation *invocation, GVariant *parameters)
247 {
248         GVariant *v;
249         uid_t target_uid;
250         int is_admin;
251
252         if (uid < REGULAR_USER)
253                 return 0;
254
255         v = g_variant_get_child_value(parameters, 0);
256         if (v == NULL) {
257                 g_dbus_method_invocation_return_error_literal(invocation,
258                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
259                                 "Internal error.");
260                 return -1;
261         }
262
263         target_uid = g_variant_get_uint32(v);
264         g_variant_unref(v);
265         if (uid == target_uid)
266                 return 0;
267
268         is_admin = __is_admin_user(uid);
269         if (is_admin == -1) {
270                 g_dbus_method_invocation_return_error_literal(invocation,
271                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
272                                 "Internal error.");
273                 return -1;
274         } else if (is_admin == 0) {
275                 g_dbus_method_invocation_return_error_literal(invocation,
276                                 G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED,
277                                 "Non-admin user cannot request operation to "
278                                 "other users.");
279                 return -1;
280         }
281
282         return 0;
283 }
284
285 static int __handle_request_install(uid_t caller_uid,
286                 GDBusMethodInvocation *invocation, GVariant *parameters)
287 {
288         uid_t target_uid = (uid_t)-1;
289         char *arg_pkgtype = NULL;
290         const char *pkgtype;
291         char *pkgpath = NULL;
292         char *args = NULL;
293         char *reqkey = NULL;
294         gchar **tmp_args = NULL;
295         gsize args_count;
296         int ret = -1;
297         GVariant *value;
298         int i = 0;
299         int len = 0;
300
301         g_variant_get(parameters, "(u&s&s@as)", &target_uid, &arg_pkgtype,
302                         &pkgpath, &value);
303         tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
304
305         for (i = 0; i < args_count; i++)
306                 len = len + strlen(tmp_args[i]) + 1;
307
308         args = (char *)calloc(len, sizeof(char));
309         if (args == NULL) {
310                 ERR("calloc failed");
311                 g_dbus_method_invocation_return_value(invocation,
312                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
313                 ret = -1;
314                 goto catch;
315         }
316
317         for (i = 0; i < args_count; i++) {
318                 strncat(args, tmp_args[i], strlen(tmp_args[i]));
319                 if (i != args_count - 1)
320                         strncat(args, " ", strlen(" "));
321         }
322
323         if (target_uid == (uid_t)-1 || pkgpath == NULL) {
324                 g_dbus_method_invocation_return_value(invocation,
325                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
326                 ret = -1;
327                 goto catch;
328         }
329
330         pkgtype = _get_pkgtype_from_file(pkgpath, caller_uid);
331         if (!pkgtype && arg_pkgtype && strlen(arg_pkgtype))
332                 pkgtype = (const char *)arg_pkgtype;
333         if (pkgtype == NULL) {
334                 g_dbus_method_invocation_return_value(invocation,
335                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
336                 ret = -1;
337                 goto catch;
338         }
339
340         reqkey = __generate_reqkey(pkgpath);
341         if (reqkey == NULL) {
342                 g_dbus_method_invocation_return_value(invocation,
343                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
344                 ret = -1;
345                 goto catch;
346         }
347
348         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_INSTALL,
349                                 pkgtype, pkgpath, args)) {
350                 g_dbus_method_invocation_return_value(invocation,
351                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
352                 ret = -1;
353                 goto catch;
354         }
355
356         g_dbus_method_invocation_return_value(invocation,
357                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
358
359         ret = 0;
360
361 catch:
362         if (reqkey)
363                 free(reqkey);
364
365         if (args)
366                 free(args);
367
368         if (tmp_args)
369                 g_free(tmp_args);
370
371         return ret;
372 }
373
374 static int __handle_request_mount_install(uid_t caller_uid,
375         GDBusMethodInvocation *invocation, GVariant *parameters)
376 {
377         uid_t target_uid = (uid_t)-1;
378         char *arg_pkgtype = NULL;
379         const char *pkgtype;
380         char *pkgpath = NULL;
381         char *args = NULL;
382         char *reqkey = NULL;
383         gchar **tmp_args = NULL;
384         gsize args_count;
385         int ret = -1;
386         GVariant *value;
387         int i = 0;
388         int len = 0;
389
390         g_variant_get(parameters, "(u&s&s@as)", &target_uid, &arg_pkgtype,
391                         &pkgpath, &value);
392         tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
393
394         for (i = 0; i < args_count; i++)
395                 len = len + strlen(tmp_args[i]) + 1;
396
397         args = (char *)calloc(len, sizeof(char));
398         if (args == NULL) {
399                 ERR("calloc failed");
400                 g_dbus_method_invocation_return_value(invocation,
401                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
402                 ret = -1;
403                 goto catch;
404         }
405
406         for (i = 0; i < args_count; i++) {
407                 strncat(args, tmp_args[i], strlen(tmp_args[i]));
408                 if (i != args_count - 1)
409                         strncat(args, " ", strlen(" "));
410         }
411
412         if (target_uid == (uid_t)-1 || pkgpath == NULL) {
413                 g_dbus_method_invocation_return_value(invocation,
414                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
415                 ret = -1;
416                 goto catch;
417         }
418
419         pkgtype = _get_pkgtype_from_file(pkgpath, caller_uid);
420         if (!pkgtype && arg_pkgtype && strlen(arg_pkgtype))
421                 pkgtype = (const char *)arg_pkgtype;
422         if (pkgtype == NULL) {
423                 g_dbus_method_invocation_return_value(invocation,
424                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
425                 ret = -1;
426                 goto catch;
427         }
428
429         reqkey = __generate_reqkey(pkgpath);
430         if (reqkey == NULL) {
431                 g_dbus_method_invocation_return_value(invocation,
432                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
433                 ret = -1;
434                 goto catch;
435         }
436
437         if (_push_queue(target_uid, caller_uid, reqkey,
438                                 REQUEST_TYPE_MOUNT_INSTALL,
439                                 pkgtype, pkgpath, args)) {
440                 g_dbus_method_invocation_return_value(invocation,
441                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
442                 ret = -1;
443                 goto catch;
444         }
445
446         g_dbus_method_invocation_return_value(invocation,
447                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
448         ret = 0;
449
450 catch:
451         if (reqkey)
452                 free(reqkey);
453
454         if (args)
455                 free(args);
456
457         if (tmp_args)
458                 g_free(tmp_args);
459
460         return ret;
461 }
462
463 static int __handle_request_reinstall(uid_t caller_uid,
464                 GDBusMethodInvocation *invocation, GVariant *parameters)
465 {
466         uid_t target_uid = (uid_t)-1;
467         char *pkgtype;
468         char *pkgid = NULL;
469         char *reqkey;
470
471         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
472         if (target_uid == (uid_t)-1 || pkgid == NULL) {
473                 g_dbus_method_invocation_return_value(invocation,
474                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
475                 return -1;
476         }
477
478         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
479         if (pkgtype == NULL) {
480                 g_dbus_method_invocation_return_value(invocation,
481                                 g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
482                 return -1;
483         }
484
485         reqkey = __generate_reqkey(pkgid);
486         if (reqkey == NULL) {
487                 g_dbus_method_invocation_return_value(invocation,
488                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
489                 free(pkgtype);
490                 return -1;
491         }
492         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_REINSTALL,
493                                 pkgtype, pkgid, NULL)) {
494                 g_dbus_method_invocation_return_value(invocation,
495                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
496                 free(reqkey);
497                 free(pkgtype);
498                 return -1;
499         }
500
501         g_dbus_method_invocation_return_value(invocation,
502                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
503         free(reqkey);
504         free(pkgtype);
505
506         return 0;
507 }
508
509 static int __handle_request_uninstall(uid_t caller_uid,
510                 GDBusMethodInvocation *invocation, GVariant *parameters)
511 {
512         uid_t target_uid = (uid_t)-1;
513         char *pkgtype;
514         char *pkgid = NULL;
515         char *reqkey;
516
517         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
518         if (target_uid == (uid_t)-1 || pkgid == NULL) {
519                 g_dbus_method_invocation_return_value(invocation,
520                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
521                 return -1;
522         }
523
524         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
525         if (pkgtype == NULL) {
526                 g_dbus_method_invocation_return_value(invocation,
527                                 g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
528                 return -1;
529         }
530
531         reqkey = __generate_reqkey(pkgid);
532         if (reqkey == NULL) {
533                 g_dbus_method_invocation_return_value(invocation,
534                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
535                 free(pkgtype);
536                 return -1;
537         }
538         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_UNINSTALL,
539                                 pkgtype, pkgid, NULL)) {
540                 g_dbus_method_invocation_return_value(invocation,
541                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
542                 free(reqkey);
543                 free(pkgtype);
544                 return -1;
545         }
546
547         g_dbus_method_invocation_return_value(invocation,
548                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
549         free(reqkey);
550         free(pkgtype);
551
552         return 0;
553 }
554
555 static int __handle_request_move(uid_t caller_uid,
556                 GDBusMethodInvocation *invocation, GVariant *parameters)
557 {
558         uid_t target_uid = (uid_t)-1;
559         char *pkgtype;
560         char *pkgid = NULL;
561         char *reqkey;
562         int move_type = -1;
563         char buf[4] = { '\0' };
564
565         g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &move_type);
566         if (target_uid == (uid_t)-1 || pkgid == NULL) {
567                 g_dbus_method_invocation_return_value(invocation,
568                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
569                 return -1;
570         }
571
572         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
573         if (pkgtype == NULL) {
574                 g_dbus_method_invocation_return_value(invocation,
575                                 g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
576                 return -1;
577         }
578
579         reqkey = __generate_reqkey(pkgid);
580         if (reqkey == NULL) {
581                 g_dbus_method_invocation_return_value(invocation,
582                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
583                 free(pkgtype);
584                 return -1;
585         }
586
587         snprintf(buf, sizeof(buf), "%d", move_type);
588         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_MOVE,
589                                 pkgtype, pkgid, buf)) {
590                 g_dbus_method_invocation_return_value(invocation,
591                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
592                 free(reqkey);
593                 free(pkgtype);
594                 return -1;
595         }
596
597         g_dbus_method_invocation_return_value(invocation,
598                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
599         free(reqkey);
600         free(pkgtype);
601
602         return 0;
603 }
604
605 static int __handle_request_enable_pkgs(uid_t caller_uid,
606                 GDBusMethodInvocation *invocation, GVariant *parameters)
607 {
608         uid_t target_uid = (uid_t)-1;
609         char *pkgtype;
610         char *pkgid;
611         char *reqkey;
612         GVariantIter *iter;
613
614         g_variant_get(parameters, "(uas)", &target_uid, &iter);
615         if (target_uid == (uid_t)-1 || iter == NULL) {
616                 g_dbus_method_invocation_return_value(invocation,
617                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
618                 return -1;
619         }
620
621         reqkey = __generate_reqkey("enable_pkgs");
622         if (reqkey == NULL) {
623                 g_dbus_method_invocation_return_value(invocation,
624                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
625                 return -1;
626         }
627
628         while (g_variant_iter_next(iter, "&s", &pkgid)) {
629                 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
630                 if (pkgtype == NULL) {
631                         g_dbus_method_invocation_return_value(invocation,
632                                         g_variant_new("(is)",
633                                                 PKGMGR_R_ENOPKG, ""));
634                         free(reqkey);
635                         return -1;
636                 }
637                 if (_push_queue(target_uid, caller_uid, reqkey,
638                                         REQUEST_TYPE_ENABLE_PKG,
639                                         pkgtype, pkgid, NULL)) {
640                         g_dbus_method_invocation_return_value(invocation,
641                                         g_variant_new("(is)",
642                                                 PKGMGR_R_ESYSTEM, ""));
643                         free(pkgtype);
644                         free(reqkey);
645                         return -1;
646                 }
647                 free(pkgtype);
648         }
649
650         g_dbus_method_invocation_return_value(invocation,
651                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
652         free(reqkey);
653
654         return 0;
655 }
656
657 static int __handle_request_disable_pkgs(uid_t caller_uid,
658                 GDBusMethodInvocation *invocation, GVariant *parameters)
659 {
660         uid_t target_uid = (uid_t)-1;
661         char *pkgtype;
662         char *pkgid;
663         char *reqkey;
664         GVariantIter *iter;
665
666         g_variant_get(parameters, "(uas)", &target_uid, &iter);
667         if (target_uid == (uid_t)-1 || iter == NULL) {
668                 g_dbus_method_invocation_return_value(invocation,
669                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
670                 return -1;
671         }
672
673         reqkey = __generate_reqkey("disable_pkgs");
674         if (reqkey == NULL) {
675                 g_dbus_method_invocation_return_value(invocation,
676                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
677                 return -1;
678         }
679
680         while (g_variant_iter_next(iter, "&s", &pkgid)) {
681                 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
682                 if (pkgtype == NULL) {
683                         g_dbus_method_invocation_return_value(invocation,
684                                         g_variant_new("(is)",
685                                                 PKGMGR_R_ENOPKG, ""));
686                         free(reqkey);
687                         return -1;
688                 }
689                 if (_push_queue(target_uid, caller_uid, reqkey,
690                                         REQUEST_TYPE_DISABLE_PKG,
691                                         pkgtype, pkgid, NULL)) {
692                         g_dbus_method_invocation_return_value(invocation,
693                                         g_variant_new("(is)",
694                                                 PKGMGR_R_ESYSTEM, ""));
695                         free(pkgtype);
696                         free(reqkey);
697                         return -1;
698                 }
699                 free(pkgtype);
700         }
701
702         g_dbus_method_invocation_return_value(invocation,
703                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
704         free(reqkey);
705
706         return 0;
707 }
708
709 static int __handle_request_enable_app(uid_t caller_uid,
710                 GDBusMethodInvocation *invocation, GVariant *parameters)
711 {
712         uid_t target_uid = (uid_t)-1;
713         char *appid = NULL;
714         char *reqkey = NULL;
715         int ret = -1;
716
717         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
718         if (target_uid == (uid_t)-1 || appid == NULL) {
719                 g_dbus_method_invocation_return_value(invocation,
720                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
721                 return -1;
722         }
723
724         reqkey = __generate_reqkey(appid);
725         if (reqkey == NULL) {
726                 g_dbus_method_invocation_return_value(invocation,
727                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
728                 ret = -1;
729                 goto catch;
730         }
731
732         if (_push_queue(target_uid, caller_uid, reqkey,
733                                 REQUEST_TYPE_ENABLE_APP, "default",
734                                 appid, NULL)) {
735                 g_dbus_method_invocation_return_value(invocation,
736                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
737                 ret = -1;
738                 goto catch;
739         }
740
741         g_dbus_method_invocation_return_value(invocation,
742                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
743
744         ret = 0;
745
746 catch:
747         if (reqkey)
748                 free(reqkey);
749
750         return ret;
751 }
752
753 static int __handle_request_disable_app(uid_t caller_uid,
754                 GDBusMethodInvocation *invocation, GVariant *parameters)
755 {
756         uid_t target_uid = (uid_t)-1;
757         char *appid = NULL;
758         char *reqkey = NULL;
759         int ret = -1;
760
761         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
762         if (target_uid == (uid_t)-1 || appid == NULL) {
763                 g_dbus_method_invocation_return_value(invocation,
764                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
765                 return -1;
766         }
767
768         reqkey = __generate_reqkey(appid);
769         if (reqkey == NULL) {
770                 g_dbus_method_invocation_return_value(invocation,
771                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
772                 ret = -1;
773                 goto catch;
774         }
775
776         if (_push_queue(target_uid, caller_uid, reqkey,
777                                 REQUEST_TYPE_DISABLE_APP, "default",
778                                 appid, NULL)) {
779                 g_dbus_method_invocation_return_value(invocation,
780                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
781                 ret = -1;
782                 goto catch;
783         }
784
785         g_dbus_method_invocation_return_value(invocation,
786                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
787
788         ret = 0;
789
790 catch:
791         if (reqkey)
792                 free(reqkey);
793
794         return ret;
795 }
796
797 static int __handle_request_enable_global_app_for_uid(uid_t caller_uid,
798                 GDBusMethodInvocation *invocation, GVariant *parameters)
799 {
800         uid_t target_uid = (uid_t)-1;
801         char *appid = NULL;
802         char *reqkey = NULL;
803         int ret = -1;
804
805         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
806         if (target_uid == (uid_t)-1 || appid == NULL) {
807                 g_dbus_method_invocation_return_value(invocation,
808                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
809                 return -1;
810         }
811
812         reqkey = __generate_reqkey(appid);
813         if (reqkey == NULL) {
814                 g_dbus_method_invocation_return_value(invocation,
815                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
816                 ret = -1;
817                 goto catch;
818         }
819
820         if (_push_queue(target_uid, caller_uid, reqkey,
821                                 REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID,
822                                 "default", appid, NULL)) {
823                 g_dbus_method_invocation_return_value(invocation,
824                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
825                 ret = -1;
826                 goto catch;
827         }
828
829         g_dbus_method_invocation_return_value(invocation,
830                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
831
832         ret = 0;
833
834 catch:
835         if (reqkey)
836                 free(reqkey);
837
838         return ret;
839 }
840
841 static int __handle_request_disable_global_app_for_uid(uid_t caller_uid,
842                 GDBusMethodInvocation *invocation, GVariant *parameters)
843 {
844         uid_t target_uid = (uid_t)-1;
845         char *appid = NULL;
846         char *reqkey = NULL;
847         int ret = -1;
848
849         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
850         if (target_uid == (uid_t)-1 || appid == NULL) {
851                 g_dbus_method_invocation_return_value(invocation,
852                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
853                 return -1;
854         }
855
856         reqkey = __generate_reqkey(appid);
857         if (reqkey == NULL) {
858                 g_dbus_method_invocation_return_value(invocation,
859                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
860                 ret = -1;
861                 goto catch;
862         }
863
864         if (_push_queue(target_uid, caller_uid, reqkey,
865                                 REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID,
866                                 "default", appid, NULL)) {
867                 g_dbus_method_invocation_return_value(invocation,
868                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
869                 ret = -1;
870                 goto catch;
871         }
872
873         g_dbus_method_invocation_return_value(invocation,
874                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
875
876         ret = 0;
877
878 catch:
879         if (reqkey)
880                 free(reqkey);
881
882         return ret;
883 }
884
885 static int __handle_request_getsize(uid_t caller_uid,
886                 GDBusMethodInvocation *invocation, GVariant *parameters)
887 {
888         uid_t target_uid = (uid_t)-1;
889         char *pkgid = NULL;
890         int get_type = -1;
891         char *reqkey;
892         char buf[4];
893
894         g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
895         if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
896                 g_dbus_method_invocation_return_value(invocation,
897                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
898                 return -1;
899         }
900
901         reqkey = __generate_reqkey(pkgid);
902         if (reqkey == NULL) {
903                 g_dbus_method_invocation_return_value(invocation,
904                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
905                 return -1;
906         }
907
908         snprintf(buf, sizeof(buf), "%d", get_type);
909         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_GETSIZE,
910                                 "pkgtool", pkgid, buf)) {
911                 g_dbus_method_invocation_return_value(invocation,
912                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
913                 free(reqkey);
914                 return -1;
915         }
916
917         g_dbus_method_invocation_return_value(invocation,
918                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
919         free(reqkey);
920
921         return 0;
922 }
923
924 static int __handle_request_getsize_sync(uid_t caller_uid,
925                 GDBusMethodInvocation *invocation, GVariant *parameters)
926 {
927         uid_t target_uid = (uid_t)-1;
928         char *pkgid = NULL;
929         int get_type = -1;
930         char *reqkey;
931         char buf[4];
932
933         g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
934         if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
935                 g_dbus_method_invocation_return_value(invocation,
936                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
937                 return -1;
938         }
939
940         reqkey = __generate_reqkey(pkgid);
941         if (reqkey == NULL) {
942                 g_dbus_method_invocation_return_value(invocation,
943                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
944                 return -1;
945         }
946
947         snprintf(buf, sizeof(buf), "%d", get_type);
948         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_GETSIZE_SYNC,
949                                 "pkgtool", pkgid, buf)) {
950                 g_dbus_method_invocation_return_value(invocation,
951                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
952                 free(reqkey);
953                 return -1;
954         }
955
956         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
957                                 (gpointer)invocation))
958                 ERR("reqkey already exists");
959
960         return 0;
961 }
962
963 static int __handle_request_cleardata(uid_t caller_uid,
964                 GDBusMethodInvocation *invocation, GVariant *parameters)
965 {
966         uid_t target_uid = (uid_t)-1;
967         char *pkgtype;
968         char *pkgid = NULL;
969         char *reqkey = NULL;
970
971         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
972         if (target_uid == (uid_t)-1 || pkgid == NULL) {
973                 g_dbus_method_invocation_return_value(invocation,
974                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
975                 return -1;
976         }
977
978         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
979         if (pkgtype == NULL) {
980                 g_dbus_method_invocation_return_value(invocation,
981                                 g_variant_new("(i)", PKGMGR_R_ENOPKG));
982                 return -1;
983         }
984
985         reqkey = __generate_reqkey(pkgid);
986         if (reqkey == NULL) {
987                 g_dbus_method_invocation_return_value(invocation,
988                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
989                 free(pkgtype);
990                 return -1;
991         }
992
993         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CLEARDATA,
994                                 pkgtype, pkgid, NULL)) {
995                 g_dbus_method_invocation_return_value(invocation,
996                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
997                 free(reqkey);
998                 free(pkgtype);
999                 return -1;
1000         }
1001
1002         g_dbus_method_invocation_return_value(invocation,
1003                         g_variant_new("(i)", PKGMGR_R_OK));
1004
1005         free(reqkey);
1006         free(pkgtype);
1007
1008         return 0;
1009 }
1010
1011 static int __handle_request_clearcache(uid_t caller_uid,
1012                 GDBusMethodInvocation *invocation, GVariant *parameters)
1013 {
1014         uid_t target_uid = (uid_t)-1;
1015         char *pkgid = NULL;
1016
1017         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1018         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1019                 g_dbus_method_invocation_return_value(invocation,
1020                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1021                 return -1;
1022         }
1023
1024         if (_push_queue(target_uid, caller_uid, NULL, REQUEST_TYPE_CLEARCACHE,
1025                                 "pkgtool",  pkgid, NULL)) {
1026                 g_dbus_method_invocation_return_value(invocation,
1027                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1028                 return -1;
1029         }
1030
1031         g_dbus_method_invocation_return_value(invocation,
1032                         g_variant_new("(i)", PKGMGR_R_OK));
1033
1034         return 0;
1035 }
1036
1037 static int __handle_request_kill(uid_t caller_uid,
1038                 GDBusMethodInvocation *invocation, GVariant *parameters)
1039 {
1040         uid_t target_uid = (uid_t)-1;
1041         char *pkgid = NULL;
1042         char *reqkey = NULL;
1043
1044         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1045         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1046                 g_dbus_method_invocation_return_value(invocation,
1047                                 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1048                 return -1;
1049         }
1050
1051         reqkey = __generate_reqkey(pkgid);
1052         if (reqkey == NULL) {
1053                 g_dbus_method_invocation_return_value(invocation,
1054                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1055                 return -1;
1056         }
1057
1058         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_KILL,
1059                                 "default", pkgid, NULL)) {
1060                 g_dbus_method_invocation_return_value(invocation,
1061                                 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1062                 free(reqkey);
1063                 return -1;
1064         }
1065
1066         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1067                                 (gpointer)invocation))
1068                 ERR("reqkey already exists");
1069
1070         return 0;
1071 }
1072
1073 static int __handle_request_check(uid_t caller_uid,
1074                 GDBusMethodInvocation *invocation, GVariant *parameters)
1075 {
1076         uid_t target_uid = (uid_t)-1;
1077         char *pkgid = NULL;
1078         char *reqkey = NULL;
1079
1080         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1081         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1082                 g_dbus_method_invocation_return_value(invocation,
1083                                 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1084                 return -1;
1085         }
1086
1087         reqkey = __generate_reqkey(pkgid);
1088         if (reqkey == NULL) {
1089                 g_dbus_method_invocation_return_value(invocation,
1090                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1091                 return -1;
1092         }
1093
1094         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CHECK,
1095                                 "default", pkgid, NULL)) {
1096                 g_dbus_method_invocation_return_value(invocation,
1097                                 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1098                 free(reqkey);
1099                 return -1;
1100         }
1101
1102         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1103                                 (gpointer)invocation))
1104                 ERR("reqkey already exists");
1105
1106         return 0;
1107 }
1108
1109 static int __handle_request_generate_license_request(uid_t caller_uid,
1110                 GDBusMethodInvocation *invocation, GVariant *parameters)
1111 {
1112         char *reqkey;
1113         char *resp_data = NULL;
1114
1115         g_variant_get(parameters, "(&s)", &resp_data);
1116         if (resp_data == NULL) {
1117                 g_dbus_method_invocation_return_value(invocation,
1118                                 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
1119                 return -1;
1120         }
1121
1122         reqkey = __generate_reqkey("drm");
1123         if (reqkey == NULL) {
1124                 g_dbus_method_invocation_return_value(invocation,
1125                                 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
1126                                         ""));
1127                 return -1;
1128         }
1129
1130         if (_push_queue(caller_uid, caller_uid, reqkey,
1131                                 REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
1132                                 "default", NULL, resp_data)) {
1133                 g_dbus_method_invocation_return_value(invocation,
1134                                 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
1135                                         ""));
1136                 free(reqkey);
1137                 return -1;
1138         }
1139
1140         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1141                                 (gpointer)invocation))
1142                 ERR("reqkey already exists");
1143
1144         return 0;
1145 }
1146
1147 static int __handle_request_register_license(uid_t caller_uid,
1148                 GDBusMethodInvocation *invocation, GVariant *parameters)
1149 {
1150         char *reqkey;
1151         char *resp_data = NULL;
1152
1153         g_variant_get(parameters, "(&s)", &resp_data);
1154         if (resp_data == NULL) {
1155                 g_dbus_method_invocation_return_value(invocation,
1156                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1157                 return -1;
1158         }
1159
1160         reqkey = __generate_reqkey("drm");
1161         if (reqkey == NULL) {
1162                 g_dbus_method_invocation_return_value(invocation,
1163                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1164                 return -1;
1165         }
1166
1167         if (_push_queue(caller_uid, caller_uid, reqkey,
1168                                 REQUEST_TYPE_REGISTER_LICENSE,
1169                                 "default", NULL, resp_data)) {
1170                 g_dbus_method_invocation_return_value(invocation,
1171                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1172                 free(reqkey);
1173                 return -1;
1174         }
1175
1176         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1177                                 (gpointer)invocation))
1178                 ERR("reqkey already exists");
1179
1180         return 0;
1181 }
1182
1183 static int __handle_request_decrypt_package(uid_t caller_uid,
1184                 GDBusMethodInvocation *invocation, GVariant *parameters)
1185 {
1186         char *reqkey;
1187         char *drm_file_path = NULL;
1188         char *decrypted_file_path = NULL;
1189
1190         g_variant_get(parameters, "(&s&s)", &drm_file_path,
1191                         &decrypted_file_path);
1192         if (drm_file_path == NULL || decrypted_file_path == NULL) {
1193                 g_dbus_method_invocation_return_value(invocation,
1194                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1195                 return -1;
1196         }
1197
1198         reqkey = __generate_reqkey("drm");
1199         if (reqkey == NULL) {
1200                 g_dbus_method_invocation_return_value(invocation,
1201                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1202                 return -1;
1203         }
1204
1205         if (_push_queue(caller_uid, caller_uid, reqkey,
1206                                 REQUEST_TYPE_DECRYPT_PACKAGE,
1207                                 "default", drm_file_path,
1208                                 decrypted_file_path)) {
1209                 g_dbus_method_invocation_return_value(invocation,
1210                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1211                 free(reqkey);
1212                 return -1;
1213         }
1214
1215         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1216                                 (gpointer)invocation))
1217                 ERR("reqkey already exists");
1218
1219         return 0;
1220 }
1221
1222 static int __update_app_splash_screen(uid_t caller_uid,
1223                 GDBusMethodInvocation *invocation, GVariant *parameters,
1224                 int req_type)
1225 {
1226         uid_t target_uid = (uid_t)-1;
1227         char *appid = NULL;
1228         char *reqkey;
1229
1230         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
1231         if (target_uid == (uid_t)-1 || appid == NULL) {
1232                 ERR("target_uid: %d, appid: %s", target_uid, appid);
1233                 g_dbus_method_invocation_return_value(invocation,
1234                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1235                 return -1;
1236         }
1237
1238         reqkey = __generate_reqkey(appid);
1239         if (reqkey == NULL) {
1240                 ERR("Failed to generate request key");
1241                 g_dbus_method_invocation_return_value(invocation,
1242                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1243                 return -1;
1244         }
1245
1246         if (_push_queue(target_uid, caller_uid, reqkey, req_type, "default",
1247                                 appid, NULL)) {
1248                 ERR("Failed to push request");
1249                 g_dbus_method_invocation_return_value(invocation,
1250                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1251                 free(reqkey);
1252                 return -1;
1253         }
1254
1255         g_dbus_method_invocation_return_value(invocation,
1256                         g_variant_new("(i)", PKGMGR_R_OK));
1257
1258         if (reqkey)
1259                 free(reqkey);
1260
1261         return 0;
1262 }
1263
1264 static int __handle_request_enable_app_splash_screen(uid_t caller_uid,
1265                 GDBusMethodInvocation *invocation, GVariant *parameters)
1266 {
1267         return __update_app_splash_screen(caller_uid, invocation, parameters,
1268                         REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN);
1269 }
1270
1271 static int __handle_request_disable_app_splash_screen(uid_t caller_uid,
1272                 GDBusMethodInvocation *invocation, GVariant *parameters)
1273 {
1274         return __update_app_splash_screen(caller_uid, invocation, parameters,
1275                         REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN);
1276 }
1277
1278 static int __handle_request_set_restriction_mode(uid_t caller_uid,
1279                 GDBusMethodInvocation *invocation, GVariant *parameters)
1280 {
1281         uid_t target_uid = (uid_t)-1;
1282         char *pkgid = NULL;
1283         char *reqkey;
1284         int mode = -1;
1285         char buf[4];
1286
1287         g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1288         if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1289                 g_dbus_method_invocation_return_value(invocation,
1290                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1291                 return -1;
1292         }
1293
1294         reqkey = __generate_reqkey("restriction");
1295         if (reqkey == NULL) {
1296                 g_dbus_method_invocation_return_value(invocation,
1297                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1298                 return -1;
1299         }
1300
1301         snprintf(buf, sizeof(buf), "%d", mode);
1302         if (_push_queue(target_uid, caller_uid, reqkey,
1303                                 REQUEST_TYPE_SET_RESTRICTION_MODE,
1304                                 "default", pkgid, buf)) {
1305                 g_dbus_method_invocation_return_value(invocation,
1306                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1307                 free(reqkey);
1308                 return -1;
1309         }
1310
1311         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1312                                 (gpointer)invocation))
1313                 ERR("reqkey already exists");
1314
1315         return 0;
1316 }
1317
1318 static int __handle_request_unset_restriction_mode(uid_t caller_uid,
1319                 GDBusMethodInvocation *invocation, GVariant *parameters)
1320 {
1321         uid_t target_uid = (uid_t)-1;
1322         char *pkgid = NULL;
1323         char *reqkey;
1324         int mode = -1;
1325         char buf[4];
1326
1327         g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1328         if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1329                 g_dbus_method_invocation_return_value(invocation,
1330                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1331                 return -1;
1332         }
1333
1334         reqkey = __generate_reqkey("restriction");
1335         if (reqkey == NULL) {
1336                 g_dbus_method_invocation_return_value(invocation,
1337                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1338                 return -1;
1339         }
1340
1341         snprintf(buf, sizeof(buf), "%d", mode);
1342         if (_push_queue(target_uid, caller_uid, reqkey,
1343                                 REQUEST_TYPE_UNSET_RESTRICTION_MODE,
1344                                 "default", pkgid, buf)) {
1345                 g_dbus_method_invocation_return_value(invocation,
1346                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1347                 free(reqkey);
1348                 return -1;
1349         }
1350
1351         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1352                                 (gpointer)invocation))
1353                 ERR("reqkey already exists");
1354
1355         return 0;
1356 }
1357
1358 static int __handle_request_get_restriction_mode(uid_t caller_uid,
1359                 GDBusMethodInvocation *invocation, GVariant *parameters)
1360 {
1361         uid_t target_uid = (uid_t)-1;
1362         char *pkgid = NULL;
1363         char *reqkey;
1364
1365         g_variant_get(parameters, "(us)", &target_uid, &pkgid);
1366         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1367                 g_dbus_method_invocation_return_value(invocation,
1368                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1369                 return -1;
1370         }
1371
1372         reqkey = __generate_reqkey("restriction");
1373         if (reqkey == NULL) {
1374                 g_dbus_method_invocation_return_value(invocation,
1375                                 g_variant_new("(ii)", -1, PKGMGR_R_ENOMEM));
1376                 return -1;
1377         }
1378
1379         if (_push_queue(target_uid, caller_uid, reqkey,
1380                                 REQUEST_TYPE_GET_RESTRICTION_MODE,
1381                                 "default", pkgid, NULL)) {
1382                 g_dbus_method_invocation_return_value(invocation,
1383                                 g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM));
1384                 free(reqkey);
1385                 return -1;
1386         }
1387
1388         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1389                                 (gpointer)invocation))
1390                 ERR("reqkey already exists");
1391
1392         return 0;
1393 }
1394
1395 static int __handle_request_set_app_label(uid_t uid,
1396                 GDBusMethodInvocation *invocation, GVariant *parameters)
1397 {
1398         uid_t target_uid = (uid_t)-1;
1399         char *appid = NULL;
1400         char *label = NULL;
1401         char *reqkey;
1402
1403         g_variant_get(parameters, "(uss)", &target_uid, &appid, &label);
1404         if (target_uid == (uid_t)-1 || appid == NULL || label == NULL) {
1405                 g_dbus_method_invocation_return_value(invocation,
1406                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1407                 return -1;
1408         }
1409
1410         reqkey = __generate_reqkey("appid");
1411         if (reqkey == NULL) {
1412                 g_dbus_method_invocation_return_value(invocation,
1413                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1414                 return -1;
1415         }
1416
1417         if (_push_queue(target_uid, uid, reqkey,
1418                                 REQUEST_TYPE_SET_APP_LABEL,
1419                                 "default", appid, label)) {
1420                 g_dbus_method_invocation_return_value(invocation,
1421                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1422                 free(reqkey);
1423                 return -1;
1424         }
1425
1426         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1427                                 (gpointer)invocation))
1428                 ERR("reqkey already exists");
1429
1430         return 0;
1431 }
1432
1433 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
1434 {
1435         GError *err = NULL;
1436         GVariant *result;
1437         uid_t uid;
1438
1439         result = g_dbus_connection_call_sync(connection,
1440                         "org.freedesktop.DBus", "/org/freedesktop/DBus",
1441                         "org.freedesktop.DBus", "GetConnectionUnixUser",
1442                         g_variant_new("(s)", name), NULL,
1443                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1444         if (result == NULL) {
1445                 ERR("failed to get caller uid: %s", err->message);
1446                 g_error_free(err);
1447                 return (uid_t)-1;
1448         }
1449
1450         g_variant_get(result, "(u)", &uid);
1451
1452         return uid;
1453 }
1454
1455 static void __handle_method_call(GDBusConnection *connection,
1456                 const gchar *sender, const gchar *object_path,
1457                 const gchar *interface_name, const gchar *method_name,
1458                 GVariant *parameters, GDBusMethodInvocation *invocation,
1459                 gpointer user_data)
1460 {
1461         int ret;
1462         uid_t uid;
1463
1464         uid = __get_caller_uid(connection,
1465                 g_dbus_method_invocation_get_sender(invocation));
1466         if (uid == (uid_t)-1)
1467                 return;
1468
1469         if (__check_caller_permission(uid, invocation, parameters))
1470                 return;
1471
1472         if (g_strcmp0(method_name, "install") == 0)
1473                 ret = __handle_request_install(uid, invocation, parameters);
1474         else if (g_strcmp0(method_name, "mount_install") == 0)
1475                 ret = __handle_request_mount_install(uid, invocation,
1476                                 parameters);
1477         else if (g_strcmp0(method_name, "reinstall") == 0)
1478                 ret = __handle_request_reinstall(uid, invocation, parameters);
1479         else if (g_strcmp0(method_name, "uninstall") == 0)
1480                 ret = __handle_request_uninstall(uid, invocation, parameters);
1481         else if (g_strcmp0(method_name, "cleardata") == 0)
1482                 ret = __handle_request_cleardata(uid, invocation, parameters);
1483         else if (g_strcmp0(method_name, "move") == 0)
1484                 ret = __handle_request_move(uid, invocation, parameters);
1485         else if (g_strcmp0(method_name, "enable_pkgs") == 0)
1486                 ret = __handle_request_enable_pkgs(uid, invocation, parameters);
1487         else if (g_strcmp0(method_name, "disable_pkgs") == 0)
1488                 ret = __handle_request_disable_pkgs(uid, invocation, parameters);
1489         else if (g_strcmp0(method_name, "getsize") == 0)
1490                 ret = __handle_request_getsize(uid, invocation, parameters);
1491         else if (g_strcmp0(method_name, "getsize_sync") == 0)
1492                 ret = __handle_request_getsize_sync(uid, invocation, parameters);
1493         else if (g_strcmp0(method_name, "clearcache") == 0)
1494                 ret = __handle_request_clearcache(uid, invocation, parameters);
1495         else if (g_strcmp0(method_name, "enable_app") == 0)
1496                 ret = __handle_request_enable_app(uid, invocation, parameters);
1497         else if (g_strcmp0(method_name, "disable_app") == 0)
1498                 ret = __handle_request_disable_app(uid, invocation, parameters);
1499         else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
1500                 ret = __handle_request_enable_global_app_for_uid(uid,
1501                                 invocation, parameters);
1502         else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
1503                 ret = __handle_request_disable_global_app_for_uid(uid,
1504                                 invocation, parameters);
1505         else if (g_strcmp0(method_name, "kill") == 0)
1506                 ret = __handle_request_kill(uid, invocation, parameters);
1507         else if (g_strcmp0(method_name, "check") == 0)
1508                 ret = __handle_request_check(uid, invocation, parameters);
1509         else if (g_strcmp0(method_name, "generate_license_request") == 0)
1510                 ret = __handle_request_generate_license_request(uid, invocation,
1511                                 parameters);
1512         else if (g_strcmp0(method_name, "register_license") == 0)
1513                 ret = __handle_request_register_license(uid, invocation,
1514                                 parameters);
1515         else if (g_strcmp0(method_name, "decrypt_package") == 0)
1516                 ret = __handle_request_decrypt_package(uid, invocation,
1517                                 parameters);
1518         else if (g_strcmp0(method_name, "disable_app_splash_screen") == 0)
1519                 ret = __handle_request_disable_app_splash_screen(uid,
1520                                 invocation, parameters);
1521         else if (g_strcmp0(method_name, "enable_app_splash_screen") == 0)
1522                 ret = __handle_request_enable_app_splash_screen(uid,
1523                                 invocation, parameters);
1524         else if (g_strcmp0(method_name, "set_restriction_mode") == 0)
1525                 ret = __handle_request_set_restriction_mode(uid, invocation,
1526                                 parameters);
1527         else if (g_strcmp0(method_name, "unset_restriction_mode") == 0)
1528                 ret = __handle_request_unset_restriction_mode(uid, invocation,
1529                                 parameters);
1530         else if (g_strcmp0(method_name, "get_restriction_mode") == 0)
1531                 ret = __handle_request_get_restriction_mode(uid, invocation,
1532                                 parameters);
1533         else if (g_strcmp0(method_name, "set_app_label") == 0)
1534                 ret = __handle_request_set_app_label(uid, invocation, parameters);
1535         else
1536                 ret = -1;
1537
1538         if (ret == 0)
1539                 g_idle_add(queue_job, NULL);
1540 }
1541
1542 int _return_value_to_caller(const char *req_key, GVariant *result)
1543 {
1544         GDBusMethodInvocation *invocation;
1545
1546         invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1547                         (gpointer)req_key);
1548         if (invocation == NULL) {
1549                 ERR("no such request id");
1550                 return -1;
1551         }
1552
1553         g_dbus_method_invocation_return_value(invocation, result);
1554         g_hash_table_remove(req_table, (gpointer)req_key);
1555
1556         return 0;
1557 }
1558
1559 static const GDBusInterfaceVTable interface_vtable = {
1560         __handle_method_call,
1561         NULL,
1562         NULL,
1563 };
1564
1565 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1566                 gpointer user_data)
1567 {
1568         GError *err = NULL;
1569
1570         DBG("on bus acquired");
1571
1572         reg_id = g_dbus_connection_register_object(connection,
1573                         PKGMGR_DBUS_OBJECT_PATH,
1574                         instropection_data->interfaces[0],
1575                         &interface_vtable, NULL, NULL, &err);
1576
1577         if (reg_id == 0) {
1578                 ERR("failed to register object: %s", err->message);
1579                 g_error_free(err);
1580         }
1581 }
1582
1583 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1584                 gpointer user_data)
1585 {
1586         DBG("on name acquired: %s", name);
1587 }
1588
1589 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1590                 gpointer user_data)
1591 {
1592         DBG("on name lost: %s", name);
1593 }
1594
1595 int _init_request_handler(void)
1596 {
1597         instropection_data = g_dbus_node_info_new_for_xml(instropection_xml,
1598                         NULL);
1599
1600         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, PKGMGR_DBUS_SERVICE,
1601                         G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1602                         __on_name_acquired, __on_name_lost, NULL, NULL);
1603
1604         req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1605                         free, NULL);
1606         if (req_table == NULL)
1607                 return -1;
1608
1609         return 0;
1610 }
1611
1612 void _fini_request_handler(void)
1613 {
1614         g_hash_table_destroy(req_table);
1615         g_bus_unown_name(owner_id);
1616         g_dbus_node_info_unref(instropection_data);
1617 }