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