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.
20 #include <app2sd_internals.h>
21 #include <app2sd_interface.h>
25 GMainLoop *app2sd_mainloop = NULL;
27 gboolean __exit_app2sd_server(void *data)
29 _D("exit app2sd_server");
31 g_main_loop_quit(app2sd_mainloop);
36 static int __app2sd_get_sender_unixinfo(GDBusConnection *conn,
37 const char *sender_name, const char *type)
39 GDBusMessage *msg = NULL;
40 GDBusMessage *reply = NULL;
46 msg = g_dbus_message_new_method_call("org.freedesktop.DBus",
47 "/org/freedesktop/DBus", "org.freedesktop.DBus", type);
49 _E("Can't allocate new method call");
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);
59 _E("Failed to get info [%s]", err->message);
65 body = g_dbus_message_get_body(reply);
66 g_variant_get(body, "(u)", &value);
73 g_object_unref(reply);
79 static int __app2sd_get_sender_pid(GDBusConnection *conn,
80 const char *sender_name)
84 pid = __app2sd_get_sender_unixinfo(conn, sender_name,
85 "GetConnectionUnixProcessID");
87 _E("failed to get pid");
91 _D("sender_name(%s), pid(%d)", sender_name, pid);
97 static int __app2sd_get_sender_uid(GDBusConnection *conn,
98 const char *sender_name)
102 uid = __app2sd_get_sender_unixinfo(conn, sender_name,
103 "GetConnectionUnixUser");
105 _E("failed to get uid");
108 _D("sender_name(%s), uid(%d)", sender_name, uid);
113 static GDBusNodeInfo *introspection_data;
114 static const gchar introspection_xml[] =
116 " <interface name='org.tizen.app2sd'>"
117 " <method name='PreAppInstall'>"
118 " <arg type='s' name='pkgid' direction='in'/>"
119 " <arg type='i' name='size' direction='in'/>"
120 " <arg type='a(si)' name='dir_list' direction='in'/>"
121 " <arg type='i' name='uid' direction='in'/>"
122 " <arg type='i' name='result' direction='out'/>"
124 " <method name='PostAppInstall'>"
125 " <arg type='s' name='pkgid' direction='in'/>"
126 " <arg type='i' name='install_status' direction='in'/>"
127 " <arg type='i' name='uid' direction='in'/>"
128 " <arg type='i' name='result' direction='out'/>"
130 " <method name='PreAppUpgrade'>"
131 " <arg type='s' name='pkgid' direction='in'/>"
132 " <arg type='i' name='size' direction='in'/>"
133 " <arg type='a(si)' name='dir_list' direction='in'/>"
134 " <arg type='i' name='uid' direction='in'/>"
135 " <arg type='i' name='result' direction='out'/>"
137 " <method name='PostAppUpgrade'>"
138 " <arg type='s' name='pkgid' direction='in'/>"
139 " <arg type='i' name='install_status' direction='in'/>"
140 " <arg type='i' name='uid' direction='in'/>"
141 " <arg type='i' name='result' direction='out'/>"
143 " <method name='PreAppUninstall'>"
144 " <arg type='s' name='pkgid' direction='in'/>"
145 " <arg type='i' name='uid' direction='in'/>"
146 " <arg type='i' name='result' direction='out'/>"
148 " <method name='PostAppUninstall'>"
149 " <arg type='s' name='pkgid' direction='in'/>"
150 " <arg type='i' name='uid' direction='in'/>"
151 " <arg type='i' name='result' direction='out'/>"
153 " <method name='OndemandSetupInit'>"
154 " <arg type='s' name='pkgid' direction='in'/>"
155 " <arg type='i' name='uid' direction='in'/>"
156 " <arg type='i' name='result' direction='out'/>"
158 " <method name='OndemandSetupExit'>"
159 " <arg type='s' name='pkgid' direction='in'/>"
160 " <arg type='i' name='uid' direction='in'/>"
161 " <arg type='i' name='result' direction='out'/>"
163 " <method name='MoveInstalledApp'>"
164 " <arg type='s' name='pkgid' direction='in'/>"
165 " <arg type='i' name='move_type' direction='in'/>"
166 " <arg type='a(si)' name='dir_list' direction='in'/>"
167 " <arg type='i' name='uid' direction='in'/>"
168 " <arg type='i' name='result' direction='out'/>"
173 static void _app2sd_server_return_method_error(GDBusMethodInvocation *invocation, int result)
175 GVariant *param = NULL;
177 param = g_variant_new("(i)", result);
178 g_dbus_method_invocation_return_value(invocation, param);
181 static void _app2sd_server_pre_app_install(GDBusConnection *connection, const gchar *sender,
182 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
184 GVariant *param = NULL;
185 int result = APP2EXT_SUCCESS;
192 uid_t target_uid = -1;
193 GList *dir_list = NULL;
195 app2ext_dir_details *dir_detail = NULL;
197 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
199 _D("pkgid(%s), size(%d),sender_uid(%d), target_uid(%d)",
200 pkgid, size, sender_uid, target_uid);
202 if (sender_uid != 0 && sender_uid != target_uid) {
203 _E("Not permitted user!");
204 g_variant_iter_free(iter);
205 _app2sd_server_return_method_error(invocation,
206 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
210 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
212 _D("str(%s), type(%d)", str, type);
214 /* generate dir_list */
215 dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
216 if (dir_detail == NULL) {
217 _E("memory allocation failed");
218 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
222 dir_detail->name = strdup((char *)str);
223 if (dir_detail->name == NULL) {
226 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
230 dir_detail->type = type;
231 list = g_list_append(list, dir_detail);
234 g_variant_iter_free(iter);
236 dir_list = g_list_first(list);
237 ret = app2sd_usr_pre_app_install(pkgid, dir_list, size, target_uid);
239 _E("error(%d)", ret);
243 param = g_variant_new("(i)", result);
244 g_dbus_method_invocation_return_value(invocation, param);
247 static void _app2sd_server_post_app_install(GDBusConnection *connection, const gchar *sender,
248 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
250 GVariant *param = NULL;
251 int result = APP2EXT_SUCCESS;
253 int install_status = 0;
257 g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
259 _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
260 pkgid, install_status, sender_uid, target_uid);
262 if (sender_uid != 0 && sender_uid != target_uid) {
263 _E("Not permitted user!");
264 _app2sd_server_return_method_error(invocation,
265 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
269 ret = app2sd_usr_post_app_install(pkgid, install_status, target_uid);
271 _E("error(%d)", ret);
275 param = g_variant_new("(i)", result);
276 g_dbus_method_invocation_return_value(invocation, param);
279 static void _app2sd_server_pre_app_upgrade(GDBusConnection *connection, const gchar *sender,
280 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
282 GVariant *param = NULL;
283 int result = APP2EXT_SUCCESS;
289 uid_t target_uid = -1;
291 GList *dir_list = NULL;
293 app2ext_dir_details *dir_detail = NULL;
295 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
297 _D("pkgid(%s), size(%d), sender_uid(%d), target_uid(%d)",
298 pkgid, size, sender_uid, target_uid);
300 if (sender_uid != 0 && sender_uid != target_uid) {
301 _E("Not permitted user!");
302 g_variant_iter_free(iter);
303 _app2sd_server_return_method_error(invocation,
304 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
308 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
310 _D("str(%s), type(%d)", str, type);
312 /* generate dir_list */
313 dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
314 if (dir_detail == NULL) {
315 _E("memory allocation failed");
316 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
320 dir_detail->name = strdup((char *)str);
321 if (dir_detail->name == NULL) {
324 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
328 dir_detail->type = type;
329 list = g_list_append(list, dir_detail);
332 g_variant_iter_free(iter);
334 dir_list = g_list_first(list);
335 ret = app2sd_usr_pre_app_upgrade(pkgid, dir_list, size, target_uid);
337 _E("error(%d)", ret);
341 param = g_variant_new("(i)", result);
342 g_dbus_method_invocation_return_value(invocation, param);
345 static void _app2sd_server_post_app_upgrade(GDBusConnection *connection, const gchar *sender,
346 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
348 GVariant *param = NULL;
349 int result = APP2EXT_SUCCESS;
351 int install_status = 0;
352 uid_t target_uid = -1;
355 g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
357 _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
358 pkgid, install_status, sender_uid, target_uid);
360 if (sender_uid != 0 && sender_uid != target_uid) {
361 _E("Not permitted user!");
362 _app2sd_server_return_method_error(invocation,
363 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
367 ret = app2sd_usr_post_app_upgrade(pkgid, install_status, target_uid);
369 _E("error(%d)", ret);
373 param = g_variant_new("(i)", result);
374 g_dbus_method_invocation_return_value(invocation, param);
377 static void _app2sd_server_pre_app_uninstall(GDBusConnection *connection, const gchar *sender,
378 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
380 GVariant *param = NULL;
381 int result = APP2EXT_SUCCESS;
383 uid_t target_uid = -1;
386 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
388 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
389 pkgid, sender_uid, target_uid);
391 if (sender_uid != 0 && sender_uid != target_uid) {
392 _E("Not permitted user!");
393 _app2sd_server_return_method_error(invocation,
394 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
398 ret = app2sd_usr_pre_app_uninstall(pkgid, target_uid);
400 _E("error(%d)", ret);
404 param = g_variant_new("(i)", result);
405 g_dbus_method_invocation_return_value(invocation, param);
408 static void _app2sd_server_post_app_uninstall(GDBusConnection *connection, const gchar *sender,
409 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
411 GVariant *param = NULL;
412 int result = APP2EXT_SUCCESS;
414 uid_t target_uid = -1;
417 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
419 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
420 pkgid, sender_uid, target_uid);
422 if (sender_uid != 0 && sender_uid != target_uid) {
423 _E("Not permitted user!");
424 _app2sd_server_return_method_error(invocation,
425 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
429 ret = app2sd_usr_post_app_uninstall(pkgid, target_uid);
431 _E("error(%d)", ret);
435 param = g_variant_new("(i)", result);
436 g_dbus_method_invocation_return_value(invocation, param);
439 static void _app2sd_server_ondemand_setup_init(GDBusConnection *connection, const gchar *sender,
440 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
442 GVariant *param = NULL;
443 int result = APP2EXT_SUCCESS;
445 uid_t target_uid = -1;
448 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
450 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
451 pkgid, sender_uid, target_uid);
453 if (sender_uid != 0 && sender_uid != target_uid) {
454 _E("Not permitted user!");
455 _app2sd_server_return_method_error(invocation,
456 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
460 ret = app2sd_usr_on_demand_setup_init(pkgid, target_uid);
462 _E("error(%d)", ret);
466 param = g_variant_new("(i)", result);
467 g_dbus_method_invocation_return_value(invocation, param);
470 static void _app2sd_server_ondemand_setup_exit(GDBusConnection *connection, const gchar *sender,
471 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
473 GVariant *param = NULL;
474 int result = APP2EXT_SUCCESS;
476 uid_t target_uid = -1;
479 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
481 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
482 pkgid, sender_uid, target_uid);
484 if (sender_uid != 0 && sender_uid != target_uid) {
485 _E("Not permitted user!");
486 _app2sd_server_return_method_error(invocation,
487 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
491 ret = app2sd_usr_on_demand_setup_exit(pkgid, target_uid);
493 _E("error(%d)", ret);
497 param = g_variant_new("(i)", result);
498 g_dbus_method_invocation_return_value(invocation, param);
501 static void _app2sd_server_move_installed_app(GDBusConnection *connection, const gchar *sender,
502 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
504 GVariant *param = NULL;
505 int result = APP2EXT_SUCCESS;
512 uid_t target_uid = -1;
513 GList *dir_list = NULL;
515 app2ext_dir_details *dir_detail = NULL;
517 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &move_type, &iter, &target_uid);
519 _D("pkgid(%s), move_type(%d),sender_uid(%d), target_uid(%d)",
520 pkgid, move_type, sender_uid, target_uid);
522 if (sender_uid != 0 && sender_uid != target_uid) {
523 _E("Not permitted user!");
524 g_variant_iter_free(iter);
525 _app2sd_server_return_method_error(invocation,
526 APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
530 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
532 _D("str(%s), type(%d)", str, type);
534 /* generate dir_list */
535 dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
536 if (dir_detail == NULL) {
537 _E("memory allocation failed");
538 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
542 dir_detail->name = strdup((char *)str);
543 if (dir_detail->name == NULL) {
546 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
550 dir_detail->type = type;
551 list = g_list_append(list, dir_detail);
554 g_variant_iter_free(iter);
556 dir_list = g_list_first(list);
557 ret = app2sd_usr_move_installed_app(pkgid, dir_list, move_type, target_uid);
559 _E("usr_move error(%d)", ret);
563 param = g_variant_new("(i)", result);
564 g_dbus_method_invocation_return_value(invocation, param);
567 static void handle_method_call(GDBusConnection *connection,
568 const gchar *sender, const gchar *object_path,
569 const gchar *interface_name, const gchar *method_name,
570 GVariant *parameters, GDBusMethodInvocation *invocation,
573 uid_t sender_uid = -1;
575 sender_uid = (uid_t)__app2sd_get_sender_uid(connection, sender);
577 if (g_strcmp0(method_name, "PreAppInstall") == 0) {
578 _app2sd_server_pre_app_install(connection, sender,
579 parameters, invocation, sender_uid);
580 } else if (g_strcmp0(method_name, "PostAppInstall") == 0) {
581 _app2sd_server_post_app_install(connection, sender,
582 parameters, invocation, sender_uid);
583 } else if (g_strcmp0(method_name, "PreAppUpgrade") == 0) {
584 _app2sd_server_pre_app_upgrade(connection, sender,
585 parameters, invocation, sender_uid);
586 } else if (g_strcmp0(method_name, "PostAppUpgrade") == 0) {
587 _app2sd_server_post_app_upgrade(connection, sender,
588 parameters, invocation, sender_uid);
589 } else if (g_strcmp0(method_name, "PreAppUninstall") == 0) {
590 _app2sd_server_pre_app_uninstall(connection, sender,
591 parameters, invocation, sender_uid);
592 } else if (g_strcmp0(method_name, "PostAppUninstall") == 0) {
593 _app2sd_server_post_app_uninstall(connection, sender,
594 parameters, invocation, sender_uid);
595 } else if (g_strcmp0(method_name, "OndemandSetupInit") == 0) {
596 _app2sd_server_ondemand_setup_init(connection, sender,
597 parameters, invocation, sender_uid);
598 } else if (g_strcmp0(method_name, "OndemandSetupExit") == 0) {
599 _app2sd_server_ondemand_setup_exit(connection, sender,
600 parameters, invocation, sender_uid);
601 } else if (g_strcmp0(method_name, "MoveInstalledApp") == 0) {
602 _app2sd_server_move_installed_app(connection, sender,
603 parameters, invocation, sender_uid);
606 g_timeout_add_seconds(5, __exit_app2sd_server, NULL);
609 static const GDBusInterfaceVTable interface_vtable = {
615 static void __app2sd_on_bus_acquired(GDBusConnection *connection,
616 const gchar *name, gpointer user_data)
618 _I("bus acquired(%s)", name);
621 GError *error = NULL;
623 reg_id = g_dbus_connection_register_object(connection,
625 introspection_data->interfaces[0],
629 _E("g_dbus_connection_register_object error(%s)", error->message);
634 static void __app2sd_on_name_acquired(GDBusConnection *connection,
635 const gchar *name, gpointer user_data)
637 _I("name acquired(%s)", name);
640 static void __app2sd_on_name_lost(GDBusConnection *connection,
641 const gchar *name, gpointer user_data)
643 _E("name lost(%s)", name);
646 static int __app2sd_server_init()
648 GError *error = NULL;
651 /* gdbus setup for method call */
652 introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
653 if (!introspection_data) {
654 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
659 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
661 G_BUS_NAME_OWNER_FLAGS_NONE,
662 __app2sd_on_bus_acquired,
663 __app2sd_on_name_acquired,
664 __app2sd_on_name_lost,
667 _E("g_bus_own_name error");
668 g_dbus_node_info_unref(introspection_data);
677 static void __app2sd_finalize(void)
679 _D("app2sd finalize");
681 if (introspection_data)
682 g_dbus_node_info_unref(introspection_data);
684 _D("app2sd finalize end");
687 int main(int argc, char *argv[])
691 _I("app2sd_server : start");
693 ret = __app2sd_server_init();
695 _E("app2sd_server init failed(%d)", ret);
699 app2sd_mainloop = g_main_loop_new(NULL, FALSE);
700 if (!app2sd_mainloop) {
701 _E("g_main_loop_new failed");
705 g_main_loop_run(app2sd_mainloop);
709 _I("app2sd_server : end");