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);
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);
95 static int __app2sd_get_sender_uid(GDBusConnection *conn,
96 const char *sender_name)
100 uid = __app2sd_get_sender_unixinfo(conn, sender_name,
101 "GetConnectionUnixUser");
103 _E("failed to get uid");
106 _D("sender_name(%s), uid(%d)", sender_name, uid);
111 static GDBusNodeInfo *introspection_data;
112 static const gchar introspection_xml[] =
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
171 static void _app2sd_server_return_method_error(GDBusMethodInvocation *invocation, int result)
173 GVariant *param = NULL;
175 param = g_variant_new("(i)", result);
176 g_dbus_method_invocation_return_value(invocation, param);
179 static void _app2sd_server_pre_app_install(GDBusConnection *connection, const gchar *sender,
180 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
182 GVariant *param = NULL;
183 int result = APP2EXT_SUCCESS;
190 uid_t target_uid = -1;
191 GList *dir_list = NULL;
193 app2ext_dir_details *dir_detail = NULL;
195 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
197 _D("pkgid(%s), size(%d),sender_uid(%d), target_uid(%d)",
198 pkgid, size, sender_uid, target_uid);
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);
208 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
210 _D("str(%s), type(%d)", str, type);
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;
220 dir_detail->name = strdup((char *)str);
221 if (dir_detail->name == NULL) {
224 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
228 dir_detail->type = type;
229 list = g_list_append(list, dir_detail);
232 g_variant_iter_free(iter);
234 dir_list = g_list_first(list);
235 ret = app2sd_usr_pre_app_install(pkgid, dir_list, size, target_uid);
237 _E("error(%d)", ret);
241 param = g_variant_new("(i)", result);
242 g_dbus_method_invocation_return_value(invocation, param);
245 static void _app2sd_server_post_app_install(GDBusConnection *connection, const gchar *sender,
246 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
248 GVariant *param = NULL;
249 int result = APP2EXT_SUCCESS;
251 int install_status = 0;
255 g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
257 _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
258 pkgid, install_status, sender_uid, target_uid);
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);
267 ret = app2sd_usr_post_app_install(pkgid, install_status, target_uid);
269 _E("error(%d)", ret);
273 param = g_variant_new("(i)", result);
274 g_dbus_method_invocation_return_value(invocation, param);
277 static void _app2sd_server_pre_app_upgrade(GDBusConnection *connection, const gchar *sender,
278 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
280 GVariant *param = NULL;
281 int result = APP2EXT_SUCCESS;
287 uid_t target_uid = -1;
289 GList *dir_list = NULL;
291 app2ext_dir_details *dir_detail = NULL;
293 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
295 _D("pkgid(%s), size(%d), sender_uid(%d), target_uid(%d)",
296 pkgid, size, sender_uid, target_uid);
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);
306 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
308 _D("str(%s), type(%d)", str, type);
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;
318 dir_detail->name = strdup((char *)str);
319 if (dir_detail->name == NULL) {
322 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
326 dir_detail->type = type;
327 list = g_list_append(list, dir_detail);
330 g_variant_iter_free(iter);
332 dir_list = g_list_first(list);
333 ret = app2sd_usr_pre_app_upgrade(pkgid, dir_list, size, target_uid);
335 _E("error(%d)", ret);
339 param = g_variant_new("(i)", result);
340 g_dbus_method_invocation_return_value(invocation, param);
343 static void _app2sd_server_post_app_upgrade(GDBusConnection *connection, const gchar *sender,
344 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
346 GVariant *param = NULL;
347 int result = APP2EXT_SUCCESS;
349 int install_status = 0;
350 uid_t target_uid = -1;
353 g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
355 _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
356 pkgid, install_status, sender_uid, target_uid);
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);
365 ret = app2sd_usr_post_app_upgrade(pkgid, install_status, target_uid);
367 _E("error(%d)", ret);
371 param = g_variant_new("(i)", result);
372 g_dbus_method_invocation_return_value(invocation, param);
375 static void _app2sd_server_pre_app_uninstall(GDBusConnection *connection, const gchar *sender,
376 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
378 GVariant *param = NULL;
379 int result = APP2EXT_SUCCESS;
381 uid_t target_uid = -1;
384 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
386 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
387 pkgid, sender_uid, target_uid);
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);
396 ret = app2sd_usr_pre_app_uninstall(pkgid, target_uid);
398 _E("error(%d)", ret);
402 param = g_variant_new("(i)", result);
403 g_dbus_method_invocation_return_value(invocation, param);
406 static void _app2sd_server_post_app_uninstall(GDBusConnection *connection, const gchar *sender,
407 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
409 GVariant *param = NULL;
410 int result = APP2EXT_SUCCESS;
412 uid_t target_uid = -1;
415 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
417 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
418 pkgid, sender_uid, target_uid);
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);
427 ret = app2sd_usr_post_app_uninstall(pkgid, target_uid);
429 _E("error(%d)", ret);
433 param = g_variant_new("(i)", result);
434 g_dbus_method_invocation_return_value(invocation, param);
437 static void _app2sd_server_ondemand_setup_init(GDBusConnection *connection, const gchar *sender,
438 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
440 GVariant *param = NULL;
441 int result = APP2EXT_SUCCESS;
443 uid_t target_uid = -1;
446 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
448 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
449 pkgid, sender_uid, target_uid);
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);
458 ret = app2sd_usr_on_demand_setup_init(pkgid, target_uid);
460 _E("error(%d)", ret);
464 param = g_variant_new("(i)", result);
465 g_dbus_method_invocation_return_value(invocation, param);
468 static void _app2sd_server_ondemand_setup_exit(GDBusConnection *connection, const gchar *sender,
469 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
471 GVariant *param = NULL;
472 int result = APP2EXT_SUCCESS;
474 uid_t target_uid = -1;
477 g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
479 _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
480 pkgid, sender_uid, target_uid);
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);
489 ret = app2sd_usr_on_demand_setup_exit(pkgid, target_uid);
491 _E("error(%d)", ret);
495 param = g_variant_new("(i)", result);
496 g_dbus_method_invocation_return_value(invocation, param);
499 static void _app2sd_server_move_installed_app(GDBusConnection *connection, const gchar *sender,
500 GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
502 GVariant *param = NULL;
503 int result = APP2EXT_SUCCESS;
510 uid_t target_uid = -1;
511 GList *dir_list = NULL;
513 app2ext_dir_details *dir_detail = NULL;
515 g_variant_get(parameters, "(&sia(si)i)", &pkgid, &move_type, &iter, &target_uid);
517 _D("pkgid(%s), move_type(%d),sender_uid(%d), target_uid(%d)",
518 pkgid, move_type, sender_uid, target_uid);
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);
528 while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
530 _D("str(%s), type(%d)", str, type);
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;
540 dir_detail->name = strdup((char *)str);
541 if (dir_detail->name == NULL) {
544 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
548 dir_detail->type = type;
549 list = g_list_append(list, dir_detail);
552 g_variant_iter_free(iter);
554 dir_list = g_list_first(list);
555 ret = app2sd_usr_move_installed_app(pkgid, dir_list, move_type, target_uid);
557 _E("usr_move error(%d)", ret);
561 param = g_variant_new("(i)", result);
562 g_dbus_method_invocation_return_value(invocation, param);
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,
571 uid_t sender_uid = -1;
573 sender_uid = (uid_t)__app2sd_get_sender_uid(connection, sender);
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);
604 g_timeout_add_seconds(5, __exit_app2sd_server, NULL);
607 static const GDBusInterfaceVTable interface_vtable = {
613 static void __app2sd_on_bus_acquired(GDBusConnection *connection,
614 const gchar *name, gpointer user_data)
616 _I("bus acquired(%s)", name);
619 GError *error = NULL;
621 reg_id = g_dbus_connection_register_object(connection,
623 introspection_data->interfaces[0],
627 _E("g_dbus_connection_register_object error(%s)", error->message);
632 static void __app2sd_on_name_acquired(GDBusConnection *connection,
633 const gchar *name, gpointer user_data)
635 _I("name acquired(%s)", name);
638 static void __app2sd_on_name_lost(GDBusConnection *connection,
639 const gchar *name, gpointer user_data)
641 _E("name lost(%s)", name);
644 static int __app2sd_server_init()
646 GError *error = NULL;
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);
657 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
659 G_BUS_NAME_OWNER_FLAGS_NONE,
660 __app2sd_on_bus_acquired,
661 __app2sd_on_name_acquired,
662 __app2sd_on_name_lost,
665 _E("g_bus_own_name error");
666 g_dbus_node_info_unref(introspection_data);
675 static void __app2sd_finalize(void)
677 _D("app2sd finalize");
679 if (introspection_data)
680 g_dbus_node_info_unref(introspection_data);
682 _D("app2sd finalize end");
685 int main(int argc, char *argv[])
689 _I("app2sd_server : start");
691 ret = __app2sd_server_init();
693 _E("app2sd_server init failed(%d)", ret);
697 app2sd_mainloop = g_main_loop_new(NULL, FALSE);
698 if (!app2sd_mainloop) {
699 _E("g_main_loop_new failed");
703 g_main_loop_run(app2sd_mainloop);
707 _I("app2sd_server : end");