ca27a2eda0e3bf88044db851451506c4740be9c1
[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         "    </method>"
60         "    <method name='disable_app'>"
61         "      <arg type='u' name='uid' direction='in'/>"
62         "      <arg type='s' name='appid' direction='in'/>"
63         "      <arg type='i' name='ret' direction='out'/>"
64         "    </method>"
65         "    <method name='enable_global_app'>"
66         "      <arg type='u' name='uid' direction='in'/>"
67         "      <arg type='s' name='appid' direction='in'/>"
68         "      <arg type='i' name='ret' direction='out'/>"
69         "    </method>"
70         "    <method name='disable_global_app'>"
71         "      <arg type='u' name='uid' direction='in'/>"
72         "      <arg type='s' name='appid' direction='in'/>"
73         "      <arg type='i' name='ret' direction='out'/>"
74         "    </method>"
75         "    <method name='getsize'>"
76         "      <arg type='u' name='uid' direction='in'/>"
77         "      <arg type='s' name='pkgid' direction='in'/>"
78         "      <arg type='i' name='get_type' direction='in'/>"
79         "      <arg type='i' name='ret' direction='out'/>"
80         "      <arg type='s' name='reqkey' direction='out'/>"
81         "    </method>"
82         "    <method name='cleardata'>"
83         "      <arg type='u' name='uid' direction='in'/>"
84         "      <arg type='s' name='pkgtype' direction='in'/>"
85         "      <arg type='s' name='pkgid' direction='in'/>"
86         "      <arg type='i' name='ret' direction='out'/>"
87         "    </method>"
88         "    <method name='clearcache'>"
89         "      <arg type='u' name='uid' direction='in'/>"
90         "      <arg type='s' name='pkgid' direction='in'/>"
91         "      <arg type='i' name='ret' direction='out'/>"
92         "    </method>"
93         "    <method name='kill'>"
94         "      <arg type='u' name='uid' direction='in'/>"
95         "      <arg type='s' name='pkgid' direction='in'/>"
96         "      <arg type='i' name='ret' direction='out'/>"
97         "    </method>"
98         "    <method name='check'>"
99         "      <arg type='u' name='uid' direction='in'/>"
100         "      <arg type='s' name='pkgid' direction='in'/>"
101         "      <arg type='i' name='ret' direction='out'/>"
102         "    </method>"
103         "    <method name='generate_license_request'>"
104         "      <arg type='s' name='resp_data' direction='in'/>"
105         "      <arg type='i' name='ret' direction='out'/>"
106         "      <arg type='s' name='req_data' direction='out'/>"
107         "      <arg type='s' name='license_url' direction='out'/>"
108         "    </method>"
109         "    <method name='register_license'>"
110         "      <arg type='s' name='resp_data' direction='in'/>"
111         "      <arg type='i' name='ret' direction='out'/>"
112         "    </method>"
113         "    <method name='decrypt_package'>"
114         "      <arg type='s' name='drm_file_path' direction='in'/>"
115         "      <arg type='s' name='decrypted_file_path' direction='in'/>"
116         "      <arg type='i' name='ret' direction='out'/>"
117         "    </method>"
118         "  </interface>"
119         "</node>";
120 static GDBusNodeInfo *instropection_data;
121 static guint reg_id;
122 static guint owner_id;
123 static GHashTable *req_table;
124
125 static char *__generate_reqkey(const char *pkgid)
126 {
127         struct timeval tv;
128         long curtime;
129         char timestr[MAX_PKG_ARGS_LEN];
130         char *str_req_key;
131         int size;
132
133         gettimeofday(&tv, NULL);
134         curtime = tv.tv_sec * 1000000 + tv.tv_usec;
135         snprintf(timestr, sizeof(timestr), "%ld", curtime);
136
137         size = strlen(pkgid) + strlen(timestr) + 2;
138         str_req_key = (char *)calloc(size, sizeof(char));
139         if (str_req_key == NULL) {
140                 DBG("calloc failed");
141                 return NULL;
142         }
143         snprintf(str_req_key, size, "%s_%s", pkgid, timestr);
144
145         return str_req_key;
146 }
147
148 static int __handle_request_install(uid_t uid,
149                 GDBusMethodInvocation *invocation, GVariant *parameters)
150 {
151         uid_t target_uid = (uid_t)-1;
152         char *pkgtype = NULL;
153         char *pkgpath = NULL;
154         char *args = NULL;
155         char *reqkey = NULL;
156         gchar **tmp_args = NULL;
157         gsize args_count;
158         int ret = -1;
159         GVariant *value;
160         gchar *str;
161         int i = 0;
162         int len = 0;
163
164         g_variant_get(parameters, "(u&s&s@as)", &target_uid, &pkgtype, &pkgpath, &value);
165         tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
166
167         for (i = 0; i < args_count; i++)
168                 len = len + strlen(tmp_args[i]) + 1;
169
170         args = (char *)calloc(len, sizeof(char));
171         if (args == NULL) {
172                 ERR("calloc failed");
173                 ret =  -1;
174                 goto catch;
175         }
176
177         for (i = 0; i < args_count; i++) {
178                 strncat(args, tmp_args[i], strlen(tmp_args[i]));
179                 strncat(args, " ", strlen(" "));
180         }
181
182         if (target_uid == (uid_t)-1 || pkgtype == NULL) {
183                 g_dbus_method_invocation_return_value(invocation,
184                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
185                 ret = -1;
186                 goto catch;
187         }
188
189         if (pkgpath == NULL) {
190                 g_dbus_method_invocation_return_value(invocation,
191                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
192                 ret = -1;
193                 goto catch;
194         }
195
196         reqkey = __generate_reqkey(pkgpath);
197         if (reqkey == NULL) {
198                 ret = -1;
199                 goto catch;
200         }
201
202         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_INSTALL, pkgtype,
203                                 pkgpath, args)) {
204                 g_dbus_method_invocation_return_value(invocation,
205                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
206                 ret = -1;
207                 goto catch;
208         }
209
210         g_dbus_method_invocation_return_value(invocation,
211                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
212
213         ret = 0;
214
215 catch:
216         if (reqkey)
217                 free(reqkey);
218
219         if (args)
220                 free(args);
221
222         return ret;
223 }
224
225 static int __handle_request_reinstall(uid_t uid,
226                 GDBusMethodInvocation *invocation, GVariant *parameters)
227 {
228         uid_t target_uid = (uid_t)-1;
229         char *pkgtype = NULL;
230         char *pkgid = NULL;
231         char *reqkey;
232
233         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
234         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
235                 g_dbus_method_invocation_return_value(invocation,
236                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
237                 return -1;
238         }
239
240         reqkey = __generate_reqkey(pkgid);
241         if (reqkey == NULL)
242                 return -1;
243         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_REINSTALL, pkgtype,
244                                 pkgid, "")) {
245                 g_dbus_method_invocation_return_value(invocation,
246                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
247                 free(reqkey);
248                 return -1;
249         }
250
251         g_dbus_method_invocation_return_value(invocation,
252                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
253         free(reqkey);
254
255         return 0;
256 }
257
258 static int __handle_request_uninstall(uid_t uid,
259                 GDBusMethodInvocation *invocation, GVariant *parameters)
260 {
261         uid_t target_uid = (uid_t)-1;
262         char *pkgtype = NULL;
263         char *pkgid = NULL;
264         char *reqkey;
265
266         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
267         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
268                 g_dbus_method_invocation_return_value(invocation,
269                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
270                 return -1;
271         }
272
273         reqkey = __generate_reqkey(pkgid);
274         if (reqkey == NULL)
275                 return -1;
276         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_UNINSTALL, pkgtype,
277                                 pkgid, "")) {
278                 g_dbus_method_invocation_return_value(invocation,
279                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
280                 free(reqkey);
281                 return -1;
282         }
283
284         g_dbus_method_invocation_return_value(invocation,
285                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
286         free(reqkey);
287
288         return 0;
289 }
290
291 static int __handle_request_move(uid_t uid,
292                 GDBusMethodInvocation *invocation, GVariant *parameters)
293 {
294         uid_t target_uid = (uid_t)-1;
295         char *pkgtype = NULL;
296         char *pkgid = NULL;
297         char *reqkey;
298
299         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
300         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
301                 g_dbus_method_invocation_return_value(invocation,
302                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
303                 return -1;
304         }
305
306         reqkey = __generate_reqkey(pkgid);
307         if (reqkey == NULL)
308                 return -1;
309         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_MOVE, pkgtype,
310                                 pkgid, "")) {
311                 g_dbus_method_invocation_return_value(invocation,
312                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
313                 free(reqkey);
314                 return -1;
315         }
316
317         g_dbus_method_invocation_return_value(invocation,
318                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
319         free(reqkey);
320
321         return 0;
322 }
323
324 static int __handle_request_enable(uid_t uid,
325                 GDBusMethodInvocation *invocation, GVariant *parameters)
326 {
327         uid_t target_uid = (uid_t)-1;
328         char *pkgid = NULL;
329
330         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
331         if (target_uid == (uid_t)-1 || pkgid == NULL) {
332                 g_dbus_method_invocation_return_value(invocation,
333                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
334                 return -1;
335         }
336
337         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_ENABLE, "none",
338                                 pkgid, "")) {
339                 g_dbus_method_invocation_return_value(invocation,
340                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
341                 return -1;
342         }
343
344         g_dbus_method_invocation_return_value(invocation,
345                         g_variant_new("(i)", PKGMGR_R_OK));
346
347         return 0;
348 }
349
350 static int __handle_request_disable(uid_t uid,
351                 GDBusMethodInvocation *invocation, GVariant *parameters)
352 {
353         uid_t target_uid = (uid_t)-1;
354         char *pkgid = NULL;
355
356         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
357         if (target_uid == (uid_t)-1 || pkgid == NULL) {
358                 g_dbus_method_invocation_return_value(invocation,
359                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
360                 return -1;
361         }
362
363         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_DISABLE, "none",
364                                 pkgid, "")) {
365                 g_dbus_method_invocation_return_value(invocation,
366                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
367                 return -1;
368         }
369
370         g_dbus_method_invocation_return_value(invocation,
371                         g_variant_new("(i)", PKGMGR_R_OK));
372
373         return 0;
374 }
375
376 static int __handle_request_enable_global_app(uid_t uid,
377                 GDBusMethodInvocation *invocation, GVariant *parameters)
378 {
379         uid_t target_uid = (uid_t)-1;
380         char *appid = NULL;
381
382         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
383         if (target_uid == (uid_t)-1 || appid == NULL) {
384                 g_dbus_method_invocation_return_value(invocation,
385                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
386                 return -1;
387         }
388
389         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP, "none",
390                                 appid, "")) {
391                 g_dbus_method_invocation_return_value(invocation,
392                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
393                 return -1;
394         }
395
396         g_dbus_method_invocation_return_value(invocation,
397                         g_variant_new("(i)", PKGMGR_R_OK));
398
399         return 0;
400 }
401
402 static int __handle_request_disable_global_app(uid_t uid,
403                 GDBusMethodInvocation *invocation, GVariant *parameters)
404 {
405         uid_t target_uid = (uid_t)-1;
406         char *appid = NULL;
407
408         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
409         if (target_uid == (uid_t)-1 || appid == NULL) {
410                 g_dbus_method_invocation_return_value(invocation,
411                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
412                 return -1;
413         }
414
415         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP, "none",
416                                 appid, "")) {
417                 g_dbus_method_invocation_return_value(invocation,
418                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
419                 return -1;
420         }
421
422         g_dbus_method_invocation_return_value(invocation,
423                         g_variant_new("(i)", PKGMGR_R_OK));
424
425         return 0;
426 }
427
428 static int __handle_request_getsize(uid_t uid,
429                 GDBusMethodInvocation *invocation, GVariant *parameters)
430 {
431         uid_t target_uid = (uid_t)-1;
432         char *pkgid = NULL;
433         int get_type = -1;
434         char *reqkey;
435         char buf[4];
436
437         g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
438         if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
439                 g_dbus_method_invocation_return_value(invocation,
440                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
441                 return -1;
442         }
443
444         reqkey = __generate_reqkey(pkgid);
445         if (reqkey == NULL)
446                 return -1;
447
448         snprintf(buf, sizeof(buf), "%d", get_type);
449         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_GETSIZE, "getsize",
450                                 pkgid, buf)) {
451                 g_dbus_method_invocation_return_value(invocation,
452                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
453                 free(reqkey);
454                 return -1;
455         }
456
457         g_dbus_method_invocation_return_value(invocation,
458                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
459         free(reqkey);
460
461         return 0;
462 }
463
464 static int __handle_request_cleardata(uid_t uid,
465                 GDBusMethodInvocation *invocation, GVariant *parameters)
466 {
467         uid_t target_uid = (uid_t)-1;
468         char *pkgtype = NULL;
469         char *pkgid = NULL;
470
471         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
472         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
473                 g_dbus_method_invocation_return_value(invocation,
474                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
475                 return -1;
476         }
477
478         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CLEARDATA, pkgtype,
479                                 pkgid, "")) {
480                 g_dbus_method_invocation_return_value(invocation,
481                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
482                 return -1;
483         }
484
485         g_dbus_method_invocation_return_value(invocation,
486                         g_variant_new("(i)", PKGMGR_R_OK));
487
488         return 0;
489 }
490
491 static int __handle_request_clearcache(uid_t uid,
492                 GDBusMethodInvocation *invocation, GVariant *parameters)
493 {
494         uid_t target_uid = (uid_t)-1;
495         char *pkgid = NULL;
496
497         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
498         if (target_uid == (uid_t)-1 || pkgid == NULL) {
499                 g_dbus_method_invocation_return_value(invocation,
500                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
501                 return -1;
502         }
503
504         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CLEARCACHE,
505                                 "clearcache", pkgid, "")) {
506                 g_dbus_method_invocation_return_value(invocation,
507                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
508                 return -1;
509         }
510
511         g_dbus_method_invocation_return_value(invocation,
512                         g_variant_new("(i)", PKGMGR_R_OK));
513
514         return 0;
515 }
516
517 static int __handle_request_kill(uid_t uid,
518                 GDBusMethodInvocation *invocation, GVariant *parameters)
519 {
520         uid_t target_uid = (uid_t)-1;
521         char *pkgid = NULL;
522
523         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
524         if (target_uid == (uid_t)-1 || pkgid == NULL) {
525                 g_dbus_method_invocation_return_value(invocation,
526                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
527                 return -1;
528         }
529
530         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_KILL, "pkg",
531                                 pkgid, "")) {
532                 g_dbus_method_invocation_return_value(invocation,
533                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
534                 return -1;
535         }
536
537         g_dbus_method_invocation_return_value(invocation,
538                         g_variant_new("(i)", PKGMGR_R_OK));
539
540         return 0;
541 }
542
543 static int __handle_request_check(uid_t uid,
544                 GDBusMethodInvocation *invocation, GVariant *parameters)
545 {
546         uid_t target_uid = (uid_t)-1;
547         char *pkgid = NULL;
548
549         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
550         if (target_uid == (uid_t)-1 || pkgid == NULL) {
551                 g_dbus_method_invocation_return_value(invocation,
552                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
553                 return -1;
554         }
555
556         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CHECK, "pkg",
557                                 pkgid, "")) {
558                 g_dbus_method_invocation_return_value(invocation,
559                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
560                 return -1;
561         }
562
563         g_dbus_method_invocation_return_value(invocation,
564                         g_variant_new("(i)", PKGMGR_R_OK));
565
566         return 0;
567 }
568
569 static int __handle_request_generate_license_request(uid_t uid,
570                 GDBusMethodInvocation *invocation, GVariant *parameters)
571 {
572         char *reqkey;
573         char *resp_data = NULL;
574
575         g_variant_get(parameters, "(&s)", &resp_data);
576         if (resp_data == NULL) {
577                 g_dbus_method_invocation_return_value(invocation,
578                                 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
579                 return -1;
580         }
581
582         reqkey = __generate_reqkey("drm");
583         if (reqkey == NULL) {
584                 g_dbus_method_invocation_return_value(invocation,
585                                 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
586                                         ""));
587                 return -1;
588         }
589
590         if (_pm_queue_push(uid, reqkey,
591                                 PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
592                                 "pkg", "", resp_data)) {
593                 g_dbus_method_invocation_return_value(invocation,
594                                 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
595                                         ""));
596                 free(reqkey);
597                 return -1;
598         }
599
600         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
601                                 (gpointer)invocation))
602                 ERR("reqkey already exists");
603
604         return 0;
605 }
606
607 static int __handle_request_register_license(uid_t uid,
608                 GDBusMethodInvocation *invocation, GVariant *parameters)
609 {
610         char *reqkey;
611         char *resp_data = NULL;
612
613         g_variant_get(parameters, "(&s)", &resp_data);
614         if (resp_data == NULL) {
615                 g_dbus_method_invocation_return_value(invocation,
616                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
617                 return -1;
618         }
619
620         reqkey = __generate_reqkey("drm");
621         if (reqkey == NULL) {
622                 g_dbus_method_invocation_return_value(invocation,
623                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
624                 return -1;
625         }
626
627         if (_pm_queue_push(uid, reqkey, PKGMGR_REQUEST_TYPE_REGISTER_LICENSE,
628                                 "pkg", "", resp_data)) {
629                 g_dbus_method_invocation_return_value(invocation,
630                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
631                 free(reqkey);
632                 return -1;
633         }
634
635         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
636                                 (gpointer)invocation))
637                 ERR("reqkey already exists");
638
639         return 0;
640 }
641
642 static int __handle_request_decrypt_package(uid_t uid,
643                 GDBusMethodInvocation *invocation, GVariant *parameters)
644 {
645         char *reqkey;
646         char *drm_file_path = NULL;
647         char *decrypted_file_path = NULL;
648
649         g_variant_get(parameters, "(&s&s)", &drm_file_path,
650                         &decrypted_file_path);
651         if (drm_file_path == NULL || decrypted_file_path == NULL) {
652                 g_dbus_method_invocation_return_value(invocation,
653                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
654                 return -1;
655         }
656
657         reqkey = __generate_reqkey("drm");
658         if (reqkey == NULL) {
659                 g_dbus_method_invocation_return_value(invocation,
660                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
661                 return -1;
662         }
663
664         if (_pm_queue_push(uid, reqkey, PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE,
665                                 "pkg", drm_file_path, decrypted_file_path)) {
666                 g_dbus_method_invocation_return_value(invocation,
667                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
668                 free(reqkey);
669                 return -1;
670         }
671
672         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
673                                 (gpointer)invocation))
674                 ERR("reqkey already exists");
675
676         return 0;
677 }
678
679 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
680 {
681         GError *err = NULL;
682         GVariant *result;
683         uid_t uid;
684
685         result = g_dbus_connection_call_sync(connection,
686                         "org.freedesktop.DBus", "/org/freedesktop/DBus",
687                         "org.freedesktop.DBus", "GetConnectionUnixUser",
688                         g_variant_new("(s)", name), NULL,
689                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
690         if (result == NULL) {
691                 ERR("failed to get caller uid: %s", err->message);
692                 g_error_free(err);
693                 return (uid_t)-1;
694         }
695
696         g_variant_get(result, "(u)", &uid);
697
698         return uid;
699 }
700
701 static void __handle_method_call(GDBusConnection *connection,
702                 const gchar *sender, const gchar *object_path,
703                 const gchar *interface_name, const gchar *method_name,
704                 GVariant *parameters, GDBusMethodInvocation *invocation,
705                 gpointer user_data)
706 {
707         int ret;
708         uid_t uid;
709
710         uid = __get_caller_uid(connection,
711                 g_dbus_method_invocation_get_sender(invocation));
712         if (uid == (uid_t)-1)
713                 return;
714
715         if (g_strcmp0(method_name, "install") == 0)
716                 ret = __handle_request_install(uid, invocation, parameters);
717         else if (g_strcmp0(method_name, "reinstall") == 0)
718                 ret = __handle_request_reinstall(uid, invocation, parameters);
719         else if (g_strcmp0(method_name, "uninstall") == 0)
720                 ret = __handle_request_uninstall(uid, invocation, parameters);
721         else if (g_strcmp0(method_name, "cleardata") == 0)
722                 ret = __handle_request_cleardata(uid, invocation, parameters);
723         else if (g_strcmp0(method_name, "move") == 0)
724                 ret = __handle_request_move(uid, invocation, parameters);
725         else if (g_strcmp0(method_name, "enable") == 0)
726                 ret = __handle_request_enable(uid, invocation, parameters);
727         else if (g_strcmp0(method_name, "disable") == 0)
728                 ret = __handle_request_disable(uid, invocation, parameters);
729         else if (g_strcmp0(method_name, "getsize") == 0)
730                 ret = __handle_request_getsize(uid, invocation, parameters);
731         else if (g_strcmp0(method_name, "clearcache") == 0)
732                 ret = __handle_request_clearcache(uid, invocation, parameters);
733         else if (g_strcmp0(method_name, "enable_global_app") == 0)
734                 ret = __handle_request_enable_global_app(uid, invocation, parameters);
735         else if (g_strcmp0(method_name, "disable_global_app") == 0)
736                 ret = __handle_request_disable_global_app(uid, invocation, parameters);
737         else if (g_strcmp0(method_name, "kill") == 0)
738                 ret = __handle_request_kill(uid, invocation, parameters);
739         else if (g_strcmp0(method_name, "check") == 0)
740                 ret = __handle_request_check(uid, invocation, parameters);
741         else if (g_strcmp0(method_name, "generate_license_request") == 0)
742                 ret = __handle_request_generate_license_request(uid, invocation,
743                                 parameters);
744         else if (g_strcmp0(method_name, "register_license") == 0)
745                 ret = __handle_request_register_license(uid, invocation,
746                                 parameters);
747         else if (g_strcmp0(method_name, "decrypt_package") == 0)
748                 ret = __handle_request_decrypt_package(uid, invocation,
749                                 parameters);
750         else
751                 ret = -1;
752
753         if (ret == 0)
754                 g_idle_add(queue_job, NULL);
755 }
756
757 int __return_value_to_caller(const char *req_key, GVariant *result)
758 {
759         GDBusMethodInvocation *invocation;
760
761         invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
762                         (gpointer)req_key);
763         if (invocation == NULL) {
764                 ERR("no such request id");
765                 return -1;
766         }
767
768         g_dbus_method_invocation_return_value(invocation, result);
769         g_hash_table_remove(req_table, (gpointer)req_key);
770
771         return 0;
772 }
773
774 static const GDBusInterfaceVTable interface_vtable =
775 {
776         __handle_method_call,
777         NULL,
778         NULL,
779 };
780
781 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
782                 gpointer user_data)
783 {
784         GError *err = NULL;
785
786         DBG("on bus acquired");
787
788         reg_id = g_dbus_connection_register_object(connection,
789                         COMM_PKGMGR_DBUS_OBJECT_PATH,
790                         instropection_data->interfaces[0],
791                         &interface_vtable, NULL, NULL, &err);
792
793         if (reg_id == 0) {
794                 ERR("failed to register object: %s", err->message);
795                 g_error_free(err);
796         }
797 }
798
799 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
800                 gpointer user_data)
801 {
802         DBG("on name acquired: %s", name);
803 }
804
805 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
806                 gpointer user_data)
807 {
808         DBG("on name lost: %s", name);
809 }
810
811 int __init_request_handler(void)
812 {
813         instropection_data = g_dbus_node_info_new_for_xml(instropection_xml, NULL);
814
815         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, COMM_PKGMGR_DBUS_SERVICE,
816                         G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
817                         __on_name_acquired, __on_name_lost, NULL, NULL);
818
819         req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
820                         free, NULL);
821         if (req_table == NULL)
822                 return -1;
823
824         return 0;
825 }
826
827 void __fini_request_handler(void)
828 {
829         g_hash_table_destroy(req_table);
830         g_bus_unown_name(owner_id);
831         g_dbus_node_info_unref(instropection_data);
832 }