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