4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Garima Shrivastava<garima.s@samsung.com>
7 * Jyotsna Dhumale <jyotsna.a@samsung.com>
8 * Venkatesha Sarpangala <sarpangala.v@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
26 #include <sys/types.h>
30 #include <pkgmgr-info.h>
32 #include "app2sd_client_interface.h"
33 #include "app2sd_utils.h"
35 #define CONNECTION_RETRY_MAX 5
36 #define CONNECTION_WAIT_USEC (1000000 / 2) /* 0.5 sec */
38 static int app2sd_gdbus_shared_connection(GDBusConnection **connection)
42 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
46 *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
47 if (*connection == NULL) {
49 _E("app2sd error : failed to get "
50 "system dbus [%s]", error->message);
53 return APP2EXT_ERROR_DBUS_FAILED;
56 return APP2EXT_SUCCESS;
59 static int __app2sd_call_server_method(const gchar *method_name,
62 int ret = APP2EXT_SUCCESS;
65 GDBusConnection *conn = NULL;
66 GDBusProxy *proxy = NULL;
68 GVariant *value = NULL;
70 /* get gdbus connection */
71 ret = app2sd_gdbus_shared_connection(&conn);
73 _E("app2sd error : dbus connection error");
79 proxy = g_dbus_proxy_new_sync(conn,
80 G_DBUS_PROXY_FLAGS_NONE, NULL,
81 APP2SD_BUS_NAME, APP2SD_OBJECT_PATH,
82 APP2SD_INTERFACE_NAME,
85 _E("failed to create new proxy, error(%s)",
88 ret = APP2EXT_ERROR_DBUS_FAILED;
90 usleep(CONNECTION_WAIT_USEC);
94 value = g_dbus_proxy_call_sync(proxy, method_name, param,
95 G_DBUS_CALL_FLAGS_NONE, G_MAXINT, NULL, &error);
96 g_object_unref(proxy);
98 _E("proxy call sync error(%s)", error->message);
100 ret = APP2EXT_ERROR_DBUS_FAILED;
102 usleep(CONNECTION_WAIT_USEC);
106 g_variant_get(value, "(i)", &result);
107 g_variant_unref(value);
109 _D("result(%d)", result);
114 } while (retry_cnt <= CONNECTION_RETRY_MAX);
117 g_object_unref(conn);
122 static void __app2sd_create_dir_list_builder(gpointer data, gpointer user_data)
124 app2ext_dir_details *item = (app2ext_dir_details *)data;
125 GVariantBuilder *builder = (GVariantBuilder *)user_data;
127 g_variant_builder_add(builder, "(si)", item->name, item->type);
130 static int __app2sd_delete_temp_directories(const char *pkgid,
131 app2sd_cmd cmd, uid_t uid)
134 char temp_path[FILENAME_MAX] = { 0, };
136 if (cmd != APP2SD_PRE_UPGRADE)
137 return APP2EXT_SUCCESS;
139 if (_is_global(uid)) {
140 snprintf(temp_path, FILENAME_MAX - 1, "%s/%s.new",
141 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
143 tzplatform_set_user(uid);
144 snprintf(temp_path, FILENAME_MAX - 1, "%s/%s.new",
145 tzplatform_getenv(TZ_USER_APP), pkgid);
146 tzplatform_reset_user();
149 /* this will delete all files under temp_path */
150 ret = _app2sd_delete_directory(temp_path);
152 _E("unable to delete (%s)", temp_path);
153 return APP2EXT_ERROR_DELETE_DIRECTORY;
156 return APP2EXT_SUCCESS;
159 static int __app2sd_create_default_directories(const char *pkgid,
160 app2sd_cmd cmd, uid_t uid)
163 mode_t mode = DIR_PERMS;
164 char application_path[FILENAME_MAX] = { 0, };
165 char application_mmc_path[FILENAME_MAX] = { 0, };
166 char temp_path[FILENAME_MAX] = { 0, };
168 if (_is_global(uid)) {
169 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
170 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
172 tzplatform_set_user(uid);
173 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
174 tzplatform_getenv(TZ_USER_APP), pkgid);
175 tzplatform_reset_user();
178 ret = mkdir(application_path, mode);
180 if (errno != EEXIST) {
181 _E("create directory failed," \
182 " error no is (%d)", errno);
183 return APP2EXT_ERROR_CREATE_DIRECTORY;
187 snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/.mmc",
190 ret = mkdir(application_mmc_path, mode);
192 if (errno != EEXIST) {
193 _E("create directory failed," \
194 " error no is (%d)", errno);
195 return APP2EXT_ERROR_CREATE_DIRECTORY;
199 if (cmd == APP2SD_PRE_UPGRADE) {
200 /* application_path for {pkgid}.new */
201 snprintf(temp_path, FILENAME_MAX - 1, "%s.new",
203 ret = mkdir(temp_path, mode);
205 if (errno != EEXIST) {
206 _E("create directory failed," \
207 " error no is (%d)", errno);
208 return APP2EXT_ERROR_CREATE_DIRECTORY;
211 /* application_mmc_path for {pkgid}.new */
212 snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/.mmc",
214 ret = mkdir(application_mmc_path, mode);
216 if (errno != EEXIST) {
217 _E("create directory failed," \
218 " error no is (%d)", errno);
219 return APP2EXT_ERROR_CREATE_DIRECTORY;
224 return APP2EXT_SUCCESS;
227 int app2sd_client_usr_pre_app_install(const char *pkgid, GList *dir_list,
231 GVariantBuilder *builder = NULL;
232 GVariant *param = NULL;
234 /* validate the function parameter recieved */
235 if (pkgid == NULL || dir_list == NULL || size <= 0) {
236 _E("invalid function arguments");
237 return APP2EXT_ERROR_INVALID_ARGUMENTS;
240 ret = __app2sd_create_default_directories(pkgid,
241 APP2SD_PRE_INSTALL, uid);
245 builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)"));
246 g_list_foreach(dir_list, __app2sd_create_dir_list_builder, builder);
248 param = g_variant_new("(sia(si)i)", pkgid, size, builder, uid);
249 ret = __app2sd_call_server_method("PreAppInstall", param);
252 g_variant_builder_unref(builder);
256 int app2sd_client_pre_app_install(const char *pkgid, GList *dir_list,
261 ret = app2sd_client_usr_pre_app_install(pkgid,
262 dir_list, size, getuid());
267 int app2sd_client_usr_post_app_install(const char *pkgid,
268 app2ext_status install_status, uid_t uid)
271 GVariant *param = NULL;
273 /* validate the function parameter recieved */
274 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
275 || install_status > APP2EXT_STATUS_SUCCESS) {
276 _E("invalid func parameters");
277 return APP2EXT_ERROR_INVALID_ARGUMENTS;
280 param = g_variant_new("(sii)", pkgid, install_status, uid);
281 ret = __app2sd_call_server_method("PostAppInstall", param);
285 int app2sd_client_post_app_install(const char *pkgid,
286 app2ext_status install_status)
290 ret = app2sd_client_usr_post_app_install(pkgid,
291 install_status, getuid());
296 int app2sd_client_usr_pre_app_upgrade(const char *pkgid, GList *dir_list,
300 GVariantBuilder *builder = NULL;
301 GVariant *param = NULL;
303 /* validate the function parameter recieved */
304 if (pkgid == NULL || dir_list == NULL || size <= 0) {
305 _E("invalid function arguments");
306 return APP2EXT_ERROR_INVALID_ARGUMENTS;
309 ret = __app2sd_create_default_directories(pkgid,
310 APP2SD_PRE_UPGRADE, uid);
314 builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)"));
315 g_list_foreach(dir_list, __app2sd_create_dir_list_builder, builder);
317 param = g_variant_new("(sia(si)i)", pkgid, size, builder, uid);
318 ret = __app2sd_call_server_method("PreAppUpgrade", param);
321 g_variant_builder_unref(builder);
323 __app2sd_delete_temp_directories(pkgid, APP2SD_PRE_UPGRADE, uid);
327 int app2sd_client_pre_app_upgrade(const char *pkgid, GList *dir_list,
332 ret = app2sd_client_usr_pre_app_upgrade(pkgid,
333 dir_list, size, getuid());
338 int app2sd_client_usr_post_app_upgrade(const char *pkgid,
339 app2ext_status install_status, uid_t uid)
342 GVariant *param = NULL;
344 /* validate the function parameter recieved */
345 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
346 || install_status > APP2EXT_STATUS_SUCCESS) {
347 _E("invalid func parameters");
348 return APP2EXT_ERROR_INVALID_ARGUMENTS;
351 param = g_variant_new("(sii)", pkgid, install_status, uid);
352 ret = __app2sd_call_server_method("PostAppUpgrade", param);
356 int app2sd_client_post_app_upgrade(const char *pkgid,
357 app2ext_status install_status)
361 ret = app2sd_client_usr_post_app_upgrade(pkgid,
362 install_status, getuid());
367 int app2sd_client_usr_pre_app_uninstall(const char *pkgid, uid_t uid)
370 GVariant *param = NULL;
372 /* validate the function parameter recieved */
374 _E("invalid func parameters");
375 return APP2EXT_ERROR_INVALID_ARGUMENTS;
378 param = g_variant_new("(si)", pkgid, uid);
379 ret = __app2sd_call_server_method("PreAppUninstall", param);
383 int app2sd_client_pre_app_uninstall(const char *pkgid)
387 ret = app2sd_client_usr_pre_app_uninstall(pkgid,
393 int app2sd_client_usr_post_app_uninstall(const char *pkgid, uid_t uid)
396 GVariant *param = NULL;
398 /* validate the function parameter recieved */
400 _E("invalid func parameters");
401 return APP2EXT_ERROR_INVALID_ARGUMENTS;
404 param = g_variant_new("(si)", pkgid, uid);
405 ret = __app2sd_call_server_method("PostAppUninstall", param);
409 int app2sd_client_post_app_uninstall(const char *pkgid)
413 ret = app2sd_client_usr_post_app_uninstall(pkgid,
419 int app2sd_client_usr_force_clean(const char *pkgid, uid_t uid)
422 GVariant *param = NULL;
424 /* validate the function parameter recieved */
426 _E("invalid func parameters");
427 return APP2EXT_ERROR_INVALID_ARGUMENTS;
430 param = g_variant_new("(si)", pkgid, uid);
431 ret = __app2sd_call_server_method("ForceClean", param);
435 int app2sd_client_force_clean(const char *pkgid)
439 ret = app2sd_client_usr_force_clean(pkgid, getuid());
444 int app2sd_client_enable_full_pkg(void)
448 ret = __app2sd_call_server_method("EnableFullPkg", NULL);
453 int app2sd_client_disable_full_pkg(void)
457 ret = __app2sd_call_server_method("DisableFullPkg", NULL);
462 int app2sd_client_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
465 GVariant *param = NULL;
467 /* validate the function parameter recieved */
469 _E("invalid func parameters");
470 return APP2EXT_ERROR_INVALID_ARGUMENTS;
473 param = g_variant_new("(si)", pkgid, uid);
474 ret = __app2sd_call_server_method("OndemandSetupInit", param);
478 int app2sd_client_on_demand_setup_init(const char *pkgid)
482 ret = app2sd_client_usr_on_demand_setup_init(pkgid,
488 int app2sd_client_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
491 GVariant *param = NULL;
493 /* validate the function parameter recieved */
495 _E("invalid func parameters");
496 return APP2EXT_ERROR_INVALID_ARGUMENTS;
499 param = g_variant_new("(si)", pkgid, uid);
500 ret = __app2sd_call_server_method("OndemandSetupExit", param);
504 int app2sd_client_on_demand_setup_exit(const char *pkgid)
508 ret = app2sd_client_usr_on_demand_setup_exit(pkgid,
514 int app2sd_client_usr_pre_move_installed_app(const char *pkgid, GList *dir_list,
515 app2ext_move_type move_type, uid_t uid)
518 GVariantBuilder *builder = NULL;
519 GVariant *param = NULL;
520 app2sd_cmd cmd = APP2SD_MOVE_APP_TO_PHONE;
521 pkgmgrinfo_pkginfo_h info_handle = NULL;
522 pkgmgrinfo_installed_storage storage = PMINFO_INTERNAL_STORAGE;
524 /* validate the function parameter recieved */
525 if (pkgid == NULL || dir_list == NULL
526 || move_type < APP2EXT_MOVE_TO_EXT
527 || move_type > APP2EXT_MOVE_TO_PHONE) {
528 _E("invalid function arguments");
529 return APP2EXT_ERROR_INVALID_ARGUMENTS;
532 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &info_handle);
534 _E("failed to get pkginfo for pkg(%s), uid(%d), ret(%d)",
536 return APP2EXT_ERROR_PKGMGR_ERROR;
538 ret = pkgmgrinfo_pkginfo_get_installed_storage(info_handle, &storage);
540 _E("failed to get installed storage for pkg(%s) of uid(%d), ret(%d)",
542 pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
543 return APP2EXT_ERROR_PKGMGR_ERROR;
546 if ((move_type == APP2EXT_MOVE_TO_EXT && storage == PMINFO_EXTERNAL_STORAGE)
547 || (move_type == APP2EXT_MOVE_TO_PHONE && storage == PMINFO_INTERNAL_STORAGE)) {
548 _E("PKG_EXISTS in [%d] STORAGE", storage);
549 pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
550 return APP2EXT_ERROR_PKG_EXISTS;
552 _D("pkgid[%s] move to STORAGE [%d]", pkgid, storage);
554 pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
556 if (move_type == APP2EXT_MOVE_TO_EXT)
557 cmd = APP2SD_MOVE_APP_TO_MMC;
559 if (cmd == APP2SD_MOVE_APP_TO_MMC) {
560 ret = __app2sd_create_default_directories(pkgid, cmd, uid);
565 builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)"));
566 g_list_foreach(dir_list, __app2sd_create_dir_list_builder, builder);
568 param = g_variant_new("(sia(si)i)", pkgid, move_type, builder, uid);
569 ret = __app2sd_call_server_method("PreMoveInstalledApp", param);
572 g_variant_builder_unref(builder);
576 int app2sd_client_pre_move_installed_app(const char *pkgid, GList *dir_list,
577 app2ext_move_type move_type)
581 ret = app2sd_client_usr_pre_move_installed_app(pkgid,
582 dir_list, move_type, getuid());
587 int app2sd_client_usr_post_move_installed_app(const char *pkgid,
588 app2ext_move_type move_type, uid_t uid)
591 GVariant *param = NULL;
593 /* validate the function parameter recieved */
594 if (pkgid == NULL || move_type < APP2EXT_MOVE_TO_EXT
595 || move_type > APP2EXT_MOVE_TO_PHONE) {
596 _E("invalid function arguments");
597 return APP2EXT_ERROR_INVALID_ARGUMENTS;
600 param = g_variant_new("(sii)", pkgid, move_type, uid);
601 ret = __app2sd_call_server_method("PostMoveInstalledApp", param);
605 int app2sd_client_post_move_installed_app(const char *pkgid,
606 app2ext_move_type move_type)
610 ret = app2sd_client_usr_post_move_installed_app(pkgid,
611 move_type, getuid());
616 void app2ext_on_load(app2ext_interface *interface)
618 /* Plug-in Binding.*/
619 interface->client_pre_install = app2sd_client_pre_app_install;
620 interface->client_post_install = app2sd_client_post_app_install;
621 interface->client_pre_upgrade = app2sd_client_pre_app_upgrade;
622 interface->client_post_upgrade = app2sd_client_post_app_upgrade;
623 interface->client_pre_uninstall = app2sd_client_pre_app_uninstall;
624 interface->client_post_uninstall = app2sd_client_post_app_uninstall;
625 interface->client_force_clean = app2sd_client_force_clean;
626 interface->client_enable = app2sd_client_on_demand_setup_init;
627 interface->client_disable = app2sd_client_on_demand_setup_exit;
628 interface->client_enable_full_pkg = app2sd_client_enable_full_pkg;
629 interface->client_disable_full_pkg = app2sd_client_disable_full_pkg;
630 interface->client_pre_move = app2sd_client_pre_move_installed_app;
631 interface->client_post_move = app2sd_client_post_move_installed_app;
633 interface->client_usr_pre_install = app2sd_client_usr_pre_app_install;
634 interface->client_usr_post_install = app2sd_client_usr_post_app_install;
635 interface->client_usr_pre_upgrade = app2sd_client_usr_pre_app_upgrade;
636 interface->client_usr_post_upgrade = app2sd_client_usr_post_app_upgrade;
637 interface->client_usr_pre_uninstall = app2sd_client_usr_pre_app_uninstall;
638 interface->client_usr_post_uninstall = app2sd_client_usr_post_app_uninstall;
639 interface->client_usr_force_clean = app2sd_client_usr_force_clean;
640 interface->client_usr_enable = app2sd_client_usr_on_demand_setup_init;
641 interface->client_usr_disable = app2sd_client_usr_on_demand_setup_exit;
642 interface->client_usr_pre_move = app2sd_client_usr_pre_move_installed_app;
643 interface->client_usr_post_move = app2sd_client_usr_post_move_installed_app;