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.
24 #include <pkgmgr-info.h>
27 #include "app2sd_internals.h"
29 static int __app2sd_create_app2sd_directories(uid_t uid)
32 mode_t mode = DIR_PERMS;
34 ret = mkdir(APP2SD_PATH, mode);
36 if (errno != EEXIST) {
37 _E("create directory failed," \
38 " error no is (%d)", errno);
39 return APP2EXT_ERROR_CREATE_DIRECTORY;
43 return APP2EXT_SUCCESS;
46 int app2sd_usr_pre_app_install(const char *pkgid, GList *dir_list, int size, uid_t uid)
50 char *device_node = NULL;
51 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
55 char application_path[FILENAME_MAX] = { 0, };
56 char loopback_device[FILENAME_MAX] = { 0, };
57 char *encoded_id = NULL;
58 int reqd_disk_size = size + ceil(size * 0.2);
60 /* validate the function parameter recieved */
61 if (pkgid == NULL || dir_list == NULL || size <= 0) {
62 _E("invalid function arguments");
63 return APP2EXT_ERROR_INVALID_ARGUMENTS;
66 /* check whether MMC is present or not */
67 ret = _app2sd_check_mmc_status();
69 _E("MMC not preset OR Not ready (%d)", ret);
70 return APP2EXT_ERROR_MMC_STATUS;
73 /* find available free memory in the MMC card */
74 ret = _app2sd_get_available_free_memory(MMC_PATH, &free_mmc_mem);
76 _E("unable to get available free memory in MMC (%d)",
78 return APP2EXT_ERROR_MMC_STATUS;
80 _D("size details for application installation:" \
81 " size=(%d)MB, reqd_disk_size=(%d)MB, free_mmc_size=(%d)MB",
82 size, reqd_disk_size, free_mmc_mem);
84 /* if avaialalbe free memory in MMC is less than required size + 5MB,
87 if ((reqd_disk_size + PKG_BUF_SIZE + MEM_BUF_SIZE) > free_mmc_mem) {
88 _E("insufficient memory in MMC for"
89 " application installation (%d)", ret);
90 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
93 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
94 if (encoded_id == NULL)
95 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
97 if (_is_global(uid)) {
98 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
99 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
100 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
101 APP2SD_PATH, encoded_id);
103 tzplatform_set_user(uid);
104 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
105 tzplatform_getenv(TZ_USER_APP), pkgid);
106 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
107 APP2SD_PATH, encoded_id);
108 tzplatform_reset_user();
112 ret = __app2sd_create_app2sd_directories(uid);
114 _E("failed to create app2sd dirs");
118 /* check same loopback_device existence */
119 result = (char *)_app2sd_find_associated_device(loopback_device);
120 if (result != NULL) {
121 _E("there is same associated File (%s)", loopback_device);
122 return APP2EXT_ERROR_SAME_LOOPBACK_DEVICE_EXISTS;
125 /* create a loopback device */
126 ret = _app2sd_create_loopback_device(pkgid, loopback_device,
127 (reqd_disk_size + PKG_BUF_SIZE));
129 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
130 ret = _app2sd_dmcrypt_setup_device(pkgid, loopback_device, false, uid);
132 _E("dmcrypt setup device error");
133 return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
136 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
137 false, uid, &device_node);
139 _E("dmcrypt open device error");
140 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
143 /* perform loopback encryption setup */
144 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
145 loopback_device, uid);
147 _E("loopback encryption setup failed");
148 _app2sd_delete_loopback_device(loopback_device);
149 return APP2EXT_ERROR_DO_LOSETUP;
152 /* check whether loopback device is associated
153 * with device node or not
155 devi = _app2sd_find_associated_device_node(loopback_device);
157 _E("finding associated device node failed");
158 ret = APP2EXT_ERROR_DO_LOSETUP;
163 /* format the loopback file system */
164 ret = _app2sd_create_file_system(device_node);
166 _E("creating FS failed failed");
167 ret = APP2EXT_ERROR_CREATE_FS;
171 /* mount the loopback encrypted pseudo device on application
172 * installation path as with Read Write permission
174 ret = _app2sd_mount_app_content(application_path, pkgid,
175 device_node, MOUNT_TYPE_RW, dir_list,
176 APP2SD_PRE_INSTALL, uid);
178 _E("mounting dev path to app install path failed");
179 ret = APP2EXT_ERROR_MOUNT_PATH;
184 ret = APP2EXT_SUCCESS;
189 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
190 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
192 _E("close dmcrypt device error(%d)", ret);
193 _app2sd_delete_loopback_device(loopback_device);
195 result = _app2sd_detach_loop_device(device_node);
200 _app2sd_delete_loopback_device(loopback_device);
210 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
220 int app2sd_usr_post_app_install(const char *pkgid,
221 app2ext_status install_status, uid_t uid)
223 char *device_name = NULL;
224 char application_path[FILENAME_MAX] = { 0, };
225 char loopback_device[FILENAME_MAX] = { 0, };
226 char *encoded_id = NULL;
227 int ret = APP2EXT_SUCCESS;
230 /* validate the function parameter recieved */
231 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
232 || install_status > APP2EXT_STATUS_SUCCESS) {
233 _E("invalid func parameters");
234 return APP2EXT_ERROR_INVALID_ARGUMENTS;
237 /* check whether MMC is present or not */
238 ret = _app2sd_check_mmc_status();
240 _E("MMC not present OR Not ready (%d)", ret);
241 return APP2EXT_ERROR_MMC_STATUS;
245 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
246 if (encoded_id == NULL)
247 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
249 if (_is_global(uid)) {
250 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
251 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
252 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
253 APP2SD_PATH, encoded_id);
255 tzplatform_set_user(uid);
256 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
257 tzplatform_getenv(TZ_USER_APP), pkgid);
258 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
259 APP2SD_PATH, encoded_id);
260 tzplatform_reset_user();
264 /* get the associated device node for SD card applicationer */
265 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
267 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
269 return APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE;
271 device_name = _app2sd_find_associated_device_node(loopback_device);
272 if (NULL == device_name)
273 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
276 ret = _app2sd_unmount_app_content(application_path);
282 _E("unable to unmount the app content (%d)", ret);
283 return APP2EXT_ERROR_UNMOUNT;
286 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
287 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
293 _E("close dmcrypt device error(%d)", ret);
297 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
303 _E("unable to detach the loopback encryption setup" \
304 " for the application");
305 return APP2EXT_ERROR_UNMOUNT;
314 /* take appropriate action based on
315 * installation status of application package
317 if (install_status == APP2EXT_STATUS_FAILED) {
318 /* delete the loopback device from the SD card */
319 ret = _app2sd_delete_loopback_device(loopback_device);
321 _E("unable to delete the loopback device from the SD Card");
322 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
324 ret = _app2sd_remove_info_from_db(pkgid, uid);
326 _E("unable to delete info");
328 ret = _app2sd_delete_directory(application_path);
330 _E("unable to delete the directory (%s)", application_path);
332 /* if the status is success, then update installed storage
333 * to pkgmgr_parser db
335 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
336 INSTALL_EXTERNAL, uid);
337 if (pkgmgr_ret < 0) {
338 _E("fail to update installed location " \
339 "to db[%s, %d] of uid(%d), pkgmgr ret(%d)",
340 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
341 return APP2EXT_ERROR_PKGMGR_ERROR;
348 int app2sd_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
350 int ret = APP2EXT_SUCCESS;
351 char application_path[FILENAME_MAX] = { 0, };
352 char loopback_device[FILENAME_MAX] = { 0, };
353 char *encoded_id = NULL;
354 char *device_node = NULL;
355 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
360 /* validate the function parameter recieved */
362 _E("invalid function arguments to app launch setup");
363 return APP2EXT_ERROR_INVALID_ARGUMENTS;
366 /* check whether MMC is present or not */
367 ret = _app2sd_check_mmc_status();
369 _E("MMC not preset OR Not ready (%d)", ret);
370 return APP2EXT_ERROR_MMC_STATUS;
373 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
374 if (encoded_id == NULL)
375 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
377 /* check app entry is there in sd card or not. */
378 if (_is_global(uid)) {
379 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
380 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
381 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
382 APP2SD_PATH, encoded_id);
384 tzplatform_set_user(uid);
385 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
386 tzplatform_getenv(TZ_USER_APP), pkgid);
387 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
388 APP2SD_PATH, encoded_id);
389 tzplatform_reset_user();
393 fp = fopen(loopback_device, "r+");
395 _E("app entry is not present in SD Card");
396 return APP2EXT_ERROR_INVALID_PACKAGE;
400 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
402 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
404 _E("device_node(%s_%d) already associated", pkgid, uid);
405 return APP2EXT_ERROR_ALREADY_MOUNTED;
408 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
409 false, uid, &device_node);
411 _E("dmcrypt open device error(%d)", ret);
412 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
415 result = (char *)_app2sd_find_associated_device(loopback_device);
416 /* process the string */
417 if ((result != NULL) && strstr(result, "/dev") != NULL) {
418 _E("already associated");
421 return APP2EXT_ERROR_ALREADY_MOUNTED;
424 /* do loopback setup */
425 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
426 loopback_device, uid);
427 if (device_node == NULL) {
428 _E("loopback encryption setup failed");
429 return APP2EXT_ERROR_DO_LOSETUP;
434 ret = _app2sd_mount_app_content(application_path, pkgid,
435 device_node, MOUNT_TYPE_RD, NULL, APP2SD_APP_LAUNCH, uid);
442 return APP2EXT_ERROR_MOUNT_PATH;
453 static int _app2sd_application_handler(const pkgmgrinfo_appinfo_h handle, void *data)
458 uid_t uid = *(uid_t *)data;
460 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
462 _E("failed to get appid");
463 return APP2EXT_ERROR_PKGMGR_ERROR;
466 _D("appid(%s), uid(%d)", appid, uid);
468 ret = aul_app_is_running_for_uid(appid, uid);
470 return APP2EXT_SUCCESS;
472 pid = aul_app_get_pid_for_uid(appid, uid);
474 _E("failed to get pid");
475 return APP2EXT_ERROR_KILLAPP_ERROR;
478 ret = aul_terminate_pid_sync_for_uid(pid, uid);
479 if (ret != AUL_R_OK) {
480 _E("failed to kill app");
481 return APP2EXT_ERROR_KILLAPP_ERROR;
484 return APP2EXT_SUCCESS;
487 static int _app2sd_kill_running_app(const char *pkgid, uid_t uid)
490 pkgmgrinfo_pkginfo_h handle;
492 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
494 _E("failed to get pkginfo");
495 return APP2EXT_ERROR_PKGMGR_ERROR;
498 ret = pkgmgrinfo_appinfo_get_usr_list(handle,
499 PMINFO_ALL_APP, _app2sd_application_handler, &uid, uid);
501 _E("failed to get appinfo");
502 return APP2EXT_ERROR_PKGMGR_ERROR;
505 ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
507 _E("failed to destroy pkginfo");
508 return APP2EXT_ERROR_PKGMGR_ERROR;
511 return APP2EXT_SUCCESS;
514 int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
516 int ret = APP2EXT_SUCCESS;
517 char application_path[FILENAME_MAX] = { 0, };
518 char loopback_device[FILENAME_MAX] = { 0, };
519 char *encoded_id = NULL;
523 /* validate the function parameter recieved */
525 _E("invalid function arguments to app launch setup");
526 return APP2EXT_ERROR_INVALID_ARGUMENTS;
529 _app2sd_kill_running_app(pkgid, uid);
531 /* check whether MMC is present or not */
532 ret = _app2sd_check_mmc_status();
534 _W("MMC not preset OR Not ready (%d)", ret);
538 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
539 if (encoded_id == NULL)
540 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
542 /* check app entry is there in sd card or not. */
543 if (_is_global(uid)) {
544 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
545 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
546 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
547 APP2SD_PATH, encoded_id);
549 tzplatform_set_user(uid);
550 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
551 tzplatform_getenv(TZ_USER_APP), pkgid);
552 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
553 APP2SD_PATH, encoded_id);
554 tzplatform_reset_user();
559 fp = fopen(loopback_device, "r+");
561 _E("app entry is not present in SD Card");
562 return APP2EXT_ERROR_INVALID_PACKAGE;
567 ret = _app2sd_unmount_app_content(application_path);
569 _E("unable to unmount the SD application");
570 return APP2EXT_ERROR_UNMOUNT;
573 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
574 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
576 _E("close dmcrypt device error(%d)", ret);
578 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
580 _E("unable to remove loopback setup");
581 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
588 int app2sd_usr_pre_app_uninstall(const char *pkgid, uid_t uid)
590 int ret = APP2EXT_SUCCESS;
591 char application_path[FILENAME_MAX] = { 0, };
592 char loopback_device[FILENAME_MAX] = { 0, };
593 char *encoded_id = NULL;
594 char *device_node = NULL;
597 /* validate the function parameter recieved */
599 _E("invalid function arguments to app launch setup");
600 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
604 /* check whether MMC is present or not */
605 ret = _app2sd_check_mmc_status();
607 _E("MMC not preset OR Not ready (%d)", ret);
608 ret = APP2EXT_ERROR_MMC_STATUS;
612 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
613 if (encoded_id == NULL)
614 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
616 if (_is_global(uid)) {
617 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
618 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
619 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
620 APP2SD_PATH, encoded_id);
622 tzplatform_set_user(uid);
623 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
624 tzplatform_getenv(TZ_USER_APP), pkgid);
625 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
626 APP2SD_PATH, encoded_id);
627 tzplatform_reset_user();
631 /* check app entry is there in sd card or not. */
632 fp = fopen(loopback_device, "r+");
634 _E("app entry is not present in SD Card");
635 ret = APP2EXT_ERROR_INVALID_PACKAGE;
640 /* get the associated device node for SD card applicationer */
641 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
643 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
645 device_node = _app2sd_find_associated_device_node(loopback_device);
647 if (NULL == device_node) {
648 /* do loopback setup */
649 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
650 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
651 false, uid, &device_node);
653 _E("dmcrypt open device error(%d)", ret);
654 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
657 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
658 loopback_device, uid);
659 if (device_node == NULL) {
660 _E("loopback encryption setup failed");
661 ret = APP2EXT_ERROR_DO_LOSETUP;
666 ret = _app2sd_mount_app_content(application_path, pkgid,
667 device_node, MOUNT_TYPE_RW, NULL,
668 APP2SD_PRE_UNINSTALL, uid);
675 ret = APP2EXT_ERROR_MOUNT_PATH;
680 ret = _app2sd_mount_app_content(application_path, pkgid,
681 device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
682 APP2SD_PRE_UNINSTALL, uid);
684 _E("remount failed");
689 ret = APP2EXT_ERROR_MOUNT_PATH;
702 int app2sd_usr_post_app_uninstall(const char *pkgid, uid_t uid)
704 char application_path[FILENAME_MAX] = { 0, };
705 char loopback_device[FILENAME_MAX] = { 0, };
706 char *encoded_id = NULL;
707 int ret = APP2EXT_SUCCESS;
709 /* validate the function parameter recieved */
711 _E("invalid function arguments");
712 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
716 /* check whether MMC is present or not */
717 ret = _app2sd_check_mmc_status();
719 _E("MMC not preset OR Not ready (%d)", ret);
720 ret = APP2EXT_ERROR_MMC_STATUS;
724 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
725 if (encoded_id == NULL)
726 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
728 if (_is_global(uid)) {
729 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
730 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
731 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
732 APP2SD_PATH, encoded_id);
734 tzplatform_set_user(uid);
735 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
736 tzplatform_getenv(TZ_USER_APP), pkgid);
737 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
738 APP2SD_PATH, encoded_id);
739 tzplatform_reset_user();
743 /* unmount the loopback encrypted pseudo device from
744 * the application installation path
746 ret = _app2sd_unmount_app_content(application_path);
748 _E("unable to unmount the app content (%d)", ret);
749 ret = APP2EXT_ERROR_UNMOUNT;
752 /* detach the loopback encryption setup for the application */
753 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
754 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
756 _E("close dmcrypt device error(%d)", ret);
760 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
762 _E("unable to Detach the loopback encryption setup" \
763 " for the application");
764 ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
769 /* delete the loopback device from the SD card */
770 ret = _app2sd_delete_loopback_device(loopback_device);
772 _E("unable to delete the " \
773 "loopback device from the SD Card");
774 ret = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
778 ret = _app2sd_delete_directory(application_path);
780 _E("unable to delete the directory (%s)",
785 /* remove encryption password from DB */
786 ret = _app2sd_initialize_db();
788 _E("app2sd db initialize failed");
789 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
793 ret = _app2sd_remove_info_from_db(pkgid, uid);
795 _E("cannot remove info from db");
796 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
804 int app2sd_usr_pre_move_installed_app(const char *pkgid,
805 GList *dir_list, app2ext_move_type move_type, uid_t uid)
810 /* validate function arguments */
811 if (pkgid == NULL || dir_list == NULL
812 || move_type < APP2EXT_MOVE_TO_EXT
813 || move_type > APP2EXT_MOVE_TO_PHONE) {
814 _E("invalid function arguments");
815 return APP2EXT_ERROR_INVALID_ARGUMENTS;
818 ret = __app2sd_create_app2sd_directories(uid);
820 _E("failed to create app2sd dirs");
824 ret = _app2sd_usr_move_app(pkgid, move_type, dir_list, uid);
826 _D("unable to move application");
830 /* if move is completed, then update installed storage to pkgmgr_parser db */
831 if (move_type == APP2EXT_MOVE_TO_EXT) {
832 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
833 INSTALL_EXTERNAL, uid);
834 if (pkgmgr_ret < 0) {
835 _E("failed to update installed location to db " \
836 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
837 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
838 return APP2EXT_ERROR_PKGMGR_ERROR;
841 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
842 INSTALL_INTERNAL, uid);
843 if (pkgmgr_ret < 0) {
844 _E("failed to update installed location to db " \
845 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
846 pkgid, INSTALL_INTERNAL, uid, pkgmgr_ret);
847 return APP2EXT_ERROR_PKGMGR_ERROR;
851 return APP2EXT_SUCCESS;
854 int app2sd_usr_post_move_installed_app(const char *pkgid,
855 app2ext_move_type move_type, uid_t uid)
858 char application_path[FILENAME_MAX] = { 0, };
859 char loopback_device[FILENAME_MAX] = { 0, };
860 char *encoded_id = NULL;
862 /* validate function arguments */
863 if (pkgid == NULL || move_type < APP2EXT_MOVE_TO_EXT
864 || move_type > APP2EXT_MOVE_TO_PHONE) {
865 _E("invalid function arguments");
866 return APP2EXT_ERROR_INVALID_ARGUMENTS;
869 if (move_type == APP2EXT_MOVE_TO_PHONE)
870 return APP2EXT_SUCCESS;
872 /* check whether MMC is present or not */
873 ret = _app2sd_check_mmc_status();
875 _E("MMC not preset OR Not ready(%d)", ret);
876 return APP2EXT_ERROR_MMC_STATUS;
879 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
880 if (encoded_id == NULL)
881 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
883 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
884 APP2SD_PATH, encoded_id);
886 if (_is_global(uid)) {
887 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
888 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
890 tzplatform_set_user(uid);
891 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
892 tzplatform_getenv(TZ_USER_APP), pkgid);
893 tzplatform_reset_user();
896 ret = _app2sd_unmount_app_content(application_path);
898 _E("unmount error (%d)", ret);
900 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
901 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
903 _E("close dmcrypt device error(%d)", ret);
905 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
907 _E("unable to detach loopback setup for (%s)",
912 return APP2EXT_SUCCESS;
915 int app2sd_usr_pre_app_upgrade(const char *pkgid, GList *dir_list,
918 int ret = APP2EXT_SUCCESS;
919 char loopback_device[FILENAME_MAX] = { 0, };
920 char application_path[FILENAME_MAX] = { 0, };
921 char temp_uid[32] = { 0, };
922 char *temp_pkgid = NULL;
923 char *temp_loopback_device = NULL;
924 char *temp_application_path = NULL;
925 char *device_node = NULL;
926 char *encoded_id = NULL;
927 char *temp_encoded_id = NULL;
929 unsigned long long curr_size = 0;
931 int reqd_disk_size = size + ceil(size * 0.2);
933 /* validate function arguments*/
934 if (pkgid == NULL || dir_list == NULL || size <= 0) {
935 _E("invalid function arguments");
936 return APP2EXT_ERROR_INVALID_ARGUMENTS;
939 /* check whether MMC is present or not */
940 ret = _app2sd_check_mmc_status();
942 _E("MMC not preset OR Not ready (%d)", ret);
943 return APP2EXT_ERROR_MMC_STATUS;
946 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
947 if (encoded_id == NULL)
948 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
950 if (_is_global(uid)) {
951 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
952 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
953 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
954 APP2SD_PATH, encoded_id);
956 tzplatform_set_user(uid);
957 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
958 tzplatform_getenv(TZ_USER_APP), pkgid);
959 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
960 APP2SD_PATH, encoded_id);
961 tzplatform_reset_user();
965 /* check app entry is there in sd card or not. */
966 fp = fopen(loopback_device, "r+");
968 _E("app entry is not present in SD Card");
969 return APP2EXT_ERROR_INVALID_PACKAGE;
973 /* get installed app size*/
974 curr_size = _app2sd_calculate_file_size(loopback_device);
975 curr_size = (curr_size) / (1024 * 1024);
976 if (curr_size == 0) {
977 _E("app entry is not present in SD Card");
978 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
980 if ((int)curr_size < reqd_disk_size) {
981 len = strlen(pkgid) + strlen(".new");
982 temp_pkgid = calloc(len + 1, sizeof(char));
983 if (temp_pkgid == NULL) {
984 _E("memory alloc failed");
985 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
987 snprintf(temp_pkgid, len + 1, "%s.new", pkgid);
989 if (_is_global(uid)) {
990 len = strlen(tzplatform_getenv(TZ_SYS_RW_APP)) + strlen(temp_pkgid) + 1;
991 temp_application_path = calloc(len + 1, sizeof(char));
992 if (temp_application_path == NULL) {
993 _E("memory alloc failed");
995 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
997 snprintf(temp_application_path, len + 1, "%s/%s",
998 tzplatform_getenv(TZ_SYS_RW_APP), temp_pkgid);
1000 temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1001 if (temp_encoded_id == NULL) {
1003 free(temp_application_path);
1004 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1006 len = strlen(APP2SD_PATH) + strlen(temp_encoded_id) + 1;
1007 temp_loopback_device = calloc(len + 1, sizeof(char));
1008 if (temp_loopback_device == NULL) {
1009 _E("memory alloc failed");
1011 free(temp_application_path);
1012 free(temp_encoded_id);
1013 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1015 snprintf(temp_loopback_device, len + 1, "%s/%s",
1016 APP2SD_PATH, temp_encoded_id);
1017 free(temp_encoded_id);
1019 tzplatform_set_user(uid);
1020 len = strlen(tzplatform_getenv(TZ_USER_APP)) + strlen(temp_pkgid) + 1;
1021 temp_application_path = calloc(len + 1, sizeof(char));
1022 if (temp_application_path == NULL) {
1023 _E("memory alloc failed");
1025 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1027 snprintf(temp_application_path, len + 1, "%s/%s",
1028 tzplatform_getenv(TZ_USER_APP), temp_pkgid);
1030 temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1031 if (temp_encoded_id == NULL) {
1033 free(temp_application_path);
1034 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1036 snprintf(temp_uid, 32, "%d", uid);
1037 len = strlen(APP2SD_PATH) + strlen(temp_uid) + strlen(temp_encoded_id) + 2;
1038 temp_loopback_device = calloc(len + 1, sizeof(char));
1039 if (temp_loopback_device == NULL) {
1040 _E("memory alloc failed");
1042 free(temp_application_path);
1043 free(temp_encoded_id);
1044 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1046 snprintf(temp_loopback_device, len + 1, "%s/%s",
1047 APP2SD_PATH, temp_encoded_id);
1048 free(temp_encoded_id);
1049 tzplatform_reset_user();
1051 ret = _app2sd_update_loopback_device_size(pkgid,
1052 loopback_device, application_path, temp_pkgid,
1053 temp_loopback_device, temp_application_path,
1054 reqd_disk_size, dir_list, uid);
1056 free(temp_application_path);
1057 free(temp_loopback_device);
1058 if (APP2EXT_SUCCESS != ret) {
1059 _E("failed to update loopback device size");
1064 /* get the associated device node for SD card applicationer */
1065 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1067 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1069 device_node = _app2sd_find_associated_device_node(loopback_device);
1071 if (NULL == device_node) {
1072 /* do loopback setup */
1073 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1074 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
1075 false, uid, &device_node);
1077 _E("dmcrypt open device error");
1078 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
1081 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
1082 loopback_device, uid);
1083 if (device_node == NULL) {
1084 _E("loopback encryption setup failed");
1085 return APP2EXT_ERROR_DO_LOSETUP;
1090 ret = _app2sd_mount_app_content(application_path, pkgid,
1091 device_node, MOUNT_TYPE_RW, dir_list,
1092 APP2SD_PRE_UPGRADE, uid);
1099 return APP2EXT_ERROR_MOUNT_PATH;
1102 /* do re-mounting */
1103 ret = _app2sd_mount_app_content(application_path, pkgid,
1104 device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
1105 APP2SD_PRE_UPGRADE, uid);
1107 _E("remount failed");
1112 return APP2EXT_ERROR_MOUNT_PATH;
1123 int app2sd_usr_post_app_upgrade(const char *pkgid,
1124 app2ext_status install_status, uid_t uid)
1126 char *device_name = NULL;
1127 char loopback_device[FILENAME_MAX] = { 0, };
1128 char application_path[FILENAME_MAX] = { 0, };
1129 char *encoded_id = NULL;
1130 int ret = APP2EXT_SUCCESS;
1132 /* validate the function parameter recieved */
1133 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
1134 || install_status > APP2EXT_STATUS_SUCCESS) {
1135 _E("invalid func parameters");
1136 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1139 /* check whether MMC is present or not */
1140 ret = _app2sd_check_mmc_status();
1142 _E("MMC not preset OR Not ready (%d)", ret);
1143 return APP2EXT_ERROR_MMC_STATUS;
1146 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1147 if (encoded_id == NULL)
1148 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1150 if (_is_global(uid)) {
1151 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1152 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1153 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1154 APP2SD_PATH, encoded_id);
1156 tzplatform_set_user(uid);
1157 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1158 tzplatform_getenv(TZ_USER_APP), pkgid);
1159 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1160 APP2SD_PATH, encoded_id);
1161 tzplatform_reset_user();
1165 /* get the associated device node for SD card applicationer */
1166 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1168 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1170 _E("could not find associated dmcrypt device node" \
1171 " (%s_%d)", pkgid, uid);
1172 return APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE;
1175 device_name = _app2sd_find_associated_device_node(loopback_device);
1176 if (NULL == device_name)
1177 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
1180 ret = _app2sd_unmount_app_content(application_path);
1186 _E("unable to unmount the app content (%d)", ret);
1187 return APP2EXT_ERROR_UNMOUNT;
1190 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1191 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1197 _E("close dmcrypt device error(%d)", ret);
1198 return APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
1201 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
1207 _E("unable to detach the loopback encryption " \
1208 "setup for the application");
1209 return APP2EXT_ERROR_UNMOUNT;
1221 int app2sd_usr_force_clean(const char *pkgid, uid_t uid)
1223 char loopback_device[FILENAME_MAX] = { 0, };
1224 char application_path[FILENAME_MAX] = { 0, };
1225 char *encoded_id = NULL;
1226 int ret = APP2EXT_SUCCESS;
1228 /* validate the function parameter recieved */
1229 if (pkgid == NULL) {
1230 _E("invalid func parameters");
1231 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1236 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1237 if (encoded_id == NULL)
1238 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1240 if (_is_global(uid)) {
1241 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1242 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1243 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1244 APP2SD_PATH, encoded_id);
1246 tzplatform_set_user(uid);
1247 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1248 tzplatform_getenv(TZ_USER_APP), pkgid);
1249 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1250 APP2SD_PATH, encoded_id);
1251 tzplatform_reset_user();
1255 ret = _app2sd_force_clean(pkgid, application_path, loopback_device, uid);
1260 int app2sd_enable_full_pkg(void)
1262 int ret = APP2EXT_SUCCESS;
1264 char buf[FILENAME_MAX] = { 0, };
1265 char loopback_device[FILENAME_MAX] = { 0, };
1267 struct dirent entry;
1268 struct dirent *result = NULL;
1272 dir = opendir(APP2SD_PATH);
1274 strerror_r(errno, buf, sizeof(buf));
1275 _E("failed to opendir (%s)", buf);
1276 return APP2EXT_ERROR_OPEN_DIR;
1279 ret = _app2sd_initialize_db();
1281 _E("app2sd db initialize failed");
1283 return APP2EXT_ERROR_SQLITE_REGISTRY;
1286 for (rc = readdir_r(dir, &entry, &result);
1287 rc == 0 && result != NULL;
1288 rc = readdir_r(dir, &entry, &result)) {
1289 if (strcmp(entry.d_name, ".") == 0 ||
1290 strcmp(entry.d_name, "..") == 0)
1292 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1293 APP2SD_PATH, entry.d_name);
1294 ret = _app2sd_get_info_from_db(loopback_device,
1297 _E("failed to get info from db");
1301 _D("pkgid(%s), uid(%d)", pkgid, uid);
1302 ret = app2sd_usr_on_demand_setup_init(pkgid, uid);
1304 _E("error(%d)", ret);
1321 static int _app2sd_info_cb_func(const char *pkgid, uid_t uid)
1323 int ret = APP2EXT_SUCCESS;
1326 _D("pkgid(%s), uid(%d)", pkgid, uid);
1327 ret = app2sd_usr_on_demand_setup_exit(pkgid, uid);
1329 _E("error(%d)", ret);
1335 int app2sd_disable_full_pkg(void)
1337 int ret = APP2EXT_SUCCESS;
1339 ret = _app2sd_initialize_db();
1341 _E("app2sd db initialize failed");
1342 return APP2EXT_ERROR_SQLITE_REGISTRY;
1345 ret = _app2sd_get_foreach_info_from_db((app2sd_info_cb)_app2sd_info_cb_func);
1347 _E("disable full pkg error(%d)", ret);