4 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include "app2sd_internals.h"
24 GMainLoop *app2sd_mainloop = NULL;
26 gboolean __exit_app2sd_server(void *data)
28 _D("exit app2sd_server");
30 g_main_loop_quit(app2sd_mainloop);
35 static int __app2sd_get_sender_unixinfo(GDBusConnection *conn,
36 const char *sender_name, const char *type)
38 GDBusMessage *msg = NULL;
39 GDBusMessage *reply = NULL;
45 msg = g_dbus_message_new_method_call("org.freedesktop.DBus",
46 "/org/freedesktop/DBus", "org.freedesktop.DBus", type);
48 _E("Can't allocate new method call");
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);
58 _E("Failed to get info [%s]", err->message);
64 body = g_dbus_message_get_body(reply);
65 g_variant_get(body, "(u)", &value);
72 g_object_unref(reply);
78 static int __app2sd_get_sender_pid(GDBusConnection *conn,
79 const char *sender_name)
83 pid = __app2sd_get_sender_unixinfo(conn, sender_name,
84 "GetConnectionUnixProcessID");
86 _E("failed to get pid");
90 _D("sender_name(%s), pid(%d)", sender_name, pid);
96 static int __app2sd_get_sender_uid(GDBusConnection *conn,
97 const char *sender_name)
101 uid = __app2sd_get_sender_unixinfo(conn, sender_name,
102 "GetConnectionUnixUser");
104 _E("failed to get uid");
107 _D("sender_name(%s), uid(%d)", sender_name, uid);
112 static GDBusNodeInfo *introspection_data;
113 static const gchar introspection_xml[] =
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
177 static void _app2sd_server_return_method_error(GDBusMethodInvocation *invocation, int result)
179 GVariant *param = NULL;
181 param = g_variant_new("(i)", result);
182 g_dbus_method_invocation_return_value(invocation, param);
185 static void _app2sd_server_pre_app_install(GDBusConnection *connection, const gchar *sender,
186 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
188 GVariant *param = NULL;
189 int result = APP2EXT_SUCCESS;
196 uid_t target_uid = -1;
197 GList *dir_list = NULL;
199 app2ext_dir_details *dir_detail = NULL;
201 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
203 _D("pkgid(%s), size(%d),sender_uid(%d), target_uid(%d)",
204 pkgid, size, sender_uid, target_uid);
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);
214 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
216 _D("str(%s), type(%d)", str, type);
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;
226 dir_detail->name = strdup((char *)str);
227 if (dir_detail->name == NULL) {
230 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
234 dir_detail->type = type;
235 list = g_list_append(list, dir_detail);
238 g_variant_iter_free(iter);
240 dir_list = g_list_first(list);
241 ret = app2sd_usr_pre_app_install(pkgid, dir_list, size, target_uid);
243 _E("error(%d)", ret);
247 param = g_variant_new("(i)", result);
248 g_dbus_method_invocation_return_value(invocation, param);
251 static void _app2sd_server_post_app_install(GDBusConnection *connection, const gchar *sender,
252 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
254 GVariant *param = NULL;
255 int result = APP2EXT_SUCCESS;
257 int install_status = 0;
261 g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
263 _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
264 pkgid, install_status, sender_uid, target_uid);
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);
273 ret = app2sd_usr_post_app_install(pkgid, install_status, target_uid);
275 _E("error(%d)", ret);
279 param = g_variant_new("(i)", result);
280 g_dbus_method_invocation_return_value(invocation, param);
283 static void _app2sd_server_pre_app_upgrade(GDBusConnection *connection, const gchar *sender,
284 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
286 GVariant *param = NULL;
287 int result = APP2EXT_SUCCESS;
293 uid_t target_uid = -1;
295 GList *dir_list = NULL;
297 app2ext_dir_details *dir_detail = NULL;
299 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
301 _D("pkgid(%s), size(%d), sender_uid(%d), target_uid(%d)",
302 pkgid, size, sender_uid, target_uid);
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);
312 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
314 _D("str(%s), type(%d)", str, type);
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;
324 dir_detail->name = strdup((char *)str);
325 if (dir_detail->name == NULL) {
328 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
332 dir_detail->type = type;
333 list = g_list_append(list, dir_detail);
336 g_variant_iter_free(iter);
338 dir_list = g_list_first(list);
339 ret = app2sd_usr_pre_app_upgrade(pkgid, dir_list, size, target_uid);
341 _E("error(%d)", ret);
345 param = g_variant_new("(i)", result);
346 g_dbus_method_invocation_return_value(invocation, param);
349 static void _app2sd_server_post_app_upgrade(GDBusConnection *connection, const gchar *sender,
350 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
352 GVariant *param = NULL;
353 int result = APP2EXT_SUCCESS;
355 int install_status = 0;
356 uid_t target_uid = -1;
359 g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
361 _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
362 pkgid, install_status, sender_uid, target_uid);
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);
371 ret = app2sd_usr_post_app_upgrade(pkgid, install_status, target_uid);
373 _E("error(%d)", ret);
377 param = g_variant_new("(i)", result);
378 g_dbus_method_invocation_return_value(invocation, param);
381 static void _app2sd_server_pre_app_uninstall(GDBusConnection *connection, const gchar *sender,
382 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
384 GVariant *param = NULL;
385 int result = APP2EXT_SUCCESS;
387 uid_t target_uid = -1;
390 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
392 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
393 pkgid, sender_uid, target_uid);
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);
402 ret = app2sd_usr_pre_app_uninstall(pkgid, target_uid);
404 _E("error(%d)", ret);
408 param = g_variant_new("(i)", result);
409 g_dbus_method_invocation_return_value(invocation, param);
412 static void _app2sd_server_post_app_uninstall(GDBusConnection *connection, const gchar *sender,
413 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
415 GVariant *param = NULL;
416 int result = APP2EXT_SUCCESS;
418 uid_t target_uid = -1;
421 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
423 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
424 pkgid, sender_uid, target_uid);
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);
433 ret = app2sd_usr_post_app_uninstall(pkgid, target_uid);
435 _E("error(%d)", ret);
439 param = g_variant_new("(i)", result);
440 g_dbus_method_invocation_return_value(invocation, param);
443 static void _app2sd_server_ondemand_setup_init(GDBusConnection *connection, const gchar *sender,
444 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
446 GVariant *param = NULL;
447 int result = APP2EXT_SUCCESS;
449 uid_t target_uid = -1;
452 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
454 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
455 pkgid, sender_uid, target_uid);
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);
464 ret = app2sd_usr_on_demand_setup_init(pkgid, target_uid);
466 _E("error(%d)", ret);
470 param = g_variant_new("(i)", result);
471 g_dbus_method_invocation_return_value(invocation, param);
474 static void _app2sd_server_ondemand_setup_exit(GDBusConnection *connection, const gchar *sender,
475 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
477 GVariant *param = NULL;
478 int result = APP2EXT_SUCCESS;
480 uid_t target_uid = -1;
483 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
485 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
486 pkgid, sender_uid, target_uid);
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);
495 ret = app2sd_usr_on_demand_setup_exit(pkgid, target_uid);
497 _E("error(%d)", ret);
501 param = g_variant_new("(i)", result);
502 g_dbus_method_invocation_return_value(invocation, param);
505 static void _app2sd_server_move_installed_app(GDBusConnection *connection, const gchar *sender,
506 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
508 GVariant *param = NULL;
509 int result = APP2EXT_SUCCESS;
516 uid_t target_uid = -1;
517 GList *dir_list = NULL;
519 app2ext_dir_details *dir_detail = NULL;
521 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &move_type, &iter, &target_uid);
523 _D("pkgid(%s), move_type(%d),sender_uid(%d), target_uid(%d)",
524 pkgid, move_type, sender_uid, target_uid);
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);
534 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
536 _D("str(%s), type(%d)", str, type);
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;
546 dir_detail->name = strdup((char *)str);
547 if (dir_detail->name == NULL) {
550 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
554 dir_detail->type = type;
555 list = g_list_append(list, dir_detail);
558 g_variant_iter_free(iter);
560 dir_list = g_list_first(list);
561 ret = app2sd_usr_move_installed_app(pkgid, dir_list, move_type, target_uid);
563 _E("usr_move error(%d)", ret);
567 param = g_variant_new("(i)", result);
568 g_dbus_method_invocation_return_value(invocation, param);
571 static void _app2sd_server_ondemand_force_clean(GDBusConnection *connection, const gchar *sender,
572 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
574 GVariant *param = NULL;
575 int result = APP2EXT_SUCCESS;
577 uid_t target_uid = -1;
580 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
582 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
583 pkgid, sender_uid, target_uid);
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);
592 ret = app2sd_usr_force_clean(pkgid, target_uid);
594 _E("error(%d)", ret);
598 param = g_variant_new("(i)", result);
599 g_dbus_method_invocation_return_value(invocation, param);
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,
608 uid_t sender_uid = -1;
610 sender_uid = (uid_t)__app2sd_get_sender_uid(connection, sender);
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);
644 g_timeout_add_seconds(5, __exit_app2sd_server, NULL);
647 static const GDBusInterfaceVTable interface_vtable = {
653 static void __app2sd_on_bus_acquired(GDBusConnection *connection,
654 const gchar *name, gpointer user_data)
656 _I("bus acquired(%s)", name);
659 GError *error = NULL;
661 reg_id = g_dbus_connection_register_object(connection,
663 introspection_data->interfaces[0],
667 _E("g_dbus_connection_register_object error(%s)", error->message);
672 static void __app2sd_on_name_acquired(GDBusConnection *connection,
673 const gchar *name, gpointer user_data)
675 _I("name acquired(%s)", name);
678 static void __app2sd_on_name_lost(GDBusConnection *connection,
679 const gchar *name, gpointer user_data)
681 _E("name lost(%s)", name);
682 g_main_loop_quit(app2sd_mainloop);
685 static int __app2sd_server_init()
687 GError *error = NULL;
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);
698 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
700 G_BUS_NAME_OWNER_FLAGS_NONE,
701 __app2sd_on_bus_acquired,
702 __app2sd_on_name_acquired,
703 __app2sd_on_name_lost,
706 _E("g_bus_own_name error");
707 g_dbus_node_info_unref(introspection_data);
716 static void __app2sd_finalize(void)
718 _D("app2sd finalize");
720 if (introspection_data)
721 g_dbus_node_info_unref(introspection_data);
723 _D("app2sd finalize end");
726 int main(int argc, char *argv[])
730 _I("app2sd_server : start");
732 ret = __app2sd_server_init();
734 _E("app2sd_server init failed(%d)", ret);
738 app2sd_mainloop = g_main_loop_new(NULL, FALSE);
739 if (!app2sd_mainloop) {
740 _E("g_main_loop_new failed");
744 g_main_loop_run(app2sd_mainloop);
748 _I("app2sd_server : end");