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'/>"
172 static void _app2sd_server_return_method_error(GDBusMethodInvocation *invocation, int result)
174 GVariant *param = NULL;
176 param = g_variant_new("(i)", result);
177 g_dbus_method_invocation_return_value(invocation, param);
180 static void _app2sd_server_pre_app_install(GDBusConnection *connection, const gchar *sender,
181 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
183 GVariant *param = NULL;
184 int result = APP2EXT_SUCCESS;
191 uid_t target_uid = -1;
192 GList *dir_list = NULL;
194 app2ext_dir_details *dir_detail = NULL;
196 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
198 _D("pkgid(%s), size(%d),sender_uid(%d), target_uid(%d)",
199 pkgid, size, sender_uid, target_uid);
201 if (sender_uid != 0 && sender_uid != target_uid) {
202 _E("Not permitted user!");
203 g_variant_iter_free(iter);
204 _app2sd_server_return_method_error(invocation,
205 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
209 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
211 _D("str(%s), type(%d)", str, type);
213 /* generate dir_list */
214 dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
215 if (dir_detail == NULL) {
216 _E("memory allocation failed");
217 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
221 dir_detail->name = strdup((char *)str);
222 if (dir_detail->name == NULL) {
225 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
229 dir_detail->type = type;
230 list = g_list_append(list, dir_detail);
233 g_variant_iter_free(iter);
235 dir_list = g_list_first(list);
236 ret = app2sd_usr_pre_app_install(pkgid, dir_list, size, target_uid);
238 _E("error(%d)", ret);
242 param = g_variant_new("(i)", result);
243 g_dbus_method_invocation_return_value(invocation, param);
246 static void _app2sd_server_post_app_install(GDBusConnection *connection, const gchar *sender,
247 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
249 GVariant *param = NULL;
250 int result = APP2EXT_SUCCESS;
252 int install_status = 0;
256 g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
258 _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
259 pkgid, install_status, sender_uid, target_uid);
261 if (sender_uid != 0 && sender_uid != target_uid) {
262 _E("Not permitted user!");
263 _app2sd_server_return_method_error(invocation,
264 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
268 ret = app2sd_usr_post_app_install(pkgid, install_status, target_uid);
270 _E("error(%d)", ret);
274 param = g_variant_new("(i)", result);
275 g_dbus_method_invocation_return_value(invocation, param);
278 static void _app2sd_server_pre_app_upgrade(GDBusConnection *connection, const gchar *sender,
279 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
281 GVariant *param = NULL;
282 int result = APP2EXT_SUCCESS;
288 uid_t target_uid = -1;
290 GList *dir_list = NULL;
292 app2ext_dir_details *dir_detail = NULL;
294 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
296 _D("pkgid(%s), size(%d), sender_uid(%d), target_uid(%d)",
297 pkgid, size, sender_uid, target_uid);
299 if (sender_uid != 0 && sender_uid != target_uid) {
300 _E("Not permitted user!");
301 g_variant_iter_free(iter);
302 _app2sd_server_return_method_error(invocation,
303 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
307 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
309 _D("str(%s), type(%d)", str, type);
311 /* generate dir_list */
312 dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
313 if (dir_detail == NULL) {
314 _E("memory allocation failed");
315 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
319 dir_detail->name = strdup((char *)str);
320 if (dir_detail->name == NULL) {
323 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
327 dir_detail->type = type;
328 list = g_list_append(list, dir_detail);
331 g_variant_iter_free(iter);
333 dir_list = g_list_first(list);
334 ret = app2sd_usr_pre_app_upgrade(pkgid, dir_list, size, target_uid);
336 _E("error(%d)", ret);
340 param = g_variant_new("(i)", result);
341 g_dbus_method_invocation_return_value(invocation, param);
344 static void _app2sd_server_post_app_upgrade(GDBusConnection *connection, const gchar *sender,
345 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
347 GVariant *param = NULL;
348 int result = APP2EXT_SUCCESS;
350 int install_status = 0;
351 uid_t target_uid = -1;
354 g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
356 _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
357 pkgid, install_status, sender_uid, target_uid);
359 if (sender_uid != 0 && sender_uid != target_uid) {
360 _E("Not permitted user!");
361 _app2sd_server_return_method_error(invocation,
362 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
366 ret = app2sd_usr_post_app_upgrade(pkgid, install_status, target_uid);
368 _E("error(%d)", ret);
372 param = g_variant_new("(i)", result);
373 g_dbus_method_invocation_return_value(invocation, param);
376 static void _app2sd_server_pre_app_uninstall(GDBusConnection *connection, const gchar *sender,
377 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
379 GVariant *param = NULL;
380 int result = APP2EXT_SUCCESS;
382 uid_t target_uid = -1;
385 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
387 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
388 pkgid, sender_uid, target_uid);
390 if (sender_uid != 0 && sender_uid != target_uid) {
391 _E("Not permitted user!");
392 _app2sd_server_return_method_error(invocation,
393 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
397 ret = app2sd_usr_pre_app_uninstall(pkgid, target_uid);
399 _E("error(%d)", ret);
403 param = g_variant_new("(i)", result);
404 g_dbus_method_invocation_return_value(invocation, param);
407 static void _app2sd_server_post_app_uninstall(GDBusConnection *connection, const gchar *sender,
408 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
410 GVariant *param = NULL;
411 int result = APP2EXT_SUCCESS;
413 uid_t target_uid = -1;
416 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
418 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
419 pkgid, sender_uid, target_uid);
421 if (sender_uid != 0 && sender_uid != target_uid) {
422 _E("Not permitted user!");
423 _app2sd_server_return_method_error(invocation,
424 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
428 ret = app2sd_usr_post_app_uninstall(pkgid, target_uid);
430 _E("error(%d)", ret);
434 param = g_variant_new("(i)", result);
435 g_dbus_method_invocation_return_value(invocation, param);
438 static void _app2sd_server_ondemand_setup_init(GDBusConnection *connection, const gchar *sender,
439 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
441 GVariant *param = NULL;
442 int result = APP2EXT_SUCCESS;
444 uid_t target_uid = -1;
447 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
449 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
450 pkgid, sender_uid, target_uid);
452 if (sender_uid != 0 && sender_uid != target_uid) {
453 _E("Not permitted user!");
454 _app2sd_server_return_method_error(invocation,
455 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
459 ret = app2sd_usr_on_demand_setup_init(pkgid, target_uid);
461 _E("error(%d)", ret);
465 param = g_variant_new("(i)", result);
466 g_dbus_method_invocation_return_value(invocation, param);
469 static void _app2sd_server_ondemand_setup_exit(GDBusConnection *connection, const gchar *sender,
470 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
472 GVariant *param = NULL;
473 int result = APP2EXT_SUCCESS;
475 uid_t target_uid = -1;
478 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
480 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
481 pkgid, sender_uid, target_uid);
483 if (sender_uid != 0 && sender_uid != target_uid) {
484 _E("Not permitted user!");
485 _app2sd_server_return_method_error(invocation,
486 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
490 ret = app2sd_usr_on_demand_setup_exit(pkgid, target_uid);
492 _E("error(%d)", ret);
496 param = g_variant_new("(i)", result);
497 g_dbus_method_invocation_return_value(invocation, param);
500 static void _app2sd_server_move_installed_app(GDBusConnection *connection, const gchar *sender,
501 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
503 GVariant *param = NULL;
504 int result = APP2EXT_SUCCESS;
511 uid_t target_uid = -1;
512 GList *dir_list = NULL;
514 app2ext_dir_details *dir_detail = NULL;
516 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &move_type, &iter, &target_uid);
518 _D("pkgid(%s), move_type(%d),sender_uid(%d), target_uid(%d)",
519 pkgid, move_type, sender_uid, target_uid);
521 if (sender_uid != 0 && sender_uid != target_uid) {
522 _E("Not permitted user!");
523 g_variant_iter_free(iter);
524 _app2sd_server_return_method_error(invocation,
525 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
529 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
531 _D("str(%s), type(%d)", str, type);
533 /* generate dir_list */
534 dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
535 if (dir_detail == NULL) {
536 _E("memory allocation failed");
537 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
541 dir_detail->name = strdup((char *)str);
542 if (dir_detail->name == NULL) {
545 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
549 dir_detail->type = type;
550 list = g_list_append(list, dir_detail);
553 g_variant_iter_free(iter);
555 dir_list = g_list_first(list);
556 ret = app2sd_usr_move_installed_app(pkgid, dir_list, move_type, target_uid);
558 _E("usr_move error(%d)", ret);
562 param = g_variant_new("(i)", result);
563 g_dbus_method_invocation_return_value(invocation, param);
566 static void handle_method_call(GDBusConnection *connection,
567 const gchar *sender, const gchar *object_path,
568 const gchar *interface_name, const gchar *method_name,
569 GVariant *parameters, GDBusMethodInvocation *invocation,
572 uid_t sender_uid = -1;
574 sender_uid = (uid_t)__app2sd_get_sender_uid(connection, sender);
576 if (g_strcmp0(method_name, "PreAppInstall") == 0) {
577 _app2sd_server_pre_app_install(connection, sender,
578 parameters, invocation, sender_uid);
579 } else if (g_strcmp0(method_name, "PostAppInstall") == 0) {
580 _app2sd_server_post_app_install(connection, sender,
581 parameters, invocation, sender_uid);
582 } else if (g_strcmp0(method_name, "PreAppUpgrade") == 0) {
583 _app2sd_server_pre_app_upgrade(connection, sender,
584 parameters, invocation, sender_uid);
585 } else if (g_strcmp0(method_name, "PostAppUpgrade") == 0) {
586 _app2sd_server_post_app_upgrade(connection, sender,
587 parameters, invocation, sender_uid);
588 } else if (g_strcmp0(method_name, "PreAppUninstall") == 0) {
589 _app2sd_server_pre_app_uninstall(connection, sender,
590 parameters, invocation, sender_uid);
591 } else if (g_strcmp0(method_name, "PostAppUninstall") == 0) {
592 _app2sd_server_post_app_uninstall(connection, sender,
593 parameters, invocation, sender_uid);
594 } else if (g_strcmp0(method_name, "OndemandSetupInit") == 0) {
595 _app2sd_server_ondemand_setup_init(connection, sender,
596 parameters, invocation, sender_uid);
597 } else if (g_strcmp0(method_name, "OndemandSetupExit") == 0) {
598 _app2sd_server_ondemand_setup_exit(connection, sender,
599 parameters, invocation, sender_uid);
600 } else if (g_strcmp0(method_name, "MoveInstalledApp") == 0) {
601 _app2sd_server_move_installed_app(connection, sender,
602 parameters, invocation, sender_uid);
605 g_timeout_add_seconds(5, __exit_app2sd_server, NULL);
608 static const GDBusInterfaceVTable interface_vtable = {
614 static void __app2sd_on_bus_acquired(GDBusConnection *connection,
615 const gchar *name, gpointer user_data)
617 _I("bus acquired(%s)", name);
620 GError *error = NULL;
622 reg_id = g_dbus_connection_register_object(connection,
624 introspection_data->interfaces[0],
628 _E("g_dbus_connection_register_object error(%s)", error->message);
633 static void __app2sd_on_name_acquired(GDBusConnection *connection,
634 const gchar *name, gpointer user_data)
636 _I("name acquired(%s)", name);
639 static void __app2sd_on_name_lost(GDBusConnection *connection,
640 const gchar *name, gpointer user_data)
642 _E("name lost(%s)", name);
645 static int __app2sd_server_init()
647 GError *error = NULL;
650 /* gdbus setup for method call */
651 introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
652 if (!introspection_data) {
653 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
658 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
660 G_BUS_NAME_OWNER_FLAGS_NONE,
661 __app2sd_on_bus_acquired,
662 __app2sd_on_name_acquired,
663 __app2sd_on_name_lost,
666 _E("g_bus_own_name error");
667 g_dbus_node_info_unref(introspection_data);
676 static void __app2sd_finalize(void)
678 _D("app2sd finalize");
680 if (introspection_data)
681 g_dbus_node_info_unref(introspection_data);
683 _D("app2sd finalize end");
686 int main(int argc, char *argv[])
690 _I("app2sd_server : start");
692 ret = __app2sd_server_init();
694 _E("app2sd_server init failed(%d)", ret);
698 app2sd_mainloop = g_main_loop_new(NULL, FALSE);
699 if (!app2sd_mainloop) {
700 _E("g_main_loop_new failed");
704 g_main_loop_run(app2sd_mainloop);
708 _I("app2sd_server : end");