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