adjust app2sd-server capability
[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
107         _D("sender_name(%s), uid(%d)", sender_name, uid);
108
109         return uid;
110 }
111
112 static GDBusNodeInfo *introspection_data;
113 static const gchar introspection_xml[] =
114 "<node>"
115 "       <interface name='org.tizen.app2sd'>"
116 "               <method name='PreAppInstall'>"
117 "                       <arg type='s' name='pkgid' direction='in'/>"
118 "                       <arg type='i' name='size' direction='in'/>"
119 "                       <arg type='a(si)' name='dir_list' direction='in'/>"
120 "                       <arg type='i' name='uid' direction='in'/>"
121 "                       <arg type='i' name='result' direction='out'/>"
122 "               </method>"
123 "               <method name='PostAppInstall'>"
124 "                       <arg type='s' name='pkgid' direction='in'/>"
125 "                       <arg type='i' name='install_status' direction='in'/>"
126 "                       <arg type='i' name='uid' direction='in'/>"
127 "                       <arg type='i' name='result' direction='out'/>"
128 "               </method>"
129 "               <method name='PreAppUpgrade'>"
130 "                       <arg type='s' name='pkgid' direction='in'/>"
131 "                       <arg type='i' name='size' direction='in'/>"
132 "                       <arg type='a(si)' name='dir_list' direction='in'/>"
133 "                       <arg type='i' name='uid' direction='in'/>"
134 "                       <arg type='i' name='result' direction='out'/>"
135 "               </method>"
136 "               <method name='PostAppUpgrade'>"
137 "                       <arg type='s' name='pkgid' direction='in'/>"
138 "                       <arg type='i' name='install_status' direction='in'/>"
139 "                       <arg type='i' name='uid' direction='in'/>"
140 "                       <arg type='i' name='result' direction='out'/>"
141 "               </method>"
142 "               <method name='PreAppUninstall'>"
143 "                       <arg type='s' name='pkgid' direction='in'/>"
144 "                       <arg type='i' name='uid' direction='in'/>"
145 "                       <arg type='i' name='result' direction='out'/>"
146 "               </method>"
147 "               <method name='PostAppUninstall'>"
148 "                       <arg type='s' name='pkgid' direction='in'/>"
149 "                       <arg type='i' name='uid' direction='in'/>"
150 "                       <arg type='i' name='result' direction='out'/>"
151 "               </method>"
152 "               <method name='OndemandSetupInit'>"
153 "                       <arg type='s' name='pkgid' direction='in'/>"
154 "                       <arg type='i' name='uid' direction='in'/>"
155 "                       <arg type='i' name='result' direction='out'/>"
156 "               </method>"
157 "               <method name='OndemandSetupExit'>"
158 "                       <arg type='s' name='pkgid' direction='in'/>"
159 "                       <arg type='i' name='uid' direction='in'/>"
160 "                       <arg type='i' name='result' direction='out'/>"
161 "               </method>"
162 "               <method name='MoveInstalledApp'>"
163 "                       <arg type='s' name='pkgid' direction='in'/>"
164 "                       <arg type='i' name='move_type' direction='in'/>"
165 "                       <arg type='a(si)' name='dir_list' direction='in'/>"
166 "                       <arg type='i' name='uid' direction='in'/>"
167 "                       <arg type='i' name='result' direction='out'/>"
168 "               </method>"
169 "               <method name='ForceClean'>"
170 "                       <arg type='s' name='pkgid' direction='in'/>"
171 "                       <arg type='i' name='uid' direction='in'/>"
172 "                       <arg type='i' name='result' direction='out'/>"
173 "               </method>"
174 "       </interface>"
175 "</node>";
176
177 static void _app2sd_server_return_method_error(GDBusMethodInvocation *invocation, int result)
178 {
179         GVariant *param = NULL;
180
181         param = g_variant_new("(i)", result);
182         g_dbus_method_invocation_return_value(invocation, param);
183 }
184
185 static void _app2sd_server_pre_app_install(GDBusConnection *connection, const gchar *sender,
186         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
187 {
188         GVariant *param = NULL;
189         int result = APP2EXT_SUCCESS;
190         int size;
191         char *pkgid = NULL;
192         GVariantIter *iter;
193         gchar *str = NULL;
194         int type;
195         int ret = 0;
196         uid_t target_uid = -1;
197         GList *dir_list = NULL;
198         GList *list = NULL;
199         app2ext_dir_details *dir_detail = NULL;
200
201         g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
202
203         _D("pkgid(%s), size(%d),sender_uid(%d), target_uid(%d)",
204                 pkgid, size, sender_uid, target_uid);
205
206         if (sender_uid != 0 && sender_uid != target_uid) {
207                 _E("Not permitted user!");
208                 g_variant_iter_free(iter);
209                 _app2sd_server_return_method_error(invocation,
210                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
211                 return;
212         }
213
214         while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
215                 if (str) {
216                         _D("str(%s), type(%d)", str, type);
217
218                         /* generate dir_list */
219                         dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
220                         if (dir_detail == NULL) {
221                                 _E("memory allocation failed");
222                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
223                                 break;
224                         }
225
226                         dir_detail->name = strdup((char *)str);
227                         if (dir_detail->name == NULL) {
228                                 _E("out of memory");
229                                 free(dir_detail);
230                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
231                                 break;
232                         }
233
234                         dir_detail->type = type;
235                         list = g_list_append(list, dir_detail);
236                 }
237         }
238         g_variant_iter_free(iter);
239
240         dir_list = g_list_first(list);
241         ret = app2sd_usr_pre_app_install(pkgid, dir_list, size, target_uid);
242         if (ret) {
243                 _E("error(%d)", ret);
244                 result = ret;
245         }
246
247         param = g_variant_new("(i)", result);
248         g_dbus_method_invocation_return_value(invocation, param);
249 }
250
251 static void _app2sd_server_post_app_install(GDBusConnection *connection, const gchar *sender,
252         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
253 {
254         GVariant *param = NULL;
255         int result = APP2EXT_SUCCESS;
256         char *pkgid = NULL;
257         int install_status = 0;
258         int target_uid = -1;
259         int ret = 0;
260
261         g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
262
263         _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
264                 pkgid, install_status, sender_uid, target_uid);
265
266         if (sender_uid != 0 && sender_uid != target_uid) {
267                 _E("Not permitted user!");
268                 _app2sd_server_return_method_error(invocation,
269                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
270                 return;
271         }
272
273         ret = app2sd_usr_post_app_install(pkgid, install_status, target_uid);
274         if (ret) {
275                 _E("error(%d)", ret);
276                 result = ret;
277         }
278
279         param = g_variant_new("(i)", result);
280         g_dbus_method_invocation_return_value(invocation, param);
281 }
282
283 static void _app2sd_server_pre_app_upgrade(GDBusConnection *connection, const gchar *sender,
284         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
285 {
286         GVariant *param = NULL;
287         int result = APP2EXT_SUCCESS;
288         int size;
289         char *pkgid = NULL;
290         GVariantIter *iter;
291         gchar *str = NULL;
292         int type;
293         uid_t target_uid = -1;
294         int ret = 0;
295         GList *dir_list = NULL;
296         GList *list = NULL;
297         app2ext_dir_details *dir_detail = NULL;
298
299         g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
300
301         _D("pkgid(%s), size(%d), sender_uid(%d), target_uid(%d)",
302                 pkgid, size, sender_uid, target_uid);
303
304         if (sender_uid != 0 && sender_uid != target_uid) {
305                 _E("Not permitted user!");
306                 g_variant_iter_free(iter);
307                 _app2sd_server_return_method_error(invocation,
308                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
309                 return;
310         }
311
312         while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
313                 if (str) {
314                         _D("str(%s), type(%d)", str, type);
315
316                         /* generate dir_list */
317                         dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
318                         if (dir_detail == NULL) {
319                                 _E("memory allocation failed");
320                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
321                                 break;
322                         }
323
324                         dir_detail->name = strdup((char *)str);
325                         if (dir_detail->name == NULL) {
326                                 _E("out of memory");
327                                 free(dir_detail);
328                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
329                                 break;
330                         }
331
332                         dir_detail->type = type;
333                         list = g_list_append(list, dir_detail);
334                 }
335         }
336         g_variant_iter_free(iter);
337
338         dir_list = g_list_first(list);
339         ret = app2sd_usr_pre_app_upgrade(pkgid, dir_list, size, target_uid);
340         if (ret) {
341                 _E("error(%d)", ret);
342                 result = ret;
343         }
344
345         param = g_variant_new("(i)", result);
346         g_dbus_method_invocation_return_value(invocation, param);
347 }
348
349 static void _app2sd_server_post_app_upgrade(GDBusConnection *connection, const gchar *sender,
350         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
351 {
352         GVariant *param = NULL;
353         int result = APP2EXT_SUCCESS;
354         char *pkgid = NULL;
355         int install_status = 0;
356         uid_t target_uid = -1;
357         int ret = 0;
358
359         g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
360
361         _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
362                 pkgid, install_status, sender_uid, target_uid);
363
364         if (sender_uid != 0 && sender_uid != target_uid) {
365                 _E("Not permitted user!");
366                 _app2sd_server_return_method_error(invocation,
367                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
368                 return;
369         }
370
371         ret = app2sd_usr_post_app_upgrade(pkgid, install_status, target_uid);
372         if (ret) {
373                 _E("error(%d)", ret);
374                 result = ret;
375         }
376
377         param = g_variant_new("(i)", result);
378         g_dbus_method_invocation_return_value(invocation, param);
379 }
380
381 static void _app2sd_server_pre_app_uninstall(GDBusConnection *connection, const gchar *sender,
382         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
383 {
384         GVariant *param = NULL;
385         int result = APP2EXT_SUCCESS;
386         char *pkgid = NULL;
387         uid_t target_uid = -1;
388         int ret = 0;
389
390         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
391
392         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
393                 pkgid, sender_uid, target_uid);
394
395         if (sender_uid != 0 && sender_uid != target_uid) {
396                 _E("Not permitted user!");
397                 _app2sd_server_return_method_error(invocation,
398                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
399                 return;
400         }
401
402         ret = app2sd_usr_pre_app_uninstall(pkgid, target_uid);
403         if (ret) {
404                 _E("error(%d)", ret);
405                 result = ret;
406         }
407
408         param = g_variant_new("(i)", result);
409         g_dbus_method_invocation_return_value(invocation, param);
410 }
411
412 static void _app2sd_server_post_app_uninstall(GDBusConnection *connection, const gchar *sender,
413         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
414 {
415         GVariant *param = NULL;
416         int result = APP2EXT_SUCCESS;
417         char *pkgid = NULL;
418         uid_t target_uid = -1;
419         int ret = 0;
420
421         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
422
423         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
424                 pkgid, sender_uid, target_uid);
425
426         if (sender_uid != 0 && sender_uid != target_uid) {
427                 _E("Not permitted user!");
428                 _app2sd_server_return_method_error(invocation,
429                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
430                 return;
431         }
432
433         ret = app2sd_usr_post_app_uninstall(pkgid, target_uid);
434         if (ret) {
435                 _E("error(%d)", ret);
436                 result = ret;
437         }
438
439         param = g_variant_new("(i)", result);
440         g_dbus_method_invocation_return_value(invocation, param);
441 }
442
443 static void _app2sd_server_ondemand_setup_init(GDBusConnection *connection, const gchar *sender,
444         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
445 {
446         GVariant *param = NULL;
447         int result = APP2EXT_SUCCESS;
448         char *pkgid = NULL;
449         uid_t target_uid = -1;
450         int ret = 0;
451
452         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
453
454         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
455                 pkgid, sender_uid, target_uid);
456
457         if (sender_uid != 0 && sender_uid != target_uid) {
458                 _E("Not permitted user!");
459                 _app2sd_server_return_method_error(invocation,
460                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
461                 return;
462         }
463
464         ret = app2sd_usr_on_demand_setup_init(pkgid, target_uid);
465         if (ret) {
466                 _E("error(%d)", ret);
467                 result = ret;
468         }
469
470         param = g_variant_new("(i)", result);
471         g_dbus_method_invocation_return_value(invocation, param);
472 }
473
474 static void _app2sd_server_ondemand_setup_exit(GDBusConnection *connection, const gchar *sender,
475         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
476 {
477         GVariant *param = NULL;
478         int result = APP2EXT_SUCCESS;
479         char *pkgid = NULL;
480         uid_t target_uid = -1;
481         int ret = 0;
482
483         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
484
485         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
486                 pkgid, sender_uid, target_uid);
487
488         if (sender_uid != 0 && sender_uid != target_uid) {
489                 _E("Not permitted user!");
490                 _app2sd_server_return_method_error(invocation,
491                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
492                 return;
493         }
494
495         ret = app2sd_usr_on_demand_setup_exit(pkgid, target_uid);
496         if (ret) {
497                 _E("error(%d)", ret);
498                 result = ret;
499         }
500
501         param = g_variant_new("(i)", result);
502         g_dbus_method_invocation_return_value(invocation, param);
503 }
504
505 static void _app2sd_server_move_installed_app(GDBusConnection *connection, const gchar *sender,
506         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
507 {
508         GVariant *param = NULL;
509         int result = APP2EXT_SUCCESS;
510         int move_type;
511         char *pkgid = NULL;
512         GVariantIter *iter;
513         gchar *str = NULL;
514         int type;
515         int ret = 0;
516         uid_t target_uid = -1;
517         GList *dir_list = NULL;
518         GList *list = NULL;
519         app2ext_dir_details *dir_detail = NULL;
520
521         g_variant_get(parameters, "(&sia(si)i)", &pkgid, &move_type, &iter, &target_uid);
522
523         _D("pkgid(%s), move_type(%d),sender_uid(%d), target_uid(%d)",
524                 pkgid, move_type, sender_uid, target_uid);
525
526         if (sender_uid != 0 && sender_uid != target_uid) {
527                 _E("Not permitted user!");
528                 g_variant_iter_free(iter);
529                 _app2sd_server_return_method_error(invocation,
530                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
531                 return;
532         }
533
534         while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
535                 if (str) {
536                         _D("str(%s), type(%d)", str, type);
537
538                         /* generate dir_list */
539                         dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
540                         if (dir_detail == NULL) {
541                                 _E("memory allocation failed");
542                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
543                                 break;
544                         }
545
546                         dir_detail->name = strdup((char *)str);
547                         if (dir_detail->name == NULL) {
548                                 _E("out of memory");
549                                 free(dir_detail);
550                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
551                                 break;
552                         }
553
554                         dir_detail->type = type;
555                         list = g_list_append(list, dir_detail);
556                 }
557         }
558         g_variant_iter_free(iter);
559
560         dir_list = g_list_first(list);
561         ret = app2sd_usr_move_installed_app(pkgid, dir_list, move_type, target_uid);
562         if (ret) {
563                 _E("usr_move error(%d)", ret);
564                 result = ret;
565         }
566
567         param = g_variant_new("(i)", result);
568         g_dbus_method_invocation_return_value(invocation, param);
569 }
570
571 static void _app2sd_server_ondemand_force_clean(GDBusConnection *connection, const gchar *sender,
572         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
573 {
574         GVariant *param = NULL;
575         int result = APP2EXT_SUCCESS;
576         char *pkgid = NULL;
577         uid_t target_uid = -1;
578         int ret = 0;
579
580         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
581
582         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
583                 pkgid, sender_uid, target_uid);
584
585         if (sender_uid != 0 && sender_uid != target_uid) {
586                 _E("Not permitted user!");
587                 _app2sd_server_return_method_error(invocation,
588                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
589                 return;
590         }
591
592         ret = app2sd_usr_force_clean(pkgid, target_uid);
593         if (ret) {
594                 _E("error(%d)", ret);
595                 result = ret;
596         }
597
598         param = g_variant_new("(i)", result);
599         g_dbus_method_invocation_return_value(invocation, param);
600 }
601
602 static void handle_method_call(GDBusConnection *connection,
603         const gchar *sender, const gchar *object_path,
604         const gchar *interface_name, const gchar *method_name,
605         GVariant *parameters, GDBusMethodInvocation *invocation,
606         gpointer user_data)
607 {
608         uid_t sender_uid = -1;
609
610         sender_uid = (uid_t)__app2sd_get_sender_uid(connection, sender);
611
612         if (g_strcmp0(method_name, "PreAppInstall") == 0) {
613                 _app2sd_server_pre_app_install(connection, sender,
614                         parameters, invocation, sender_uid);
615         } else if (g_strcmp0(method_name, "PostAppInstall") == 0) {
616                 _app2sd_server_post_app_install(connection, sender,
617                         parameters, invocation, sender_uid);
618         } else if (g_strcmp0(method_name, "PreAppUpgrade") == 0) {
619                 _app2sd_server_pre_app_upgrade(connection, sender,
620                         parameters, invocation, sender_uid);
621         } else if (g_strcmp0(method_name, "PostAppUpgrade") == 0) {
622                 _app2sd_server_post_app_upgrade(connection, sender,
623                         parameters, invocation, sender_uid);
624         } else if (g_strcmp0(method_name, "PreAppUninstall") == 0) {
625                 _app2sd_server_pre_app_uninstall(connection, sender,
626                         parameters, invocation, sender_uid);
627         } else if (g_strcmp0(method_name, "PostAppUninstall") == 0) {
628                 _app2sd_server_post_app_uninstall(connection, sender,
629                         parameters, invocation, sender_uid);
630         } else if (g_strcmp0(method_name, "OndemandSetupInit") == 0) {
631                 _app2sd_server_ondemand_setup_init(connection, sender,
632                         parameters, invocation, sender_uid);
633         } else if (g_strcmp0(method_name, "OndemandSetupExit") == 0) {
634                 _app2sd_server_ondemand_setup_exit(connection, sender,
635                         parameters, invocation, sender_uid);
636         } else if (g_strcmp0(method_name, "MoveInstalledApp") == 0) {
637                 _app2sd_server_move_installed_app(connection, sender,
638                         parameters, invocation, sender_uid);
639         } else if (g_strcmp0(method_name, "ForceClean") == 0) {
640                 _app2sd_server_ondemand_force_clean(connection, sender,
641                         parameters, invocation, sender_uid);
642         }
643
644         g_timeout_add_seconds(5, __exit_app2sd_server, NULL);
645 }
646
647 static const GDBusInterfaceVTable interface_vtable = {
648         handle_method_call,
649         NULL,
650         NULL
651 };
652
653 static void __app2sd_on_bus_acquired(GDBusConnection *connection,
654                 const gchar *name, gpointer user_data)
655 {
656         _I("bus acquired(%s)", name);
657
658         guint reg_id = 0;
659         GError *error = NULL;
660
661         reg_id = g_dbus_connection_register_object(connection,
662                 APP2SD_OBJECT_PATH,
663                 introspection_data->interfaces[0],
664                 &interface_vtable,
665                 NULL, NULL, &error);
666         if (reg_id == 0) {
667                 _E("g_dbus_connection_register_object error(%s)", error->message);
668                 g_error_free(error);
669         }
670 }
671
672 static void __app2sd_on_name_acquired(GDBusConnection *connection,
673                 const gchar *name, gpointer user_data)
674 {
675         _I("name acquired(%s)", name);
676 }
677
678 static void __app2sd_on_name_lost(GDBusConnection *connection,
679                 const gchar *name, gpointer user_data)
680 {
681         _E("name lost(%s)", name);
682         g_main_loop_quit(app2sd_mainloop);
683 }
684
685 static int __app2sd_server_init()
686 {
687         GError *error = NULL;
688         guint owner_id = 0;
689
690         /* gdbus setup for method call */
691         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
692         if (!introspection_data) {
693                 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
694                 g_error_free(error);
695                 return -1;
696         }
697
698         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
699                 APP2SD_BUS_NAME,
700                 G_BUS_NAME_OWNER_FLAGS_NONE,
701                 __app2sd_on_bus_acquired,
702                 __app2sd_on_name_acquired,
703                 __app2sd_on_name_lost,
704                 NULL, NULL);
705         if (!owner_id) {
706                 _E("g_bus_own_name error");
707                 g_dbus_node_info_unref(introspection_data);
708                 return -1;
709         }
710
711         /* add timer */
712
713         return 0;
714 }
715
716 static void __app2sd_finalize(void)
717 {
718         _D("app2sd finalize");
719
720         if (introspection_data)
721                 g_dbus_node_info_unref(introspection_data);
722
723         _D("app2sd finalize end");
724 }
725
726 int main(int argc, char *argv[])
727 {
728         int ret = 0;
729
730         _I("app2sd_server : start");
731
732         ret = __app2sd_server_init();
733         if (ret) {
734                 _E("app2sd_server init failed(%d)", ret);
735                 return -1;
736         }
737
738         app2sd_mainloop = g_main_loop_new(NULL, FALSE);
739         if (!app2sd_mainloop) {
740                 _E("g_main_loop_new failed");
741                 return -1;
742         }
743
744         g_main_loop_run(app2sd_mainloop);
745
746         __app2sd_finalize();
747
748         _I("app2sd_server : end");
749
750         return 0;
751 }