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;
852 return APP2EXT_SUCCESS;
855 int app2sd_usr_post_move_installed_app(const char *pkgid,
856 app2ext_move_type move_type, uid_t uid)
859 char application_path[FILENAME_MAX] = { 0, };
860 char loopback_device[FILENAME_MAX] = { 0, };
861 char *encoded_id = NULL;
863 /* validate function arguments */
864 if (pkgid == NULL || move_type < APP2EXT_MOVE_TO_EXT
865 || move_type > APP2EXT_MOVE_TO_PHONE) {
866 _E("invalid function arguments");
867 return APP2EXT_ERROR_INVALID_ARGUMENTS;
870 if (move_type == APP2EXT_MOVE_TO_PHONE)
871 return APP2EXT_SUCCESS;
873 /* check whether MMC is present or not */
874 ret = _app2sd_check_mmc_status();
876 _E("MMC not preset OR Not ready(%d)", ret);
877 return APP2EXT_ERROR_MMC_STATUS;
880 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
881 if (encoded_id == NULL)
882 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
884 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
885 APP2SD_PATH, encoded_id);
887 if (_is_global(uid)) {
888 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
889 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
891 tzplatform_set_user(uid);
892 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
893 tzplatform_getenv(TZ_USER_APP), pkgid);
894 tzplatform_reset_user();
897 ret = _app2sd_unmount_app_content(application_path);
899 _E("unmount error (%d)", ret);
901 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
902 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
904 _E("close dmcrypt device error(%d)", ret);
906 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
908 _E("unable to detach loopback setup for (%s)",
913 return APP2EXT_SUCCESS;
916 int app2sd_usr_pre_app_upgrade(const char *pkgid, GList *dir_list,
919 int ret = APP2EXT_SUCCESS;
920 char loopback_device[FILENAME_MAX] = { 0, };
921 char application_path[FILENAME_MAX] = { 0, };
922 char temp_uid[32] = { 0, };
923 char *temp_pkgid = NULL;
924 char *temp_loopback_device = NULL;
925 char *temp_application_path = NULL;
926 char *device_node = NULL;
927 char *encoded_id = NULL;
928 char *temp_encoded_id = NULL;
930 unsigned long long curr_size = 0;
932 int reqd_disk_size = size + ceil(size * 0.2);
934 /* validate function arguments*/
935 if (pkgid == NULL || dir_list == NULL || size <= 0) {
936 _E("invalid function arguments");
937 return APP2EXT_ERROR_INVALID_ARGUMENTS;
940 /* check whether MMC is present or not */
941 ret = _app2sd_check_mmc_status();
943 _E("MMC not preset OR Not ready (%d)", ret);
944 return APP2EXT_ERROR_MMC_STATUS;
947 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
948 if (encoded_id == NULL)
949 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
951 if (_is_global(uid)) {
952 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
953 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
954 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
955 APP2SD_PATH, encoded_id);
957 tzplatform_set_user(uid);
958 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
959 tzplatform_getenv(TZ_USER_APP), pkgid);
960 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
961 APP2SD_PATH, encoded_id);
962 tzplatform_reset_user();
966 /* check app entry is there in sd card or not. */
967 fp = fopen(loopback_device, "r+");
969 _E("app entry is not present in SD Card");
970 return APP2EXT_ERROR_INVALID_PACKAGE;
974 /* get installed app size*/
975 curr_size = _app2sd_calculate_file_size(loopback_device);
976 curr_size = (curr_size) / (1024 * 1024);
977 if (curr_size == 0) {
978 _E("app entry is not present in SD Card");
979 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
981 if ((int)curr_size < reqd_disk_size) {
982 len = strlen(pkgid) + strlen(".new");
983 temp_pkgid = calloc(len + 1, sizeof(char));
984 if (temp_pkgid == NULL) {
985 _E("memory alloc failed");
986 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
988 snprintf(temp_pkgid, len + 1, "%s.new", pkgid);
990 if (_is_global(uid)) {
991 len = strlen(tzplatform_getenv(TZ_SYS_RW_APP)) + strlen(temp_pkgid) + 1;
992 temp_application_path = calloc(len + 1, sizeof(char));
993 if (temp_application_path == NULL) {
994 _E("memory alloc failed");
996 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
998 snprintf(temp_application_path, len + 1, "%s/%s",
999 tzplatform_getenv(TZ_SYS_RW_APP), temp_pkgid);
1001 temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1002 if (temp_encoded_id == NULL) {
1004 free(temp_application_path);
1005 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1007 len = strlen(APP2SD_PATH) + strlen(temp_encoded_id) + 1;
1008 temp_loopback_device = calloc(len + 1, sizeof(char));
1009 if (temp_loopback_device == NULL) {
1010 _E("memory alloc failed");
1012 free(temp_application_path);
1013 free(temp_encoded_id);
1014 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1016 snprintf(temp_loopback_device, len + 1, "%s/%s",
1017 APP2SD_PATH, temp_encoded_id);
1018 free(temp_encoded_id);
1020 tzplatform_set_user(uid);
1021 len = strlen(tzplatform_getenv(TZ_USER_APP)) + strlen(temp_pkgid) + 1;
1022 temp_application_path = calloc(len + 1, sizeof(char));
1023 if (temp_application_path == NULL) {
1024 _E("memory alloc failed");
1026 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1028 snprintf(temp_application_path, len + 1, "%s/%s",
1029 tzplatform_getenv(TZ_USER_APP), temp_pkgid);
1031 temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1032 if (temp_encoded_id == NULL) {
1034 free(temp_application_path);
1035 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1037 snprintf(temp_uid, 32, "%d", uid);
1038 len = strlen(APP2SD_PATH) + strlen(temp_uid) + strlen(temp_encoded_id) + 2;
1039 temp_loopback_device = calloc(len + 1, sizeof(char));
1040 if (temp_loopback_device == NULL) {
1041 _E("memory alloc failed");
1043 free(temp_application_path);
1044 free(temp_encoded_id);
1045 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1047 snprintf(temp_loopback_device, len + 1, "%s/%s",
1048 APP2SD_PATH, temp_encoded_id);
1049 free(temp_encoded_id);
1050 tzplatform_reset_user();
1052 ret = _app2sd_update_loopback_device_size(pkgid,
1053 loopback_device, application_path, temp_pkgid,
1054 temp_loopback_device, temp_application_path,
1055 reqd_disk_size, dir_list, uid);
1057 free(temp_application_path);
1058 free(temp_loopback_device);
1059 if (APP2EXT_SUCCESS != ret) {
1060 _E("failed to update loopback device size");
1065 /* get the associated device node for SD card applicationer */
1066 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1068 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1070 device_node = _app2sd_find_associated_device_node(loopback_device);
1072 if (NULL == device_node) {
1073 /* do loopback setup */
1074 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1075 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
1076 false, uid, &device_node);
1078 _E("dmcrypt open device error");
1079 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
1082 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
1083 loopback_device, uid);
1084 if (device_node == NULL) {
1085 _E("loopback encryption setup failed");
1086 return APP2EXT_ERROR_DO_LOSETUP;
1091 ret = _app2sd_mount_app_content(application_path, pkgid,
1092 device_node, MOUNT_TYPE_RW, dir_list,
1093 APP2SD_PRE_UPGRADE, uid);
1100 return APP2EXT_ERROR_MOUNT_PATH;
1103 /* do re-mounting */
1104 ret = _app2sd_mount_app_content(application_path, pkgid,
1105 device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
1106 APP2SD_PRE_UPGRADE, uid);
1108 _E("remount failed");
1113 return APP2EXT_ERROR_MOUNT_PATH;
1124 int app2sd_usr_post_app_upgrade(const char *pkgid,
1125 app2ext_status install_status, uid_t uid)
1127 char *device_name = NULL;
1128 char loopback_device[FILENAME_MAX] = { 0, };
1129 char application_path[FILENAME_MAX] = { 0, };
1130 char *encoded_id = NULL;
1131 int ret = APP2EXT_SUCCESS;
1133 /* validate the function parameter recieved */
1134 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
1135 || install_status > APP2EXT_STATUS_SUCCESS) {
1136 _E("invalid func parameters");
1137 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1140 /* check whether MMC is present or not */
1141 ret = _app2sd_check_mmc_status();
1143 _E("MMC not preset OR Not ready (%d)", ret);
1144 return APP2EXT_ERROR_MMC_STATUS;
1147 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1148 if (encoded_id == NULL)
1149 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1151 if (_is_global(uid)) {
1152 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1153 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1154 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1155 APP2SD_PATH, encoded_id);
1157 tzplatform_set_user(uid);
1158 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1159 tzplatform_getenv(TZ_USER_APP), pkgid);
1160 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1161 APP2SD_PATH, encoded_id);
1162 tzplatform_reset_user();
1166 /* get the associated device node for SD card applicationer */
1167 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1169 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1171 _E("could not find associated dmcrypt device node" \
1172 " (%s_%d)", pkgid, uid);
1173 return APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE;
1176 device_name = _app2sd_find_associated_device_node(loopback_device);
1177 if (NULL == device_name)
1178 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
1181 ret = _app2sd_unmount_app_content(application_path);
1187 _E("unable to unmount the app content (%d)", ret);
1188 return APP2EXT_ERROR_UNMOUNT;
1191 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1192 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1198 _E("close dmcrypt device error(%d)", ret);
1199 return APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
1202 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
1208 _E("unable to detach the loopback encryption " \
1209 "setup for the application");
1210 return APP2EXT_ERROR_UNMOUNT;
1222 int app2sd_usr_force_clean(const char *pkgid, uid_t uid)
1224 char loopback_device[FILENAME_MAX] = { 0, };
1225 char application_path[FILENAME_MAX] = { 0, };
1226 char *encoded_id = NULL;
1227 int ret = APP2EXT_SUCCESS;
1229 /* validate the function parameter recieved */
1230 if (pkgid == NULL) {
1231 _E("invalid func parameters");
1232 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1237 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1238 if (encoded_id == NULL)
1239 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1241 if (_is_global(uid)) {
1242 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1243 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1244 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1245 APP2SD_PATH, encoded_id);
1247 tzplatform_set_user(uid);
1248 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1249 tzplatform_getenv(TZ_USER_APP), pkgid);
1250 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1251 APP2SD_PATH, encoded_id);
1252 tzplatform_reset_user();
1256 ret = _app2sd_force_clean(pkgid, application_path, loopback_device, uid);
1261 int app2sd_enable_full_pkg(void)
1263 int ret = APP2EXT_SUCCESS;
1265 char buf[FILENAME_MAX] = { 0, };
1266 char loopback_device[FILENAME_MAX] = { 0, };
1268 struct dirent entry;
1269 struct dirent *result = NULL;
1273 dir = opendir(APP2SD_PATH);
1275 strerror_r(errno, buf, sizeof(buf));
1276 _E("failed to opendir (%s)", buf);
1277 return APP2EXT_ERROR_OPEN_DIR;
1280 ret = _app2sd_initialize_db();
1282 _E("app2sd db initialize failed");
1284 return APP2EXT_ERROR_SQLITE_REGISTRY;
1287 for (rc = readdir_r(dir, &entry, &result);
1288 rc == 0 && result != NULL;
1289 rc = readdir_r(dir, &entry, &result)) {
1290 if (strcmp(entry.d_name, ".") == 0 ||
1291 strcmp(entry.d_name, "..") == 0)
1293 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1294 APP2SD_PATH, entry.d_name);
1295 ret = _app2sd_get_info_from_db(loopback_device,
1298 _E("failed to get info from db");
1302 _D("pkgid(%s), uid(%d)", pkgid, uid);
1303 ret = app2sd_usr_on_demand_setup_init(pkgid, uid);
1305 _E("error(%d)", ret);
1322 static int _app2sd_info_cb_func(const char *pkgid, uid_t uid)
1324 int ret = APP2EXT_SUCCESS;
1327 _D("pkgid(%s), uid(%d)", pkgid, uid);
1328 ret = app2sd_usr_on_demand_setup_exit(pkgid, uid);
1330 _E("error(%d)", ret);
1336 int app2sd_disable_full_pkg(void)
1338 int ret = APP2EXT_SUCCESS;
1340 ret = _app2sd_initialize_db();
1342 _E("app2sd db initialize failed");
1343 return APP2EXT_ERROR_SQLITE_REGISTRY;
1346 ret = _app2sd_get_foreach_info_from_db((app2sd_info_cb)_app2sd_info_cb_func);
1348 _E("disable full pkg error(%d)", ret);