7744c439e4e9d45126edf1e52219d620a0c4aaa2
[platform/core/appfw/app2sd.git] / plugin / app2sd / src / app2sd_server.c
1 /*
2  * app2sd-server
3  *
4  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <gio/gio.h>
21
22 #include "app2sd_internals.h"
23
24 GMainLoop *app2sd_mainloop = NULL;
25
26 gboolean __exit_app2sd_server(void *data)
27 {
28         _D("exit app2sd_server");
29
30         g_main_loop_quit(app2sd_mainloop);
31
32         return FALSE;
33 }
34
35 static int __app2sd_get_sender_unixinfo(GDBusConnection *conn,
36                 const char *sender_name, const char *type)
37 {
38         GDBusMessage *msg = NULL;
39         GDBusMessage *reply = NULL;
40         GError *err = NULL;
41         GVariant *body;
42         int ret = -1;
43         unsigned int value;
44
45         msg = g_dbus_message_new_method_call("org.freedesktop.DBus",
46                 "/org/freedesktop/DBus", "org.freedesktop.DBus", type);
47         if (!msg) {
48                 _E("Can't allocate new method call");
49                 goto out;
50         }
51
52         g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
53         reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
54                 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
55
56         if (!reply) {
57                 if (err != NULL) {
58                         _E("Failed to get info [%s]", err->message);
59                         g_error_free(err);
60                 }
61                 goto out;
62         }
63
64         body = g_dbus_message_get_body(reply);
65         g_variant_get(body, "(u)", &value);
66         ret = (int)value;
67
68 out:
69         if (msg)
70                 g_object_unref(msg);
71         if (reply)
72                 g_object_unref(reply);
73
74         return ret;
75 }
76
77 /*
78 static int __app2sd_get_sender_pid(GDBusConnection *conn,
79                 const char *sender_name)
80 {
81         int pid = 0;
82
83         pid = __app2sd_get_sender_unixinfo(conn, sender_name,
84                 "GetConnectionUnixProcessID");
85         if (pid < 0) {
86                 _E("failed to get pid");
87                 pid = 0;
88         }
89
90         _D("sender_name(%s), pid(%d)", sender_name, pid);
91
92         return pid;
93 }
94 */
95
96 static int __app2sd_get_sender_uid(GDBusConnection *conn,
97                 const char *sender_name)
98 {
99         int uid = -1;
100
101         uid = __app2sd_get_sender_unixinfo(conn, sender_name,
102                 "GetConnectionUnixUser");
103         if (uid < 0)
104                 _E("failed to get uid");
105
106         _D("sender_name(%s), uid(%d)", sender_name, uid);
107
108         return uid;
109 }
110
111 static GDBusNodeInfo *introspection_data;
112 static const gchar introspection_xml[] =
113 "<node>"
114 "       <interface name='org.tizen.app2sd'>"
115 "               <method name='PreAppInstall'>"
116 "                       <arg type='s' name='pkgid' direction='in'/>"
117 "                       <arg type='i' name='size' direction='in'/>"
118 "                       <arg type='a(si)' name='dir_list' direction='in'/>"
119 "                       <arg type='i' name='uid' direction='in'/>"
120 "                       <arg type='i' name='result' direction='out'/>"
121 "               </method>"
122 "               <method name='PostAppInstall'>"
123 "                       <arg type='s' name='pkgid' direction='in'/>"
124 "                       <arg type='i' name='install_status' direction='in'/>"
125 "                       <arg type='i' name='uid' direction='in'/>"
126 "                       <arg type='i' name='result' direction='out'/>"
127 "               </method>"
128 "               <method name='PreAppUpgrade'>"
129 "                       <arg type='s' name='pkgid' direction='in'/>"
130 "                       <arg type='i' name='size' direction='in'/>"
131 "                       <arg type='a(si)' name='dir_list' direction='in'/>"
132 "                       <arg type='i' name='uid' direction='in'/>"
133 "                       <arg type='i' name='result' direction='out'/>"
134 "               </method>"
135 "               <method name='PostAppUpgrade'>"
136 "                       <arg type='s' name='pkgid' direction='in'/>"
137 "                       <arg type='i' name='install_status' direction='in'/>"
138 "                       <arg type='i' name='uid' direction='in'/>"
139 "                       <arg type='i' name='result' direction='out'/>"
140 "               </method>"
141 "               <method name='PreAppUninstall'>"
142 "                       <arg type='s' name='pkgid' direction='in'/>"
143 "                       <arg type='i' name='uid' direction='in'/>"
144 "                       <arg type='i' name='result' direction='out'/>"
145 "               </method>"
146 "               <method name='PostAppUninstall'>"
147 "                       <arg type='s' name='pkgid' direction='in'/>"
148 "                       <arg type='i' name='uid' direction='in'/>"
149 "                       <arg type='i' name='result' direction='out'/>"
150 "               </method>"
151 "               <method name='OndemandSetupInit'>"
152 "                       <arg type='s' name='pkgid' direction='in'/>"
153 "                       <arg type='i' name='uid' direction='in'/>"
154 "                       <arg type='i' name='result' direction='out'/>"
155 "               </method>"
156 "               <method name='OndemandSetupExit'>"
157 "                       <arg type='s' name='pkgid' direction='in'/>"
158 "                       <arg type='i' name='uid' direction='in'/>"
159 "                       <arg type='i' name='result' direction='out'/>"
160 "               </method>"
161 "               <method name='PreMoveInstalledApp'>"
162 "                       <arg type='s' name='pkgid' direction='in'/>"
163 "                       <arg type='i' name='move_type' direction='in'/>"
164 "                       <arg type='a(si)' name='dir_list' direction='in'/>"
165 "                       <arg type='i' name='uid' direction='in'/>"
166 "                       <arg type='i' name='result' direction='out'/>"
167 "               </method>"
168 "               <method name='PostMoveInstalledApp'>"
169 "                       <arg type='s' name='pkgid' direction='in'/>"
170 "                       <arg type='i' name='move_type' direction='in'/>"
171 "                       <arg type='i' name='uid' direction='in'/>"
172 "                       <arg type='i' name='result' direction='out'/>"
173 "               </method>"
174 "               <method name='ForceClean'>"
175 "                       <arg type='s' name='pkgid' direction='in'/>"
176 "                       <arg type='i' name='uid' direction='in'/>"
177 "                       <arg type='i' name='result' direction='out'/>"
178 "               </method>"
179 "               <method name='EnableFullPkg'>"
180 "                       <arg type='i' name='result' direction='out'/>"
181 "               </method>"
182 "               <method name='DisableFullPkg'>"
183 "                       <arg type='i' name='result' direction='out'/>"
184 "               </method>"
185 "       </interface>"
186 "</node>";
187
188 static void _app2sd_server_return_method_error(GDBusMethodInvocation *invocation, int result)
189 {
190         GVariant *param = NULL;
191
192         param = g_variant_new("(i)", result);
193         g_dbus_method_invocation_return_value(invocation, param);
194 }
195
196 static void _app2sd_server_pre_app_install(GDBusConnection *connection, const gchar *sender,
197         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
198 {
199         GVariant *param = NULL;
200         int result = APP2EXT_SUCCESS;
201         int size;
202         char *pkgid = NULL;
203         GVariantIter *iter;
204         gchar *str = NULL;
205         int type;
206         int ret = 0;
207         uid_t target_uid = -1;
208         GList *dir_list = NULL;
209         GList *list = NULL;
210         app2ext_dir_details *dir_detail = NULL;
211
212         g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
213
214         _D("pkgid(%s), size(%d),sender_uid(%d), target_uid(%d)",
215                 pkgid, size, sender_uid, target_uid);
216
217         if (sender_uid != 0 && sender_uid != target_uid) {
218                 _E("Not permitted user!");
219                 g_variant_iter_free(iter);
220                 _app2sd_server_return_method_error(invocation,
221                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
222                 return;
223         }
224
225         while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
226                 if (str) {
227                         _D("str(%s), type(%d)", str, type);
228
229                         /* generate dir_list */
230                         dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
231                         if (dir_detail == NULL) {
232                                 _E("memory allocation failed");
233                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
234                                 break;
235                         }
236
237                         dir_detail->name = strdup((char *)str);
238                         if (dir_detail->name == NULL) {
239                                 _E("out of memory");
240                                 free(dir_detail);
241                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
242                                 break;
243                         }
244
245                         dir_detail->type = type;
246                         list = g_list_append(list, dir_detail);
247                 }
248         }
249         g_variant_iter_free(iter);
250
251         dir_list = g_list_first(list);
252         ret = app2sd_usr_pre_app_install(pkgid, dir_list, size, target_uid);
253         if (ret) {
254                 _E("error(%d)", ret);
255                 result = ret;
256         }
257
258         param = g_variant_new("(i)", result);
259         g_dbus_method_invocation_return_value(invocation, param);
260 }
261
262 static void _app2sd_server_post_app_install(GDBusConnection *connection, const gchar *sender,
263         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
264 {
265         GVariant *param = NULL;
266         int result = APP2EXT_SUCCESS;
267         char *pkgid = NULL;
268         int install_status = 0;
269         int target_uid = -1;
270         int ret = 0;
271
272         g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
273
274         _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
275                 pkgid, install_status, sender_uid, target_uid);
276
277         if (sender_uid != 0 && sender_uid != target_uid) {
278                 _E("Not permitted user!");
279                 _app2sd_server_return_method_error(invocation,
280                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
281                 return;
282         }
283
284         ret = app2sd_usr_post_app_install(pkgid, install_status, target_uid);
285         if (ret) {
286                 _E("error(%d)", ret);
287                 result = ret;
288         }
289
290         param = g_variant_new("(i)", result);
291         g_dbus_method_invocation_return_value(invocation, param);
292 }
293
294 static void _app2sd_server_pre_app_upgrade(GDBusConnection *connection, const gchar *sender,
295         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
296 {
297         GVariant *param = NULL;
298         int result = APP2EXT_SUCCESS;
299         int size;
300         char *pkgid = NULL;
301         GVariantIter *iter;
302         gchar *str = NULL;
303         int type;
304         uid_t target_uid = -1;
305         int ret = 0;
306         GList *dir_list = NULL;
307         GList *list = NULL;
308         app2ext_dir_details *dir_detail = NULL;
309
310         g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
311
312         _D("pkgid(%s), size(%d), sender_uid(%d), target_uid(%d)",
313                 pkgid, size, sender_uid, target_uid);
314
315         if (sender_uid != 0 && sender_uid != target_uid) {
316                 _E("Not permitted user!");
317                 g_variant_iter_free(iter);
318                 _app2sd_server_return_method_error(invocation,
319                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
320                 return;
321         }
322
323         while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
324                 if (str) {
325                         _D("str(%s), type(%d)", str, type);
326
327                         /* generate dir_list */
328                         dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
329                         if (dir_detail == NULL) {
330                                 _E("memory allocation failed");
331                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
332                                 break;
333                         }
334
335                         dir_detail->name = strdup((char *)str);
336                         if (dir_detail->name == NULL) {
337                                 _E("out of memory");
338                                 free(dir_detail);
339                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
340                                 break;
341                         }
342
343                         dir_detail->type = type;
344                         list = g_list_append(list, dir_detail);
345                 }
346         }
347         g_variant_iter_free(iter);
348
349         dir_list = g_list_first(list);
350         ret = app2sd_usr_pre_app_upgrade(pkgid, dir_list, size, target_uid);
351         if (ret) {
352                 _E("error(%d)", ret);
353                 result = ret;
354         }
355
356         param = g_variant_new("(i)", result);
357         g_dbus_method_invocation_return_value(invocation, param);
358 }
359
360 static void _app2sd_server_post_app_upgrade(GDBusConnection *connection, const gchar *sender,
361         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
362 {
363         GVariant *param = NULL;
364         int result = APP2EXT_SUCCESS;
365         char *pkgid = NULL;
366         int install_status = 0;
367         uid_t target_uid = -1;
368         int ret = 0;
369
370         g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
371
372         _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
373                 pkgid, install_status, sender_uid, target_uid);
374
375         if (sender_uid != 0 && sender_uid != target_uid) {
376                 _E("Not permitted user!");
377                 _app2sd_server_return_method_error(invocation,
378                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
379                 return;
380         }
381
382         ret = app2sd_usr_post_app_upgrade(pkgid, install_status, target_uid);
383         if (ret) {
384                 _E("error(%d)", ret);
385                 result = ret;
386         }
387
388         param = g_variant_new("(i)", result);
389         g_dbus_method_invocation_return_value(invocation, param);
390 }
391
392 static void _app2sd_server_pre_app_uninstall(GDBusConnection *connection, const gchar *sender,
393         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
394 {
395         GVariant *param = NULL;
396         int result = APP2EXT_SUCCESS;
397         char *pkgid = NULL;
398         uid_t target_uid = -1;
399         int ret = 0;
400
401         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
402
403         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
404                 pkgid, sender_uid, target_uid);
405
406         if (sender_uid != 0 && sender_uid != target_uid) {
407                 _E("Not permitted user!");
408                 _app2sd_server_return_method_error(invocation,
409                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
410                 return;
411         }
412
413         ret = app2sd_usr_pre_app_uninstall(pkgid, target_uid);
414         if (ret) {
415                 _E("error(%d)", ret);
416                 result = ret;
417         }
418
419         param = g_variant_new("(i)", result);
420         g_dbus_method_invocation_return_value(invocation, param);
421 }
422
423 static void _app2sd_server_post_app_uninstall(GDBusConnection *connection, const gchar *sender,
424         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
425 {
426         GVariant *param = NULL;
427         int result = APP2EXT_SUCCESS;
428         char *pkgid = NULL;
429         uid_t target_uid = -1;
430         int ret = 0;
431
432         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
433
434         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
435                 pkgid, sender_uid, target_uid);
436
437         if (sender_uid != 0 && sender_uid != target_uid) {
438                 _E("Not permitted user!");
439                 _app2sd_server_return_method_error(invocation,
440                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
441                 return;
442         }
443
444         ret = app2sd_usr_post_app_uninstall(pkgid, target_uid);
445         if (ret) {
446                 _E("error(%d)", ret);
447                 result = ret;
448         }
449
450         param = g_variant_new("(i)", result);
451         g_dbus_method_invocation_return_value(invocation, param);
452 }
453
454 static void _app2sd_server_ondemand_setup_init(GDBusConnection *connection, const gchar *sender,
455         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
456 {
457         GVariant *param = NULL;
458         int result = APP2EXT_SUCCESS;
459         char *pkgid = NULL;
460         uid_t target_uid = -1;
461         int ret = 0;
462
463         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
464
465         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
466                 pkgid, sender_uid, target_uid);
467
468         if (sender_uid != 0 && sender_uid != target_uid) {
469                 _E("Not permitted user!");
470                 _app2sd_server_return_method_error(invocation,
471                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
472                 return;
473         }
474
475         ret = app2sd_usr_on_demand_setup_init(pkgid, target_uid);
476         if (ret) {
477                 _E("error(%d)", ret);
478                 result = ret;
479         }
480
481         param = g_variant_new("(i)", result);
482         g_dbus_method_invocation_return_value(invocation, param);
483 }
484
485 static void _app2sd_server_ondemand_setup_exit(GDBusConnection *connection, const gchar *sender,
486         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
487 {
488         GVariant *param = NULL;
489         int result = APP2EXT_SUCCESS;
490         char *pkgid = NULL;
491         uid_t target_uid = -1;
492         int ret = 0;
493
494         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
495
496         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
497                 pkgid, sender_uid, target_uid);
498
499         if (sender_uid != 0 && sender_uid != target_uid) {
500                 _E("Not permitted user!");
501                 _app2sd_server_return_method_error(invocation,
502                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
503                 return;
504         }
505
506         ret = app2sd_usr_on_demand_setup_exit(pkgid, target_uid);
507         if (ret) {
508                 _E("error(%d)", ret);
509                 result = ret;
510         }
511
512         param = g_variant_new("(i)", result);
513         g_dbus_method_invocation_return_value(invocation, param);
514 }
515
516 static void _app2sd_server_pre_move_installed_app(GDBusConnection *connection,
517         const gchar *sender, GVariant *parameters,
518         GDBusMethodInvocation *invocation, uid_t sender_uid)
519 {
520         GVariant *param = NULL;
521         int result = APP2EXT_SUCCESS;
522         int move_type;
523         char *pkgid = NULL;
524         GVariantIter *iter;
525         gchar *str = NULL;
526         int type;
527         int ret = 0;
528         uid_t target_uid = -1;
529         GList *dir_list = NULL;
530         GList *list = NULL;
531         app2ext_dir_details *dir_detail = NULL;
532
533         g_variant_get(parameters, "(&sia(si)i)", &pkgid, &move_type, &iter, &target_uid);
534
535         _D("pkgid(%s), move_type(%d),sender_uid(%d), target_uid(%d)",
536                 pkgid, move_type, sender_uid, target_uid);
537
538         if (sender_uid != 0 && sender_uid != target_uid) {
539                 _E("Not permitted user!");
540                 g_variant_iter_free(iter);
541                 _app2sd_server_return_method_error(invocation,
542                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
543                 return;
544         }
545
546         while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
547                 if (str) {
548                         _D("str(%s), type(%d)", str, type);
549
550                         /* generate dir_list */
551                         dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
552                         if (dir_detail == NULL) {
553                                 _E("memory allocation failed");
554                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
555                                 break;
556                         }
557
558                         dir_detail->name = strdup((char *)str);
559                         if (dir_detail->name == NULL) {
560                                 _E("out of memory");
561                                 free(dir_detail);
562                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
563                                 break;
564                         }
565
566                         dir_detail->type = type;
567                         list = g_list_append(list, dir_detail);
568                 }
569         }
570         g_variant_iter_free(iter);
571
572         dir_list = g_list_first(list);
573         ret = app2sd_usr_pre_move_installed_app(pkgid, dir_list, move_type, target_uid);
574         if (ret) {
575                 _E("pre_move error(%d)", ret);
576                 result = ret;
577         }
578
579         param = g_variant_new("(i)", result);
580         g_dbus_method_invocation_return_value(invocation, param);
581 }
582
583 static void _app2sd_server_post_move_installed_app(GDBusConnection *connection,
584         const gchar *sender, GVariant *parameters,
585         GDBusMethodInvocation *invocation, uid_t sender_uid)
586 {
587         GVariant *param = NULL;
588         int result = APP2EXT_SUCCESS;
589         int move_type;
590         char *pkgid = NULL;
591         int ret = 0;
592         uid_t target_uid = -1;
593
594         g_variant_get(parameters, "(&sii)", &pkgid, &move_type, &target_uid);
595
596         _D("pkgid(%s), move_type(%d),sender_uid(%d), target_uid(%d)",
597                 pkgid, move_type, sender_uid, target_uid);
598
599         if (sender_uid != 0 && sender_uid != target_uid) {
600                 _E("Not permitted user!");
601                 _app2sd_server_return_method_error(invocation,
602                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
603                 return;
604         }
605
606         ret = app2sd_usr_post_move_installed_app(pkgid, move_type, target_uid);
607         if (ret) {
608                 _E("post_move error(%d)", ret);
609                 result = ret;
610         }
611
612         param = g_variant_new("(i)", result);
613         g_dbus_method_invocation_return_value(invocation, param);
614 }
615
616 static void _app2sd_server_force_clean(GDBusConnection *connection, const gchar *sender,
617         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
618 {
619         GVariant *param = NULL;
620         int result = APP2EXT_SUCCESS;
621         char *pkgid = NULL;
622         uid_t target_uid = -1;
623         int ret = 0;
624
625         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
626
627         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
628                 pkgid, sender_uid, target_uid);
629
630         if (sender_uid != 0 && sender_uid != target_uid) {
631                 _E("Not permitted user!");
632                 _app2sd_server_return_method_error(invocation,
633                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
634                 return;
635         }
636
637         ret = app2sd_usr_force_clean(pkgid, target_uid);
638         if (ret) {
639                 _E("error(%d)", ret);
640                 result = ret;
641         }
642
643         param = g_variant_new("(i)", result);
644         g_dbus_method_invocation_return_value(invocation, param);
645 }
646
647 static void _app2sd_server_enable_full_pkg(GDBusConnection *connection, const gchar *sender,
648         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
649 {
650         GVariant *param = NULL;
651         int result = APP2EXT_SUCCESS;
652         int ret = 0;
653
654         _D("sender_uid(%d)", sender_uid);
655
656         if (sender_uid >= REGULAR_USER) {
657                 _E("Not permitted user!");
658                 _app2sd_server_return_method_error(invocation,
659                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
660                 return;
661         }
662
663         ret = app2sd_enable_full_pkg();
664         if (ret) {
665                 _E("error(%d)", ret);
666                 result = ret;
667         }
668
669         param = g_variant_new("(i)", result);
670         g_dbus_method_invocation_return_value(invocation, param);
671 }
672
673 static void _app2sd_server_disable_full_pkg(GDBusConnection *connection, const gchar *sender,
674         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
675 {
676         GVariant *param = NULL;
677         int result = APP2EXT_SUCCESS;
678         int ret = 0;
679
680         _D("sender_uid(%d)", sender_uid);
681
682         if (sender_uid >= REGULAR_USER) {
683                 _E("Not permitted user!");
684                 _app2sd_server_return_method_error(invocation,
685                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
686                 return;
687         }
688
689         ret = app2sd_disable_full_pkg();
690         if (ret) {
691                 _E("error(%d)", ret);
692                 result = ret;
693         }
694
695         param = g_variant_new("(i)", result);
696         g_dbus_method_invocation_return_value(invocation, param);
697 }
698
699 static void handle_method_call(GDBusConnection *connection,
700         const gchar *sender, const gchar *object_path,
701         const gchar *interface_name, const gchar *method_name,
702         GVariant *parameters, GDBusMethodInvocation *invocation,
703         gpointer user_data)
704 {
705         uid_t sender_uid = -1;
706
707         sender_uid = (uid_t)__app2sd_get_sender_uid(connection, sender);
708
709         if (g_strcmp0(method_name, "PreAppInstall") == 0) {
710                 _app2sd_server_pre_app_install(connection, sender,
711                         parameters, invocation, sender_uid);
712         } else if (g_strcmp0(method_name, "PostAppInstall") == 0) {
713                 _app2sd_server_post_app_install(connection, sender,
714                         parameters, invocation, sender_uid);
715         } else if (g_strcmp0(method_name, "PreAppUpgrade") == 0) {
716                 _app2sd_server_pre_app_upgrade(connection, sender,
717                         parameters, invocation, sender_uid);
718         } else if (g_strcmp0(method_name, "PostAppUpgrade") == 0) {
719                 _app2sd_server_post_app_upgrade(connection, sender,
720                         parameters, invocation, sender_uid);
721         } else if (g_strcmp0(method_name, "PreAppUninstall") == 0) {
722                 _app2sd_server_pre_app_uninstall(connection, sender,
723                         parameters, invocation, sender_uid);
724         } else if (g_strcmp0(method_name, "PostAppUninstall") == 0) {
725                 _app2sd_server_post_app_uninstall(connection, sender,
726                         parameters, invocation, sender_uid);
727         } else if (g_strcmp0(method_name, "OndemandSetupInit") == 0) {
728                 _app2sd_server_ondemand_setup_init(connection, sender,
729                         parameters, invocation, sender_uid);
730         } else if (g_strcmp0(method_name, "OndemandSetupExit") == 0) {
731                 _app2sd_server_ondemand_setup_exit(connection, sender,
732                         parameters, invocation, sender_uid);
733         } else if (g_strcmp0(method_name, "PreMoveInstalledApp") == 0) {
734                 _app2sd_server_pre_move_installed_app(connection, sender,
735                         parameters, invocation, sender_uid);
736         } else if (g_strcmp0(method_name, "PostMoveInstalledApp") == 0) {
737                 _app2sd_server_post_move_installed_app(connection, sender,
738                         parameters, invocation, sender_uid);
739         } else if (g_strcmp0(method_name, "ForceClean") == 0) {
740                 _app2sd_server_force_clean(connection, sender,
741                         parameters, invocation, sender_uid);
742         } else if (g_strcmp0(method_name, "EnableFullPkg") == 0) {
743                 _app2sd_server_enable_full_pkg(connection, sender,
744                         parameters, invocation, sender_uid);
745         } else if (g_strcmp0(method_name, "DisableFullPkg") == 0) {
746                 _app2sd_server_disable_full_pkg(connection, sender,
747                         parameters, invocation, sender_uid);
748         }
749
750         g_timeout_add_seconds(5, __exit_app2sd_server, NULL);
751 }
752
753 static const GDBusInterfaceVTable interface_vtable = {
754         handle_method_call,
755         NULL,
756         NULL
757 };
758
759 static void __app2sd_on_bus_acquired(GDBusConnection *connection,
760                 const gchar *name, gpointer user_data)
761 {
762         _I("bus acquired(%s)", name);
763
764         guint reg_id = 0;
765         GError *error = NULL;
766
767         reg_id = g_dbus_connection_register_object(connection,
768                 APP2SD_OBJECT_PATH,
769                 introspection_data->interfaces[0],
770                 &interface_vtable,
771                 NULL, NULL, &error);
772         if (reg_id == 0) {
773                 _E("g_dbus_connection_register_object error(%s)", error->message);
774                 g_error_free(error);
775         }
776 }
777
778 static void __app2sd_on_name_acquired(GDBusConnection *connection,
779                 const gchar *name, gpointer user_data)
780 {
781         _I("name acquired(%s)", name);
782 }
783
784 static void __app2sd_on_name_lost(GDBusConnection *connection,
785                 const gchar *name, gpointer user_data)
786 {
787         _E("name lost(%s)", name);
788         g_main_loop_quit(app2sd_mainloop);
789 }
790
791 static int __app2sd_server_init()
792 {
793         GError *error = NULL;
794         guint owner_id = 0;
795
796         /* gdbus setup for method call */
797         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
798         if (!introspection_data) {
799                 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
800                 g_error_free(error);
801                 return -1;
802         }
803
804         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
805                 APP2SD_BUS_NAME,
806                 G_BUS_NAME_OWNER_FLAGS_NONE,
807                 __app2sd_on_bus_acquired,
808                 __app2sd_on_name_acquired,
809                 __app2sd_on_name_lost,
810                 NULL, NULL);
811         if (!owner_id) {
812                 _E("g_bus_own_name error");
813                 g_dbus_node_info_unref(introspection_data);
814                 return -1;
815         }
816
817         /* add timer */
818
819         return 0;
820 }
821
822 static void __app2sd_finalize(void)
823 {
824         _D("app2sd finalize");
825
826         if (introspection_data)
827                 g_dbus_node_info_unref(introspection_data);
828
829         _D("app2sd finalize end");
830 }
831
832 int main(int argc, char *argv[])
833 {
834         int ret = 0;
835
836         _I("app2sd_server : start");
837
838         ret = __app2sd_server_init();
839         if (ret) {
840                 _E("app2sd_server init failed(%d)", ret);
841                 return -1;
842         }
843
844         app2sd_mainloop = g_main_loop_new(NULL, FALSE);
845         if (!app2sd_mainloop) {
846                 _E("g_main_loop_new failed");
847                 return -1;
848         }
849
850         g_main_loop_run(app2sd_mainloop);
851
852         __app2sd_finalize();
853
854         _I("app2sd_server : end");
855
856         return 0;
857 }