Implement app signal related with app disable/enable
[platform/core/appfw/pkgmgr-server.git] / src / request.c
1 #include <sys/types.h>
2 #include <sys/time.h>
3
4 #include <glib.h>
5 #include <gio/gio.h>
6
7 #include "comm_config.h"
8 #include "pm-queue.h"
9 #include "pkgmgr-server.h"
10 #include "package-manager.h"
11 #include "package-manager-debug.h"
12
13 static const char instropection_xml[] =
14         "<node>"
15         "  <interface name='org.tizen.pkgmgr'>"
16         "    <method name='install'>"
17         "      <arg type='u' name='uid' direction='in'/>"
18         "      <arg type='s' name='pkgtype' direction='in'/>"
19         "      <arg type='s' name='pkgpath' direction='in'/>"
20         "      <arg type='as' name='args' direction='in'/>"
21         "      <arg type='i' name='ret' direction='out'/>"
22         "      <arg type='s' name='reqkey' direction='out'/>"
23         "    </method>"
24         "    <method name='reinstall'>"
25         "      <arg type='u' name='uid' direction='in'/>"
26         "      <arg type='s' name='pkgtype' direction='in'/>"
27         "      <arg type='s' name='pkgid' direction='in'/>"
28         "      <arg type='i' name='ret' direction='out'/>"
29         "      <arg type='s' name='reqkey' direction='out'/>"
30         "    </method>"
31         "    <method name='uninstall'>"
32         "      <arg type='u' name='uid' direction='in'/>"
33         "      <arg type='s' name='pkgtype' direction='in'/>"
34         "      <arg type='s' name='pkgid' direction='in'/>"
35         "      <arg type='i' name='ret' direction='out'/>"
36         "      <arg type='s' name='reqkey' direction='out'/>"
37         "    </method>"
38         "    <method name='move'>"
39         "      <arg type='u' name='uid' direction='in'/>"
40         "      <arg type='s' name='pkgtype' direction='in'/>"
41         "      <arg type='s' name='pkgid' direction='in'/>"
42         "      <arg type='i' name='ret' direction='out'/>"
43         "      <arg type='s' name='reqkey' direction='out'/>"
44         "    </method>"
45         "    <method name='enable_pkg'>"
46         "      <arg type='u' name='uid' direction='in'/>"
47         "      <arg type='s' name='pkgid' direction='in'/>"
48         "      <arg type='i' name='ret' direction='out'/>"
49         "    </method>"
50         "    <method name='disable_pkg'>"
51         "      <arg type='u' name='uid' direction='in'/>"
52         "      <arg type='s' name='pkgid' direction='in'/>"
53         "      <arg type='i' name='ret' direction='out'/>"
54         "    </method>"
55         "    <method name='enable_app'>"
56         "      <arg type='u' name='uid' direction='in'/>"
57         "      <arg type='s' name='appid' direction='in'/>"
58         "      <arg type='i' name='ret' direction='out'/>"
59         "      <arg type='s' name='reqkey' direction='out'/>"
60         "    </method>"
61         "    <method name='disable_app'>"
62         "      <arg type='u' name='uid' direction='in'/>"
63         "      <arg type='s' name='appid' direction='in'/>"
64         "      <arg type='i' name='ret' direction='out'/>"
65         "      <arg type='s' name='reqkey' direction='out'/>"
66         "    </method>"
67         "    <method name='enable_global_app_for_uid'>"
68         "      <arg type='u' name='uid' direction='in'/>"
69         "      <arg type='s' name='appid' direction='in'/>"
70         "      <arg type='i' name='ret' direction='out'/>"
71         "      <arg type='s' name='reqkey' direction='out'/>"
72         "    </method>"
73         "    <method name='disable_global_app_for_uid'>"
74         "      <arg type='u' name='uid' direction='in'/>"
75         "      <arg type='s' name='appid' direction='in'/>"
76         "      <arg type='i' name='ret' direction='out'/>"
77         "      <arg type='s' name='reqkey' direction='out'/>"
78         "    </method>"
79         "    <method name='getsize'>"
80         "      <arg type='u' name='uid' direction='in'/>"
81         "      <arg type='s' name='pkgid' direction='in'/>"
82         "      <arg type='i' name='get_type' direction='in'/>"
83         "      <arg type='i' name='ret' direction='out'/>"
84         "      <arg type='s' name='reqkey' direction='out'/>"
85         "    </method>"
86         "    <method name='cleardata'>"
87         "      <arg type='u' name='uid' direction='in'/>"
88         "      <arg type='s' name='pkgtype' direction='in'/>"
89         "      <arg type='s' name='pkgid' direction='in'/>"
90         "      <arg type='i' name='ret' direction='out'/>"
91         "    </method>"
92         "    <method name='clearcache'>"
93         "      <arg type='u' name='uid' direction='in'/>"
94         "      <arg type='s' name='pkgid' direction='in'/>"
95         "      <arg type='i' name='ret' direction='out'/>"
96         "    </method>"
97         "    <method name='kill'>"
98         "      <arg type='u' name='uid' direction='in'/>"
99         "      <arg type='s' name='pkgid' direction='in'/>"
100         "      <arg type='i' name='ret' direction='out'/>"
101         "    </method>"
102         "    <method name='check'>"
103         "      <arg type='u' name='uid' direction='in'/>"
104         "      <arg type='s' name='pkgid' direction='in'/>"
105         "      <arg type='i' name='ret' direction='out'/>"
106         "    </method>"
107         "    <method name='generate_license_request'>"
108         "      <arg type='s' name='resp_data' direction='in'/>"
109         "      <arg type='i' name='ret' direction='out'/>"
110         "      <arg type='s' name='req_data' direction='out'/>"
111         "      <arg type='s' name='license_url' direction='out'/>"
112         "    </method>"
113         "    <method name='register_license'>"
114         "      <arg type='s' name='resp_data' direction='in'/>"
115         "      <arg type='i' name='ret' direction='out'/>"
116         "    </method>"
117         "    <method name='decrypt_package'>"
118         "      <arg type='s' name='drm_file_path' direction='in'/>"
119         "      <arg type='s' name='decrypted_file_path' direction='in'/>"
120         "      <arg type='i' name='ret' direction='out'/>"
121         "    </method>"
122         "    <method name='add_blacklist'>"
123         "      <arg type='u' name='uid' direction='in'/>"
124         "      <arg type='s' name='pkgid' direction='in'/>"
125         "      <arg type='i' name='ret' direction='out'/>"
126         "    </method>"
127         "    <method name='remove_blacklist'>"
128         "      <arg type='u' name='uid' direction='in'/>"
129         "      <arg type='s' name='pkgid' direction='in'/>"
130         "      <arg type='i' name='ret' direction='out'/>"
131         "    </method>"
132         "    <method name='check_blacklist'>"
133         "      <arg type='u' name='uid' direction='in'/>"
134         "      <arg type='s' name='pkgid' direction='in'/>"
135         "      <arg type='i' name='result' direction='out'/>"
136         "      <arg type='i' name='ret' direction='out'/>"
137         "    </method>"
138         "  </interface>"
139         "</node>";
140 static GDBusNodeInfo *instropection_data;
141 static guint reg_id;
142 static guint owner_id;
143 static GHashTable *req_table;
144
145 static char *__generate_reqkey(const char *pkgid)
146 {
147         struct timeval tv;
148         long curtime;
149         char timestr[MAX_PKG_ARGS_LEN];
150         char *str_req_key;
151         int size;
152
153         gettimeofday(&tv, NULL);
154         curtime = tv.tv_sec * 1000000 + tv.tv_usec;
155         snprintf(timestr, sizeof(timestr), "%ld", curtime);
156
157         size = strlen(pkgid) + strlen(timestr) + 2;
158         str_req_key = (char *)calloc(size, sizeof(char));
159         if (str_req_key == NULL) {
160                 DBG("calloc failed");
161                 return NULL;
162         }
163         snprintf(str_req_key, size, "%s_%s", pkgid, timestr);
164
165         return str_req_key;
166 }
167
168 static int __handle_request_install(uid_t uid,
169                 GDBusMethodInvocation *invocation, GVariant *parameters)
170 {
171         uid_t target_uid = (uid_t)-1;
172         char *pkgtype = NULL;
173         char *pkgpath = NULL;
174         char *args = NULL;
175         char *reqkey = NULL;
176         gchar **tmp_args = NULL;
177         gsize args_count;
178         int ret = -1;
179         GVariant *value;
180         gchar *str;
181         int i = 0;
182         int len = 0;
183
184         g_variant_get(parameters, "(u&s&s@as)", &target_uid, &pkgtype, &pkgpath, &value);
185         tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
186
187         for (i = 0; i < args_count; i++)
188                 len = len + strlen(tmp_args[i]) + 1;
189
190         args = (char *)calloc(len, sizeof(char));
191         if (args == NULL) {
192                 ERR("calloc failed");
193                 ret =  -1;
194                 goto catch;
195         }
196
197         for (i = 0; i < args_count; i++) {
198                 strncat(args, tmp_args[i], strlen(tmp_args[i]));
199                 strncat(args, " ", strlen(" "));
200         }
201
202         if (target_uid == (uid_t)-1 || pkgtype == NULL) {
203                 g_dbus_method_invocation_return_value(invocation,
204                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
205                 ret = -1;
206                 goto catch;
207         }
208
209         if (pkgpath == NULL) {
210                 g_dbus_method_invocation_return_value(invocation,
211                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
212                 ret = -1;
213                 goto catch;
214         }
215
216         reqkey = __generate_reqkey(pkgpath);
217         if (reqkey == NULL) {
218                 ret = -1;
219                 goto catch;
220         }
221
222         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_INSTALL, pkgtype,
223                                 pkgpath, args)) {
224                 g_dbus_method_invocation_return_value(invocation,
225                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
226                 ret = -1;
227                 goto catch;
228         }
229
230         g_dbus_method_invocation_return_value(invocation,
231                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
232
233         ret = 0;
234
235 catch:
236         if (reqkey)
237                 free(reqkey);
238
239         if (args)
240                 free(args);
241
242         return ret;
243 }
244
245 static int __handle_request_reinstall(uid_t uid,
246                 GDBusMethodInvocation *invocation, GVariant *parameters)
247 {
248         uid_t target_uid = (uid_t)-1;
249         char *pkgtype = NULL;
250         char *pkgid = NULL;
251         char *reqkey;
252
253         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
254         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
255                 g_dbus_method_invocation_return_value(invocation,
256                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
257                 return -1;
258         }
259
260         reqkey = __generate_reqkey(pkgid);
261         if (reqkey == NULL)
262                 return -1;
263         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_REINSTALL, pkgtype,
264                                 pkgid, "")) {
265                 g_dbus_method_invocation_return_value(invocation,
266                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
267                 free(reqkey);
268                 return -1;
269         }
270
271         g_dbus_method_invocation_return_value(invocation,
272                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
273         free(reqkey);
274
275         return 0;
276 }
277
278 static int __handle_request_uninstall(uid_t uid,
279                 GDBusMethodInvocation *invocation, GVariant *parameters)
280 {
281         uid_t target_uid = (uid_t)-1;
282         char *pkgtype = NULL;
283         char *pkgid = NULL;
284         char *reqkey;
285
286         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
287         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
288                 g_dbus_method_invocation_return_value(invocation,
289                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
290                 return -1;
291         }
292
293         reqkey = __generate_reqkey(pkgid);
294         if (reqkey == NULL)
295                 return -1;
296         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_UNINSTALL, pkgtype,
297                                 pkgid, "")) {
298                 g_dbus_method_invocation_return_value(invocation,
299                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
300                 free(reqkey);
301                 return -1;
302         }
303
304         g_dbus_method_invocation_return_value(invocation,
305                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
306         free(reqkey);
307
308         return 0;
309 }
310
311 static int __handle_request_move(uid_t uid,
312                 GDBusMethodInvocation *invocation, GVariant *parameters)
313 {
314         uid_t target_uid = (uid_t)-1;
315         char *pkgtype = NULL;
316         char *pkgid = NULL;
317         char *reqkey;
318
319         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
320         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
321                 g_dbus_method_invocation_return_value(invocation,
322                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
323                 return -1;
324         }
325
326         reqkey = __generate_reqkey(pkgid);
327         if (reqkey == NULL)
328                 return -1;
329         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_MOVE, pkgtype,
330                                 pkgid, "")) {
331                 g_dbus_method_invocation_return_value(invocation,
332                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
333                 free(reqkey);
334                 return -1;
335         }
336
337         g_dbus_method_invocation_return_value(invocation,
338                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
339         free(reqkey);
340
341         return 0;
342 }
343
344 static int __handle_request_enable_pkg(uid_t uid,
345                 GDBusMethodInvocation *invocation, GVariant *parameters)
346 {
347         uid_t target_uid = (uid_t)-1;
348         char *pkgid = NULL;
349
350         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
351         if (target_uid == (uid_t)-1 || pkgid == NULL) {
352                 g_dbus_method_invocation_return_value(invocation,
353                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
354                 return -1;
355         }
356
357         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_ENABLE_PKG, "pkg",
358                                 pkgid, "")) {
359                 g_dbus_method_invocation_return_value(invocation,
360                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
361                 return -1;
362         }
363
364         g_dbus_method_invocation_return_value(invocation,
365                         g_variant_new("(i)", PKGMGR_R_OK));
366
367         return 0;
368 }
369
370 static int __handle_request_disable_pkg(uid_t uid,
371                 GDBusMethodInvocation *invocation, GVariant *parameters)
372 {
373         uid_t target_uid = (uid_t)-1;
374         char *pkgid = NULL;
375
376         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
377         if (target_uid == (uid_t)-1 || pkgid == NULL) {
378                 g_dbus_method_invocation_return_value(invocation,
379                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
380                 return -1;
381         }
382
383         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_DISABLE_PKG, "pkg",
384                                 pkgid, "")) {
385                 g_dbus_method_invocation_return_value(invocation,
386                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
387                 return -1;
388         }
389
390         g_dbus_method_invocation_return_value(invocation,
391                         g_variant_new("(i)", PKGMGR_R_OK));
392
393         return 0;
394 }
395
396 static int __handle_request_enable_app(uid_t uid,
397                 GDBusMethodInvocation *invocation, GVariant *parameters)
398 {
399         uid_t target_uid = (uid_t)-1;
400         char *appid = NULL;
401         char *reqkey = NULL;
402         int ret = -1;
403
404         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
405         if (target_uid == (uid_t)-1 || appid == NULL) {
406                 g_dbus_method_invocation_return_value(invocation,
407                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
408                 return -1;
409         }
410
411         reqkey = __generate_reqkey(appid);
412         if (reqkey == NULL) {
413                 ret = -1;
414                 goto catch;
415         }
416
417         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_ENABLE_APP, "app",
418                                 appid, "")) {
419                 g_dbus_method_invocation_return_value(invocation,
420                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
421                 ret = -1;
422                 goto catch;
423         }
424
425         g_dbus_method_invocation_return_value(invocation,
426                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
427
428         ret = 0;
429
430 catch:
431         if(reqkey)
432                 free(reqkey);
433
434         return ret;
435 }
436
437 static int __handle_request_disable_app(uid_t uid,
438                 GDBusMethodInvocation *invocation, GVariant *parameters)
439 {
440         uid_t target_uid = (uid_t)-1;
441         char *appid = NULL;
442         char *reqkey = NULL;
443         int ret = -1;
444
445         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
446         if (target_uid == (uid_t)-1 || appid == NULL) {
447                 g_dbus_method_invocation_return_value(invocation,
448                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
449                 return -1;
450         }
451
452         reqkey = __generate_reqkey(appid);
453         if (reqkey == NULL) {
454                 ret = -1;
455                 goto catch;
456         }
457
458         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_DISABLE_APP, "app",
459                                 appid, "")) {
460                 g_dbus_method_invocation_return_value(invocation,
461                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
462                 ret = -1;
463                 goto catch;
464         }
465
466         g_dbus_method_invocation_return_value(invocation,
467                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
468
469         ret = 0;
470
471 catch:
472         if (reqkey)
473                 free(reqkey);
474
475         return ret;
476 }
477
478 static int __handle_request_enable_global_app_for_uid(uid_t uid,
479                 GDBusMethodInvocation *invocation, GVariant *parameters)
480 {
481         uid_t target_uid = (uid_t)-1;
482         char *appid = NULL;
483         char *reqkey = NULL;
484         int ret = -1;
485
486         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
487         if (target_uid == (uid_t)-1 || appid == NULL) {
488                 g_dbus_method_invocation_return_value(invocation,
489                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
490                 return -1;
491         }
492
493         reqkey = __generate_reqkey(appid);
494         if (reqkey == NULL) {
495                 ret = -1;
496                 goto catch;
497         }
498
499         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID, "app",
500                                 appid, "")) {
501                 g_dbus_method_invocation_return_value(invocation,
502                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
503                 ret = -1;
504                 goto catch;
505         }
506
507         g_dbus_method_invocation_return_value(invocation,
508                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
509
510         ret = 0;
511
512 catch:
513         if (reqkey)
514                 free(reqkey);
515
516         return ret;
517 }
518
519 static int __handle_request_disable_global_app_for_uid(uid_t uid,
520                 GDBusMethodInvocation *invocation, GVariant *parameters)
521 {
522         uid_t target_uid = (uid_t)-1;
523         char *appid = NULL;
524         char *reqkey = NULL;
525         int ret = -1;
526
527         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
528         if (target_uid == (uid_t)-1 || appid == NULL) {
529                 g_dbus_method_invocation_return_value(invocation,
530                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
531                 return -1;
532         }
533
534         reqkey = __generate_reqkey(appid);
535         if (reqkey == NULL) {
536                 ret = -1;
537                 goto catch;
538         }
539
540         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID, "app",
541                                 appid, "")) {
542                 g_dbus_method_invocation_return_value(invocation,
543                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
544                 ret = -1;
545                 goto catch;
546         }
547
548         g_dbus_method_invocation_return_value(invocation,
549                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
550
551         ret = 0;
552
553 catch:
554         if (reqkey)
555                 free(reqkey);
556
557         return ret;
558 }
559
560 static int __handle_request_getsize(uid_t uid,
561                 GDBusMethodInvocation *invocation, GVariant *parameters)
562 {
563         uid_t target_uid = (uid_t)-1;
564         char *pkgid = NULL;
565         int get_type = -1;
566         char *reqkey;
567         char buf[4];
568
569         g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
570         if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
571                 g_dbus_method_invocation_return_value(invocation,
572                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
573                 return -1;
574         }
575
576         reqkey = __generate_reqkey(pkgid);
577         if (reqkey == NULL)
578                 return -1;
579
580         snprintf(buf, sizeof(buf), "%d", get_type);
581         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_GETSIZE, "getsize",
582                                 pkgid, buf)) {
583                 g_dbus_method_invocation_return_value(invocation,
584                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
585                 free(reqkey);
586                 return -1;
587         }
588
589         g_dbus_method_invocation_return_value(invocation,
590                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
591         free(reqkey);
592
593         return 0;
594 }
595
596 static int __handle_request_cleardata(uid_t uid,
597                 GDBusMethodInvocation *invocation, GVariant *parameters)
598 {
599         uid_t target_uid = (uid_t)-1;
600         char *pkgtype = NULL;
601         char *pkgid = NULL;
602
603         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
604         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
605                 g_dbus_method_invocation_return_value(invocation,
606                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
607                 return -1;
608         }
609
610         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CLEARDATA, pkgtype,
611                                 pkgid, "")) {
612                 g_dbus_method_invocation_return_value(invocation,
613                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
614                 return -1;
615         }
616
617         g_dbus_method_invocation_return_value(invocation,
618                         g_variant_new("(i)", PKGMGR_R_OK));
619
620         return 0;
621 }
622
623 static int __handle_request_clearcache(uid_t uid,
624                 GDBusMethodInvocation *invocation, GVariant *parameters)
625 {
626         uid_t target_uid = (uid_t)-1;
627         char *pkgid = NULL;
628
629         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
630         if (target_uid == (uid_t)-1 || pkgid == NULL) {
631                 g_dbus_method_invocation_return_value(invocation,
632                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
633                 return -1;
634         }
635
636         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CLEARCACHE,
637                                 "clearcache", pkgid, "")) {
638                 g_dbus_method_invocation_return_value(invocation,
639                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
640                 return -1;
641         }
642
643         g_dbus_method_invocation_return_value(invocation,
644                         g_variant_new("(i)", PKGMGR_R_OK));
645
646         return 0;
647 }
648
649 static int __handle_request_kill(uid_t uid,
650                 GDBusMethodInvocation *invocation, GVariant *parameters)
651 {
652         uid_t target_uid = (uid_t)-1;
653         char *pkgid = NULL;
654
655         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
656         if (target_uid == (uid_t)-1 || pkgid == NULL) {
657                 g_dbus_method_invocation_return_value(invocation,
658                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
659                 return -1;
660         }
661
662         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_KILL, "pkg",
663                                 pkgid, "")) {
664                 g_dbus_method_invocation_return_value(invocation,
665                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
666                 return -1;
667         }
668
669         g_dbus_method_invocation_return_value(invocation,
670                         g_variant_new("(i)", PKGMGR_R_OK));
671
672         return 0;
673 }
674
675 static int __handle_request_check(uid_t uid,
676                 GDBusMethodInvocation *invocation, GVariant *parameters)
677 {
678         uid_t target_uid = (uid_t)-1;
679         char *pkgid = NULL;
680
681         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
682         if (target_uid == (uid_t)-1 || pkgid == NULL) {
683                 g_dbus_method_invocation_return_value(invocation,
684                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
685                 return -1;
686         }
687
688         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CHECK, "pkg",
689                                 pkgid, "")) {
690                 g_dbus_method_invocation_return_value(invocation,
691                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
692                 return -1;
693         }
694
695         g_dbus_method_invocation_return_value(invocation,
696                         g_variant_new("(i)", PKGMGR_R_OK));
697
698         return 0;
699 }
700
701 static int __handle_request_generate_license_request(uid_t uid,
702                 GDBusMethodInvocation *invocation, GVariant *parameters)
703 {
704         char *reqkey;
705         char *resp_data = NULL;
706
707         g_variant_get(parameters, "(&s)", &resp_data);
708         if (resp_data == NULL) {
709                 g_dbus_method_invocation_return_value(invocation,
710                                 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
711                 return -1;
712         }
713
714         reqkey = __generate_reqkey("drm");
715         if (reqkey == NULL) {
716                 g_dbus_method_invocation_return_value(invocation,
717                                 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
718                                         ""));
719                 return -1;
720         }
721
722         if (_pm_queue_push(uid, reqkey,
723                                 PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
724                                 "pkg", "", resp_data)) {
725                 g_dbus_method_invocation_return_value(invocation,
726                                 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
727                                         ""));
728                 free(reqkey);
729                 return -1;
730         }
731
732         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
733                                 (gpointer)invocation))
734                 ERR("reqkey already exists");
735
736         return 0;
737 }
738
739 static int __handle_request_register_license(uid_t uid,
740                 GDBusMethodInvocation *invocation, GVariant *parameters)
741 {
742         char *reqkey;
743         char *resp_data = NULL;
744
745         g_variant_get(parameters, "(&s)", &resp_data);
746         if (resp_data == NULL) {
747                 g_dbus_method_invocation_return_value(invocation,
748                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
749                 return -1;
750         }
751
752         reqkey = __generate_reqkey("drm");
753         if (reqkey == NULL) {
754                 g_dbus_method_invocation_return_value(invocation,
755                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
756                 return -1;
757         }
758
759         if (_pm_queue_push(uid, reqkey, PKGMGR_REQUEST_TYPE_REGISTER_LICENSE,
760                                 "pkg", "", resp_data)) {
761                 g_dbus_method_invocation_return_value(invocation,
762                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
763                 free(reqkey);
764                 return -1;
765         }
766
767         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
768                                 (gpointer)invocation))
769                 ERR("reqkey already exists");
770
771         return 0;
772 }
773
774 static int __handle_request_decrypt_package(uid_t uid,
775                 GDBusMethodInvocation *invocation, GVariant *parameters)
776 {
777         char *reqkey;
778         char *drm_file_path = NULL;
779         char *decrypted_file_path = NULL;
780
781         g_variant_get(parameters, "(&s&s)", &drm_file_path,
782                         &decrypted_file_path);
783         if (drm_file_path == NULL || decrypted_file_path == NULL) {
784                 g_dbus_method_invocation_return_value(invocation,
785                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
786                 return -1;
787         }
788
789         reqkey = __generate_reqkey("drm");
790         if (reqkey == NULL) {
791                 g_dbus_method_invocation_return_value(invocation,
792                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
793                 return -1;
794         }
795
796         if (_pm_queue_push(uid, reqkey, PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE,
797                                 "pkg", drm_file_path, decrypted_file_path)) {
798                 g_dbus_method_invocation_return_value(invocation,
799                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
800                 free(reqkey);
801                 return -1;
802         }
803
804         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
805                                 (gpointer)invocation))
806                 ERR("reqkey already exists");
807
808         return 0;
809 }
810
811 static int __handle_request_add_blacklist(uid_t uid,
812                 GDBusMethodInvocation *invocation, GVariant *parameters)
813 {
814         uid_t target_uid = (uid_t)-1;
815         char *reqkey;
816         char *pkgid = NULL;
817
818         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
819         if (target_uid == (uid_t)-1 || pkgid == NULL) {
820                 g_dbus_method_invocation_return_value(invocation,
821                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
822                 return -1;
823         }
824
825         reqkey = __generate_reqkey("blacklist");
826         if (reqkey == NULL) {
827                 g_dbus_method_invocation_return_value(invocation,
828                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
829                 return -1;
830         }
831
832         if (_pm_queue_push(target_uid, reqkey,
833                                 PKGMGR_REQUEST_TYPE_ADD_BLACKLIST,
834                                 "pkg", pkgid, "")) {
835                 g_dbus_method_invocation_return_value(invocation,
836                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
837                 return -1;
838         }
839
840         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
841                                 (gpointer)invocation))
842                 ERR("reqkey already exists");
843
844         return 0;
845 }
846
847 static int __handle_request_remove_blacklist(uid_t uid,
848                 GDBusMethodInvocation *invocation, GVariant *parameters)
849 {
850         uid_t target_uid = (uid_t)-1;
851         char *reqkey;
852         char *pkgid = NULL;
853
854         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
855         if (target_uid == (uid_t)-1 || pkgid == NULL) {
856                 g_dbus_method_invocation_return_value(invocation,
857                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
858                 return -1;
859         }
860
861         reqkey = __generate_reqkey("blacklist");
862         if (reqkey == NULL) {
863                 g_dbus_method_invocation_return_value(invocation,
864                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
865                 return -1;
866         }
867
868         if (_pm_queue_push(target_uid, reqkey,
869                                 PKGMGR_REQUEST_TYPE_REMOVE_BLACKLIST,
870                                 "pkg", pkgid, "")) {
871                 g_dbus_method_invocation_return_value(invocation,
872                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
873                 return -1;
874         }
875
876         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
877                                 (gpointer)invocation))
878                 ERR("reqkey already exists");
879
880         return 0;
881 }
882
883 static int __handle_request_check_blacklist(uid_t uid,
884                 GDBusMethodInvocation *invocation, GVariant *parameters)
885 {
886         uid_t target_uid = (uid_t)-1;
887         char *reqkey;
888         char *pkgid = NULL;
889
890         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
891         if (target_uid == (uid_t)-1 || pkgid == NULL) {
892                 g_dbus_method_invocation_return_value(invocation,
893                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
894                 return -1;
895         }
896
897         reqkey = __generate_reqkey("blacklist");
898         if (reqkey == NULL) {
899                 g_dbus_method_invocation_return_value(invocation,
900                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
901                 return -1;
902         }
903
904         if (_pm_queue_push(target_uid, reqkey,
905                                 PKGMGR_REQUEST_TYPE_CHECK_BLACKLIST,
906                                 "pkg", pkgid, "")) {
907                 g_dbus_method_invocation_return_value(invocation,
908                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
909                 return -1;
910         }
911
912         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
913                                 (gpointer)invocation))
914                 ERR("reqkey already exists");
915
916         return 0;
917 }
918
919 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
920 {
921         GError *err = NULL;
922         GVariant *result;
923         uid_t uid;
924
925         result = g_dbus_connection_call_sync(connection,
926                         "org.freedesktop.DBus", "/org/freedesktop/DBus",
927                         "org.freedesktop.DBus", "GetConnectionUnixUser",
928                         g_variant_new("(s)", name), NULL,
929                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
930         if (result == NULL) {
931                 ERR("failed to get caller uid: %s", err->message);
932                 g_error_free(err);
933                 return (uid_t)-1;
934         }
935
936         g_variant_get(result, "(u)", &uid);
937
938         return uid;
939 }
940
941 static void __handle_method_call(GDBusConnection *connection,
942                 const gchar *sender, const gchar *object_path,
943                 const gchar *interface_name, const gchar *method_name,
944                 GVariant *parameters, GDBusMethodInvocation *invocation,
945                 gpointer user_data)
946 {
947         int ret;
948         uid_t uid;
949
950         uid = __get_caller_uid(connection,
951                 g_dbus_method_invocation_get_sender(invocation));
952         if (uid == (uid_t)-1)
953                 return;
954
955         if (g_strcmp0(method_name, "install") == 0)
956                 ret = __handle_request_install(uid, invocation, parameters);
957         else if (g_strcmp0(method_name, "reinstall") == 0)
958                 ret = __handle_request_reinstall(uid, invocation, parameters);
959         else if (g_strcmp0(method_name, "uninstall") == 0)
960                 ret = __handle_request_uninstall(uid, invocation, parameters);
961         else if (g_strcmp0(method_name, "cleardata") == 0)
962                 ret = __handle_request_cleardata(uid, invocation, parameters);
963         else if (g_strcmp0(method_name, "move") == 0)
964                 ret = __handle_request_move(uid, invocation, parameters);
965         else if (g_strcmp0(method_name, "enable") == 0)
966                 ret = __handle_request_enable_pkg(uid, invocation, parameters);
967         else if (g_strcmp0(method_name, "disable") == 0)
968                 ret = __handle_request_disable_pkg(uid, invocation, parameters);
969         else if (g_strcmp0(method_name, "getsize") == 0)
970                 ret = __handle_request_getsize(uid, invocation, parameters);
971         else if (g_strcmp0(method_name, "clearcache") == 0)
972                 ret = __handle_request_clearcache(uid, invocation, parameters);
973         else if (g_strcmp0(method_name, "enable_app") == 0)
974                 ret = __handle_request_enable_app(uid, invocation, parameters);
975         else if (g_strcmp0(method_name, "disable_app") == 0)
976                 ret = __handle_request_disable_app(uid, invocation, parameters);
977         else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
978                 ret = __handle_request_enable_global_app_for_uid(uid, invocation, parameters);
979         else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
980                 ret = __handle_request_disable_global_app_for_uid(uid, invocation, parameters);
981         else if (g_strcmp0(method_name, "kill") == 0)
982                 ret = __handle_request_kill(uid, invocation, parameters);
983         else if (g_strcmp0(method_name, "check") == 0)
984                 ret = __handle_request_check(uid, invocation, parameters);
985         else if (g_strcmp0(method_name, "generate_license_request") == 0)
986                 ret = __handle_request_generate_license_request(uid, invocation,
987                                 parameters);
988         else if (g_strcmp0(method_name, "register_license") == 0)
989                 ret = __handle_request_register_license(uid, invocation,
990                                 parameters);
991         else if (g_strcmp0(method_name, "decrypt_package") == 0)
992                 ret = __handle_request_decrypt_package(uid, invocation,
993                                 parameters);
994         else if (g_strcmp0(method_name, "add_blacklist") == 0)
995                 ret = __handle_request_add_blacklist(uid, invocation,
996                                 parameters);
997         else if (g_strcmp0(method_name, "remove_blacklist") == 0)
998                 ret = __handle_request_remove_blacklist(uid, invocation,
999                                 parameters);
1000         else if (g_strcmp0(method_name, "check_blacklist") == 0)
1001                 ret = __handle_request_check_blacklist(uid, invocation,
1002                                 parameters);
1003         else
1004                 ret = -1;
1005
1006         if (ret == 0)
1007                 g_idle_add(queue_job, NULL);
1008 }
1009
1010 int __return_value_to_caller(const char *req_key, GVariant *result)
1011 {
1012         GDBusMethodInvocation *invocation;
1013
1014         invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1015                         (gpointer)req_key);
1016         if (invocation == NULL) {
1017                 ERR("no such request id");
1018                 return -1;
1019         }
1020
1021         g_dbus_method_invocation_return_value(invocation, result);
1022         g_hash_table_remove(req_table, (gpointer)req_key);
1023
1024         return 0;
1025 }
1026
1027 static const GDBusInterfaceVTable interface_vtable =
1028 {
1029         __handle_method_call,
1030         NULL,
1031         NULL,
1032 };
1033
1034 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1035                 gpointer user_data)
1036 {
1037         GError *err = NULL;
1038
1039         DBG("on bus acquired");
1040
1041         reg_id = g_dbus_connection_register_object(connection,
1042                         COMM_PKGMGR_DBUS_OBJECT_PATH,
1043                         instropection_data->interfaces[0],
1044                         &interface_vtable, NULL, NULL, &err);
1045
1046         if (reg_id == 0) {
1047                 ERR("failed to register object: %s", err->message);
1048                 g_error_free(err);
1049         }
1050 }
1051
1052 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1053                 gpointer user_data)
1054 {
1055         DBG("on name acquired: %s", name);
1056 }
1057
1058 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1059                 gpointer user_data)
1060 {
1061         DBG("on name lost: %s", name);
1062 }
1063
1064 int __init_request_handler(void)
1065 {
1066         instropection_data = g_dbus_node_info_new_for_xml(instropection_xml, NULL);
1067
1068         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, COMM_PKGMGR_DBUS_SERVICE,
1069                         G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1070                         __on_name_acquired, __on_name_lost, NULL, NULL);
1071
1072         req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1073                         free, NULL);
1074         if (req_table == NULL)
1075                 return -1;
1076
1077         return 0;
1078 }
1079
1080 void __fini_request_handler(void)
1081 {
1082         g_hash_table_destroy(req_table);
1083         g_bus_unown_name(owner_id);
1084         g_dbus_node_info_unref(instropection_data);
1085 }