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 <tzplatform_config.h>
34 #include "app2sd_client_interface.h"
35 #include "app2sd_utils.h"
37 #define CONNECTION_RETRY_MAX 5
38 #define CONNECTION_WAIT_USEC (1000000 / 2) /* 0.5 sec */
40 static int app2sd_gdbus_shared_connection(GDBusConnection **connection)
44 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
48 *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
49 if (*connection == NULL) {
51 _E("app2sd error : failed to get "
52 "system dbus [%s]", error->message);
55 return APP2EXT_ERROR_DBUS_FAILED;
58 return APP2EXT_SUCCESS;
61 static int __app2sd_call_server_method(const gchar *method_name,
64 int ret = APP2EXT_SUCCESS;
67 GDBusConnection *conn = NULL;
68 GDBusProxy *proxy = NULL;
70 GVariant *value = NULL;
72 /* get gdbus connection */
73 ret = app2sd_gdbus_shared_connection(&conn);
75 _E("app2sd error : dbus connection error");
81 proxy = g_dbus_proxy_new_sync(conn,
82 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
83 APP2SD_BUS_NAME, APP2SD_OBJECT_PATH,
84 APP2SD_INTERFACE_NAME,
87 _E("failed to create new proxy, error(%s)",
91 ret = APP2EXT_ERROR_DBUS_FAILED;
93 usleep(CONNECTION_WAIT_USEC);
97 value = g_dbus_proxy_call_sync(proxy, method_name, param,
98 G_DBUS_CALL_FLAGS_NONE, G_MAXINT, NULL, &error);
99 g_object_unref(proxy);
101 _E("proxy call sync error(%s)", error->message);
104 ret = APP2EXT_ERROR_DBUS_FAILED;
106 usleep(CONNECTION_WAIT_USEC);
110 g_variant_get(value, "(i)", &result);
111 g_variant_unref(value);
113 _D("result(%d)", result);
118 } while (retry_cnt <= CONNECTION_RETRY_MAX);
121 g_object_unref(conn);
126 static void __app2sd_create_dir_list_builder(gpointer data, gpointer user_data)
128 app2ext_dir_details *item = (app2ext_dir_details *)data;
129 GVariantBuilder *builder = (GVariantBuilder *)user_data;
131 g_variant_builder_add(builder, "(si)", item->name, item->type);
134 static int __app2sd_delete_temp_directories(const char *pkgid,
135 app2sd_cmd cmd, uid_t uid)
138 char app_path[FILENAME_MAX] = { 0, };
139 char temp_path[FILENAME_MAX] = { 0, };
141 if (cmd != APP2SD_PRE_UPGRADE)
142 return APP2EXT_SUCCESS;
144 _app2sd_set_application_path(pkgid, uid, app_path, sizeof(app_path));
145 snprintf(temp_path, sizeof(temp_path), "%s.new", app_path);
147 /* this will delete all files under temp_path */
148 ret = _app2sd_delete_directory(temp_path);
150 _E("unable to delete (%s)", temp_path);
151 return APP2EXT_ERROR_DELETE_DIRECTORY;
154 return APP2EXT_SUCCESS;
157 static int __app2sd_create_default_directories(const char *pkgid,
158 app2sd_cmd cmd, uid_t uid)
161 mode_t mode = DIR_PERMS;
162 char application_path[FILENAME_MAX] = { 0, };
163 char app_mmc_path[FILENAME_MAX] = { 0, };
164 char temp_path[FILENAME_MAX] = { 0, };
166 _app2sd_set_application_path(pkgid, uid, application_path,
167 sizeof(application_path));
168 ret = mkdir(application_path, mode);
170 if (errno != EEXIST) {
171 _E("create directory failed," \
172 " error no is (%d)", errno);
173 return APP2EXT_ERROR_CREATE_DIRECTORY;
177 snprintf(app_mmc_path, sizeof(app_mmc_path), "%s/.mmc",
179 ret = mkdir(app_mmc_path, mode);
181 if (errno != EEXIST) {
182 _E("create directory failed," \
183 " error no is (%d)", errno);
184 return APP2EXT_ERROR_CREATE_DIRECTORY;
188 if (cmd == APP2SD_PRE_UPGRADE) {
189 /* application_path for {pkgid}.new */
190 snprintf(temp_path, sizeof(temp_path), "%s.new",
192 ret = mkdir(temp_path, mode);
194 if (errno != EEXIST) {
195 _E("create directory failed," \
196 " error no is (%d)", errno);
197 return APP2EXT_ERROR_CREATE_DIRECTORY;
200 /* app_mmc_path for {pkgid}.new */
201 snprintf(app_mmc_path, sizeof(app_mmc_path), "%s/.mmc",
203 ret = mkdir(app_mmc_path, mode);
205 if (errno != EEXIST) {
206 _E("create directory failed," \
207 " error no is (%d)", errno);
208 return APP2EXT_ERROR_CREATE_DIRECTORY;
213 return APP2EXT_SUCCESS;
216 int app2sd_client_usr_pre_app_install(const char *pkgid, GList *dir_list,
220 GVariantBuilder *builder = NULL;
221 GVariant *param = NULL;
223 /* validate the function parameter recieved */
224 if (pkgid == NULL || dir_list == NULL || size <= 0) {
225 _E("invalid function arguments");
226 return APP2EXT_ERROR_INVALID_ARGUMENTS;
229 ret = __app2sd_create_default_directories(pkgid,
230 APP2SD_PRE_INSTALL, uid);
234 builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)"));
235 g_list_foreach(dir_list, __app2sd_create_dir_list_builder, builder);
237 param = g_variant_new("(sia(si)i)", pkgid, size, builder, uid);
238 ret = __app2sd_call_server_method("PreAppInstall", param);
241 g_variant_builder_unref(builder);
245 int app2sd_client_pre_app_install(const char *pkgid, GList *dir_list,
250 ret = app2sd_client_usr_pre_app_install(pkgid,
251 dir_list, size, getuid());
256 int app2sd_client_usr_post_app_install(const char *pkgid,
257 app2ext_status install_status, uid_t uid)
260 GVariant *param = NULL;
262 /* validate the function parameter recieved */
263 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
264 || install_status > APP2EXT_STATUS_SUCCESS) {
265 _E("invalid func parameters");
266 return APP2EXT_ERROR_INVALID_ARGUMENTS;
269 param = g_variant_new("(sii)", pkgid, install_status, uid);
270 ret = __app2sd_call_server_method("PostAppInstall", param);
274 int app2sd_client_post_app_install(const char *pkgid,
275 app2ext_status install_status)
279 ret = app2sd_client_usr_post_app_install(pkgid,
280 install_status, getuid());
285 int app2sd_client_usr_pre_app_upgrade(const char *pkgid, GList *dir_list,
289 GVariantBuilder *builder = NULL;
290 GVariant *param = NULL;
292 /* validate the function parameter recieved */
293 if (pkgid == NULL || dir_list == NULL || size <= 0) {
294 _E("invalid function arguments");
295 return APP2EXT_ERROR_INVALID_ARGUMENTS;
298 ret = __app2sd_create_default_directories(pkgid,
299 APP2SD_PRE_UPGRADE, uid);
303 builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)"));
304 g_list_foreach(dir_list, __app2sd_create_dir_list_builder, builder);
306 param = g_variant_new("(sia(si)i)", pkgid, size, builder, uid);
307 ret = __app2sd_call_server_method("PreAppUpgrade", param);
310 g_variant_builder_unref(builder);
312 __app2sd_delete_temp_directories(pkgid, APP2SD_PRE_UPGRADE, uid);
316 int app2sd_client_pre_app_upgrade(const char *pkgid, GList *dir_list,
321 ret = app2sd_client_usr_pre_app_upgrade(pkgid,
322 dir_list, size, getuid());
327 int app2sd_client_usr_post_app_upgrade(const char *pkgid,
328 app2ext_status install_status, uid_t uid)
331 GVariant *param = NULL;
333 /* validate the function parameter recieved */
334 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
335 || install_status > APP2EXT_STATUS_SUCCESS) {
336 _E("invalid func parameters");
337 return APP2EXT_ERROR_INVALID_ARGUMENTS;
340 param = g_variant_new("(sii)", pkgid, install_status, uid);
341 ret = __app2sd_call_server_method("PostAppUpgrade", param);
345 int app2sd_client_post_app_upgrade(const char *pkgid,
346 app2ext_status install_status)
350 ret = app2sd_client_usr_post_app_upgrade(pkgid,
351 install_status, getuid());
356 int app2sd_client_usr_pre_app_uninstall(const char *pkgid, uid_t uid)
359 GVariant *param = NULL;
361 /* validate the function parameter recieved */
363 _E("invalid func parameters");
364 return APP2EXT_ERROR_INVALID_ARGUMENTS;
367 param = g_variant_new("(si)", pkgid, uid);
368 ret = __app2sd_call_server_method("PreAppUninstall", param);
372 int app2sd_client_pre_app_uninstall(const char *pkgid)
376 ret = app2sd_client_usr_pre_app_uninstall(pkgid,
382 int app2sd_client_usr_post_app_uninstall(const char *pkgid, uid_t uid)
385 GVariant *param = NULL;
387 /* validate the function parameter recieved */
389 _E("invalid func parameters");
390 return APP2EXT_ERROR_INVALID_ARGUMENTS;
393 param = g_variant_new("(si)", pkgid, uid);
394 ret = __app2sd_call_server_method("PostAppUninstall", param);
398 int app2sd_client_post_app_uninstall(const char *pkgid)
402 ret = app2sd_client_usr_post_app_uninstall(pkgid,
408 int app2sd_client_usr_force_clean(const char *pkgid, uid_t uid)
411 GVariant *param = NULL;
413 /* validate the function parameter recieved */
415 _E("invalid func parameters");
416 return APP2EXT_ERROR_INVALID_ARGUMENTS;
419 param = g_variant_new("(si)", pkgid, uid);
420 ret = __app2sd_call_server_method("ForceClean", param);
424 int app2sd_client_force_clean(const char *pkgid)
428 ret = app2sd_client_usr_force_clean(pkgid, getuid());
433 int app2sd_client_enable_full_pkg(void)
437 ret = __app2sd_call_server_method("EnableFullPkg", NULL);
442 int app2sd_client_disable_full_pkg(void)
446 ret = __app2sd_call_server_method("DisableFullPkg", NULL);
451 int app2sd_client_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
454 GVariant *param = NULL;
456 /* validate the function parameter recieved */
458 _E("invalid func parameters");
459 return APP2EXT_ERROR_INVALID_ARGUMENTS;
462 param = g_variant_new("(si)", pkgid, uid);
463 ret = __app2sd_call_server_method("OndemandSetupInit", param);
467 int app2sd_client_on_demand_setup_init(const char *pkgid)
471 ret = app2sd_client_usr_on_demand_setup_init(pkgid,
477 int app2sd_client_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
480 GVariant *param = NULL;
482 /* validate the function parameter recieved */
484 _E("invalid func parameters");
485 return APP2EXT_ERROR_INVALID_ARGUMENTS;
488 param = g_variant_new("(si)", pkgid, uid);
489 ret = __app2sd_call_server_method("OndemandSetupExit", param);
493 int app2sd_client_on_demand_setup_exit(const char *pkgid)
497 ret = app2sd_client_usr_on_demand_setup_exit(pkgid,
503 int app2sd_client_usr_pre_move_installed_app(const char *pkgid, GList *dir_list,
504 app2ext_move_type move_type, uid_t uid)
507 GVariantBuilder *builder = NULL;
508 GVariant *param = NULL;
509 app2sd_cmd cmd = APP2SD_MOVE_APP_TO_PHONE;
510 pkgmgrinfo_pkginfo_h info_handle = NULL;
511 pkgmgrinfo_installed_storage storage = PMINFO_INTERNAL_STORAGE;
513 /* validate the function parameter recieved */
514 if (pkgid == NULL || dir_list == NULL
515 || move_type < APP2EXT_MOVE_TO_EXT
516 || move_type > APP2EXT_MOVE_TO_PHONE) {
517 _E("invalid function arguments");
518 return APP2EXT_ERROR_INVALID_ARGUMENTS;
521 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &info_handle);
523 _E("failed to get pkginfo for pkg(%s), uid(%d), ret(%d)",
525 return APP2EXT_ERROR_PKGMGR_ERROR;
527 ret = pkgmgrinfo_pkginfo_get_installed_storage(info_handle, &storage);
529 _E("failed to get installed storage for pkg(%s) " \
530 "of uid(%d), ret(%d)", pkgid, uid, ret);
531 pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
532 return APP2EXT_ERROR_PKGMGR_ERROR;
535 if ((move_type == APP2EXT_MOVE_TO_EXT && storage ==
536 PMINFO_EXTERNAL_STORAGE)
537 || (move_type == APP2EXT_MOVE_TO_PHONE &&
538 storage == PMINFO_INTERNAL_STORAGE)) {
539 _E("PKG_EXISTS in [%d] STORAGE", storage);
540 pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
541 return APP2EXT_ERROR_PKG_EXISTS;
543 _D("pkgid[%s] move to STORAGE [%d]", pkgid, storage);
545 pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
547 if (move_type == APP2EXT_MOVE_TO_EXT)
548 cmd = APP2SD_MOVE_APP_TO_MMC;
550 if (cmd == APP2SD_MOVE_APP_TO_MMC) {
551 ret = __app2sd_create_default_directories(pkgid, cmd, uid);
556 builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)"));
557 g_list_foreach(dir_list, __app2sd_create_dir_list_builder, builder);
559 param = g_variant_new("(sia(si)i)", pkgid, move_type, builder, uid);
560 ret = __app2sd_call_server_method("PreMoveInstalledApp", param);
563 g_variant_builder_unref(builder);
567 int app2sd_client_pre_move_installed_app(const char *pkgid, GList *dir_list,
568 app2ext_move_type move_type)
572 ret = app2sd_client_usr_pre_move_installed_app(pkgid,
573 dir_list, move_type, getuid());
578 int app2sd_client_usr_post_move_installed_app(const char *pkgid,
579 app2ext_move_type move_type, uid_t uid)
582 GVariant *param = NULL;
584 /* validate the function parameter recieved */
585 if (pkgid == NULL || move_type < APP2EXT_MOVE_TO_EXT
586 || move_type > APP2EXT_MOVE_TO_PHONE) {
587 _E("invalid function arguments");
588 return APP2EXT_ERROR_INVALID_ARGUMENTS;
591 param = g_variant_new("(sii)", pkgid, move_type, uid);
592 ret = __app2sd_call_server_method("PostMoveInstalledApp", param);
596 int app2sd_client_post_move_installed_app(const char *pkgid,
597 app2ext_move_type move_type)
601 ret = app2sd_client_usr_post_move_installed_app(pkgid,
602 move_type, getuid());
607 int app2sd_client_usr_pre_migrate_legacy(const char *pkgid, uid_t uid)
610 GVariant *param = NULL;
612 /* validate the function parameter recieved */
614 _E("invalid function arguments");
615 return APP2EXT_ERROR_INVALID_ARGUMENTS;
618 param = g_variant_new("(si)", pkgid, uid);
619 ret = __app2sd_call_server_method("PreMigrateLegacy", param);
624 int app2sd_client_usr_post_migrate_legacy(const char *pkgid, uid_t uid)
627 GVariant *param = NULL;
629 /* validate the function parameter recieved */
631 _E("invalid function arguments");
632 return APP2EXT_ERROR_INVALID_ARGUMENTS;
635 param = g_variant_new("(si)", pkgid, uid);
636 ret = __app2sd_call_server_method("PostMigrateLegacy", param);
641 int app2sd_client_migrate_legacy_all()
645 ret = __app2sd_call_server_method("MigrateLegacyAll", NULL);
650 char *app2sd_client_usr_getname_image(const char *pkgid, uid_t uid)
652 return _app2sd_get_encoded_name(pkgid, uid);
655 char *app2sd_client_usr_get_image_path(const char *pkgid, uid_t uid)
657 static const char query[] =
658 "SELECT filename FROM app2sd_info WHERE pkgid=? AND uid=?";
663 char *image_path = NULL;
665 dbpath = tzplatform_mkpath(TZ_SYS_DB, ".app2sd.db");
669 ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
670 if (ret != SQLITE_OK) {
671 LOGE("open failed: %s", sqlite3_errmsg(db));
675 ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
676 if (ret != SQLITE_OK) {
677 LOGE("prepare failed: %s", sqlite3_errmsg(db));
678 sqlite3_close_v2(db);
682 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
683 if (ret != SQLITE_OK) {
684 LOGE("bind failed: %s", sqlite3_errmsg(db));
685 sqlite3_finalize(stmt);
686 sqlite3_close_v2(db);
690 ret = sqlite3_bind_int(stmt, 2, uid);
691 if (ret != SQLITE_OK) {
692 LOGE("bind failed: %s", sqlite3_errmsg(db));
693 sqlite3_finalize(stmt);
694 sqlite3_close_v2(db);
698 ret = sqlite3_step(stmt);
699 if (ret == SQLITE_ROW)
700 image_path = strdup((char *)sqlite3_column_text(stmt, 0));
702 sqlite3_finalize(stmt);
703 sqlite3_close_v2(db);
708 void app2ext_on_load(app2ext_interface *interface)
710 /* Plug-in Binding.*/
711 interface->client_pre_install = app2sd_client_pre_app_install;
712 interface->client_post_install = app2sd_client_post_app_install;
713 interface->client_pre_upgrade = app2sd_client_pre_app_upgrade;
714 interface->client_post_upgrade = app2sd_client_post_app_upgrade;
715 interface->client_pre_uninstall = app2sd_client_pre_app_uninstall;
716 interface->client_post_uninstall = app2sd_client_post_app_uninstall;
717 interface->client_force_clean = app2sd_client_force_clean;
718 interface->client_enable = app2sd_client_on_demand_setup_init;
719 interface->client_disable = app2sd_client_on_demand_setup_exit;
720 interface->client_enable_full_pkg = app2sd_client_enable_full_pkg;
721 interface->client_disable_full_pkg = app2sd_client_disable_full_pkg;
722 interface->client_pre_move = app2sd_client_pre_move_installed_app;
723 interface->client_post_move = app2sd_client_post_move_installed_app;
724 interface->client_migrate_legacy_all = app2sd_client_migrate_legacy_all;
726 interface->client_usr_pre_install = app2sd_client_usr_pre_app_install;
727 interface->client_usr_post_install = app2sd_client_usr_post_app_install;
728 interface->client_usr_pre_upgrade = app2sd_client_usr_pre_app_upgrade;
729 interface->client_usr_post_upgrade = app2sd_client_usr_post_app_upgrade;
730 interface->client_usr_pre_uninstall = app2sd_client_usr_pre_app_uninstall;
731 interface->client_usr_post_uninstall = app2sd_client_usr_post_app_uninstall;
732 interface->client_usr_force_clean = app2sd_client_usr_force_clean;
733 interface->client_usr_enable = app2sd_client_usr_on_demand_setup_init;
734 interface->client_usr_disable = app2sd_client_usr_on_demand_setup_exit;
735 interface->client_usr_pre_move = app2sd_client_usr_pre_move_installed_app;
736 interface->client_usr_post_move = app2sd_client_usr_post_move_installed_app;
737 interface->client_usr_getname_image = app2sd_client_usr_getname_image;
738 interface->client_usr_pre_migrate_legacy = app2sd_client_usr_pre_migrate_legacy;
739 interface->client_usr_post_migrate_legacy = app2sd_client_usr_post_migrate_legacy;
740 interface->client_usr_get_image_path = app2sd_client_usr_get_image_path;