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