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, char *mmc_path)
32 char app2sd_path[FILENAME_MAX] = { 0, };
33 mode_t mode = DIR_PERMS;
35 snprintf(app2sd_path, FILENAME_MAX - 1, "%s/%s",
36 mmc_path, EXTIMG_DIR);
37 ret = mkdir(app2sd_path, mode);
39 if (errno != EEXIST) {
40 _E("create directory failed," \
41 " error no is (%d)", errno);
42 return APP2EXT_ERROR_CREATE_DIRECTORY;
46 return APP2EXT_SUCCESS;
49 int app2sd_usr_pre_app_install(const char *pkgid, GList *dir_list, int size, uid_t uid)
54 char *device_node = NULL;
55 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
59 char mmc_path[FILENAME_MAX] = { 0, };
60 char application_path[FILENAME_MAX] = { 0, };
61 char loopback_device[FILENAME_MAX] = { 0, };
62 char *encoded_id = NULL;
63 int reqd_disk_size = size + ceil(size * 0.2);
65 /* validate the function parameter recieved */
66 if (pkgid == NULL || dir_list == NULL || size <= 0) {
67 _E("invalid function arguments");
68 return APP2EXT_ERROR_INVALID_ARGUMENTS;
71 /* check whether MMC is present or not */
72 ret = _app2sd_check_mmc_status(&sdpath);
74 _E("MMC not present OR Not ready (%d)", ret);
75 return APP2EXT_ERROR_MMC_STATUS;
77 snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
81 /* find available free memory in the MMC card */
82 ret = _app2sd_get_available_free_memory(mmc_path, &free_mmc_mem);
84 _E("unable to get available free memory in MMC (%d)", ret);
85 return APP2EXT_ERROR_MMC_STATUS;
87 _D("size details for application installation:" \
88 " size=(%d)MB, reqd_disk_size=(%d)MB, free_mmc_size=(%d)MB",
89 size, reqd_disk_size, free_mmc_mem);
91 /* if avaialalbe free memory in MMC is less than required size + 5MB,
94 if ((reqd_disk_size + PKG_BUF_SIZE + MEM_BUF_SIZE) > free_mmc_mem) {
95 _E("insufficient memory in MMC for"
96 " application installation (%d)", ret);
97 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
100 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
101 if (encoded_id == NULL)
102 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
104 if (_is_global(uid)) {
105 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
106 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
107 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
108 mmc_path, EXTIMG_DIR, encoded_id);
110 tzplatform_set_user(uid);
111 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
112 tzplatform_getenv(TZ_USER_APP), pkgid);
113 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
114 mmc_path, EXTIMG_DIR, encoded_id);
115 tzplatform_reset_user();
119 ret = __app2sd_create_app2sd_directories(uid, mmc_path);
121 _E("failed to create app2sd dirs");
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)
221 int app2sd_usr_post_app_install(const char *pkgid,
222 app2ext_status install_status, uid_t uid)
224 char *device_name = NULL;
226 char mmc_path[FILENAME_MAX] = { 0, };
227 char application_path[FILENAME_MAX] = { 0, };
228 char application_mmc_path[FILENAME_MAX] = { 0, };
229 char loopback_device[FILENAME_MAX] = { 0, };
230 char *encoded_id = NULL;
231 int ret = APP2EXT_SUCCESS;
234 /* validate the function parameter recieved */
235 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
236 || install_status > APP2EXT_STATUS_SUCCESS) {
237 _E("invalid func parameters");
238 return APP2EXT_ERROR_INVALID_ARGUMENTS;
241 /* check whether MMC is present or not */
242 ret = _app2sd_check_mmc_status(&sdpath);
244 _E("MMC not present OR Not ready (%d)", ret);
245 return APP2EXT_ERROR_MMC_STATUS;
247 snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
251 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
252 if (encoded_id == NULL)
253 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
255 if (_is_global(uid)) {
256 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
257 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
258 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
259 mmc_path, EXTIMG_DIR, encoded_id);
261 tzplatform_set_user(uid);
262 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
263 tzplatform_getenv(TZ_USER_APP), pkgid);
264 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
265 mmc_path, EXTIMG_DIR, encoded_id);
266 tzplatform_reset_user();
269 snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/.mmc",
272 /* get the associated device node for SD card applicationer */
273 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
275 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
277 return APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE;
279 device_name = _app2sd_find_associated_device_node(loopback_device);
280 if (NULL == device_name)
281 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
284 ret = _app2sd_unmount_app_content(application_path);
290 _E("unable to unmount the app content (%d)", ret);
291 return APP2EXT_ERROR_UNMOUNT;
294 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
295 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
301 _E("close dmcrypt device error(%d)", ret);
305 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
311 _E("unable to detach the loopback encryption setup" \
312 " for the application");
313 return APP2EXT_ERROR_UNMOUNT;
322 /* take appropriate action based on
323 * installation status of application package
325 if (install_status == APP2EXT_STATUS_FAILED) {
326 /* delete the loopback device from the SD card */
327 ret = _app2sd_delete_loopback_device(loopback_device);
329 _E("unable to delete the loopback device from the SD Card");
330 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
332 ret = _app2sd_remove_info_from_db(pkgid, uid);
334 _E("unable to delete info");
336 ret = _app2sd_delete_directory(application_mmc_path);
338 _E("unable to delete the directory (%s)", application_path);
340 /* if the status is success, then update installed storage
341 * to pkgmgr_parser db
343 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
344 INSTALL_EXTERNAL, uid);
345 if (pkgmgr_ret < 0) {
346 _E("fail to update installed location " \
347 "to db[%s, %d] of uid(%d), pkgmgr ret(%d)",
348 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
349 return APP2EXT_ERROR_PKGMGR_ERROR;
357 int app2sd_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
359 int ret = APP2EXT_SUCCESS;
360 char mmc_path[FILENAME_MAX] = { 0, };
361 char application_path[FILENAME_MAX] = { 0, };
362 char loopback_device[FILENAME_MAX] = { 0, };
364 char *encoded_id = NULL;
365 char *device_node = NULL;
366 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
371 /* validate the function parameter recieved */
373 _E("invalid function arguments to app launch setup");
374 return APP2EXT_ERROR_INVALID_ARGUMENTS;
377 /* check whether MMC is present or not */
378 ret = _app2sd_check_mmc_status(&sdpath);
380 _E("MMC not present OR Not ready (%d)", ret);
381 return APP2EXT_ERROR_MMC_STATUS;
383 snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
386 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
387 if (encoded_id == NULL)
388 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
390 /* check app entry is there in sd card or not. */
391 if (_is_global(uid)) {
392 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
393 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
394 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
395 mmc_path, EXTIMG_DIR, encoded_id);
397 tzplatform_set_user(uid);
398 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
399 tzplatform_getenv(TZ_USER_APP), pkgid);
400 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
401 mmc_path, EXTIMG_DIR, encoded_id);
402 tzplatform_reset_user();
406 fp = fopen(loopback_device, "r+");
408 _E("app entry is not present in SD Card");
409 return APP2EXT_ERROR_INVALID_PACKAGE;
413 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
415 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
417 _E("device_node(%s_%d) already associated", pkgid, uid);
418 return APP2EXT_ERROR_ALREADY_MOUNTED;
421 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
422 false, uid, &device_node);
424 _E("dmcrypt open device error(%d)", ret);
425 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
428 result = (char *)_app2sd_find_associated_device(loopback_device);
429 /* process the string */
430 if ((result != NULL) && strstr(result, "/dev") != NULL) {
431 _E("already associated");
434 return APP2EXT_ERROR_ALREADY_MOUNTED;
437 /* do loopback setup */
438 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
439 loopback_device, uid);
440 if (device_node == NULL) {
441 _E("loopback encryption setup failed");
442 return APP2EXT_ERROR_DO_LOSETUP;
447 ret = _app2sd_mount_app_content(application_path, pkgid,
448 device_node, MOUNT_TYPE_RD, NULL, APP2SD_APP_LAUNCH, uid);
455 return APP2EXT_ERROR_MOUNT_PATH;
466 static int _app2sd_application_handler(const pkgmgrinfo_appinfo_h handle, void *data)
471 uid_t uid = *(uid_t *)data;
473 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
475 _E("failed to get appid");
476 return APP2EXT_ERROR_PKGMGR_ERROR;
479 _D("appid(%s), uid(%d)", appid, uid);
481 ret = aul_app_is_running_for_uid(appid, uid);
483 return APP2EXT_SUCCESS;
485 pid = aul_app_get_pid_for_uid(appid, uid);
487 _E("failed to get pid");
488 return APP2EXT_ERROR_KILLAPP_ERROR;
491 ret = aul_terminate_pid_sync_for_uid(pid, uid);
492 if (ret != AUL_R_OK) {
493 _E("failed to kill app");
494 return APP2EXT_ERROR_KILLAPP_ERROR;
497 return APP2EXT_SUCCESS;
500 static int _app2sd_kill_running_app(const char *pkgid, uid_t uid)
503 pkgmgrinfo_pkginfo_h handle;
505 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
507 _E("failed to get pkginfo");
508 return APP2EXT_ERROR_PKGMGR_ERROR;
511 ret = pkgmgrinfo_appinfo_get_usr_list(handle,
512 PMINFO_ALL_APP, _app2sd_application_handler, &uid, uid);
514 _E("failed to get appinfo");
515 return APP2EXT_ERROR_PKGMGR_ERROR;
518 ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
520 _E("failed to destroy pkginfo");
521 return APP2EXT_ERROR_PKGMGR_ERROR;
524 return APP2EXT_SUCCESS;
527 int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
529 int ret = APP2EXT_SUCCESS;
530 char mmc_path[FILENAME_MAX] = { 0, };
531 char application_path[FILENAME_MAX] = { 0, };
532 char loopback_device[FILENAME_MAX] = { 0, };
534 char *encoded_id = NULL;
538 /* validate the function parameter recieved */
540 _E("invalid function arguments to app launch setup");
541 return APP2EXT_ERROR_INVALID_ARGUMENTS;
544 _app2sd_kill_running_app(pkgid, uid);
546 /* check whether MMC is present or not */
547 ret = _app2sd_check_mmc_status(&sdpath);
549 _W("MMC not present OR Not ready (%d)", ret);
552 snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
555 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
556 if (encoded_id == NULL)
557 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
559 /* check app entry is there in sd card or not. */
560 if (_is_global(uid)) {
561 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
562 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
563 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
564 mmc_path, EXTIMG_DIR, encoded_id);
566 tzplatform_set_user(uid);
567 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
568 tzplatform_getenv(TZ_USER_APP), pkgid);
569 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
570 mmc_path, EXTIMG_DIR, encoded_id);
571 tzplatform_reset_user();
576 fp = fopen(loopback_device, "r+");
578 _E("app entry is not present in SD Card");
579 return APP2EXT_ERROR_INVALID_PACKAGE;
584 ret = _app2sd_unmount_app_content(application_path);
586 _E("unable to unmount the SD application");
587 return APP2EXT_ERROR_UNMOUNT;
590 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
591 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
593 _E("close dmcrypt device error(%d)", ret);
595 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
597 _E("unable to remove loopback setup");
598 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
605 int app2sd_usr_pre_app_uninstall(const char *pkgid, uid_t uid)
607 int ret = APP2EXT_SUCCESS;
608 char mmc_path[FILENAME_MAX] = { 0, };
609 char application_path[FILENAME_MAX] = { 0, };
610 char loopback_device[FILENAME_MAX] = { 0, };
612 char *encoded_id = NULL;
613 char *device_node = NULL;
616 /* validate the function parameter recieved */
618 _E("invalid function arguments to app launch setup");
619 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
623 /* check whether MMC is present or not */
624 ret = _app2sd_check_mmc_status(&sdpath);
626 _E("MMC not present OR Not ready (%d)", ret);
627 ret = APP2EXT_ERROR_MMC_STATUS;
630 snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
634 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
635 if (encoded_id == NULL)
636 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
638 if (_is_global(uid)) {
639 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
640 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
641 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
642 mmc_path, EXTIMG_DIR, encoded_id);
644 tzplatform_set_user(uid);
645 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
646 tzplatform_getenv(TZ_USER_APP), pkgid);
647 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
648 mmc_path, EXTIMG_DIR, encoded_id);
649 tzplatform_reset_user();
653 /* check app entry is there in sd card or not. */
654 fp = fopen(loopback_device, "r+");
656 _E("app entry is not present in SD Card");
657 ret = APP2EXT_ERROR_INVALID_PACKAGE;
662 /* get the associated device node for SD card applicationer */
663 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
665 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
667 device_node = _app2sd_find_associated_device_node(loopback_device);
669 if (NULL == device_node) {
670 /* do loopback setup */
671 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
672 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
673 false, uid, &device_node);
675 _E("dmcrypt open device error(%d)", ret);
676 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
679 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
680 loopback_device, uid);
681 if (device_node == NULL) {
682 _E("loopback encryption setup failed");
683 ret = APP2EXT_ERROR_DO_LOSETUP;
688 ret = _app2sd_mount_app_content(application_path, pkgid,
689 device_node, MOUNT_TYPE_RW, NULL,
690 APP2SD_PRE_UNINSTALL, uid);
697 ret = APP2EXT_ERROR_MOUNT_PATH;
702 ret = _app2sd_mount_app_content(application_path, pkgid,
703 device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
704 APP2SD_PRE_UNINSTALL, uid);
706 _E("remount failed");
711 ret = APP2EXT_ERROR_MOUNT_PATH;
725 int app2sd_usr_post_app_uninstall(const char *pkgid, uid_t uid)
727 char mmc_path[FILENAME_MAX] = { 0, };
728 char application_path[FILENAME_MAX] = { 0, };
729 char application_mmc_path[FILENAME_MAX] = { 0, };
730 char loopback_device[FILENAME_MAX] = { 0, };
732 char *encoded_id = NULL;
733 int ret = APP2EXT_SUCCESS;
735 /* validate the function parameter recieved */
737 _E("invalid function arguments");
738 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
742 /* check whether MMC is present or not */
743 ret = _app2sd_check_mmc_status(&sdpath);
745 _E("MMC not present OR Not ready (%d)", ret);
746 ret = APP2EXT_ERROR_MMC_STATUS;
749 snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
753 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
754 if (encoded_id == NULL)
755 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
757 if (_is_global(uid)) {
758 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
759 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
760 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
761 mmc_path, EXTIMG_DIR, encoded_id);
763 tzplatform_set_user(uid);
764 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
765 tzplatform_getenv(TZ_USER_APP), pkgid);
766 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
767 mmc_path, EXTIMG_DIR, encoded_id);
768 tzplatform_reset_user();
771 snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/.mmc",
774 /* unmount the loopback encrypted pseudo device from
775 * the application installation path
777 ret = _app2sd_unmount_app_content(application_path);
779 _E("unable to unmount the app content (%d)", ret);
780 ret = APP2EXT_ERROR_UNMOUNT;
783 /* detach the loopback encryption setup for the application */
784 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
785 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
787 _E("close dmcrypt device error(%d)", ret);
791 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
793 _E("unable to Detach the loopback encryption setup" \
794 " for the application");
795 ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
800 /* delete the loopback device from the SD card */
801 ret = _app2sd_delete_loopback_device(loopback_device);
803 _E("unable to delete the " \
804 "loopback device from the SD Card");
805 ret = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
809 ret = _app2sd_delete_directory(application_mmc_path);
811 _E("unable to delete the directory (%s)",
816 /* remove encryption password from DB */
817 ret = _app2sd_initialize_db();
819 _E("app2sd db initialize failed");
820 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
824 ret = _app2sd_remove_info_from_db(pkgid, uid);
826 _E("cannot remove info from db");
827 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
836 int app2sd_usr_pre_move_installed_app(const char *pkgid,
837 GList *dir_list, app2ext_move_type move_type, uid_t uid)
842 char mmc_path[FILENAME_MAX] = { 0, };
844 /* validate function arguments */
845 if (pkgid == NULL || dir_list == NULL
846 || move_type < APP2EXT_MOVE_TO_EXT
847 || move_type > APP2EXT_MOVE_TO_PHONE) {
848 _E("invalid function arguments");
849 return APP2EXT_ERROR_INVALID_ARGUMENTS;
852 /* check whether MMC is present or not */
853 ret = _app2sd_check_mmc_status(&sdpath);
855 _E("MMC not present OR Not ready(%d)", ret);
856 return APP2EXT_ERROR_MMC_STATUS;
858 snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
862 ret = __app2sd_create_app2sd_directories(uid, mmc_path);
864 _E("failed to create app2sd dirs");
868 ret = _app2sd_usr_move_app(pkgid, move_type, dir_list, uid, mmc_path);
870 _D("unable to move application");
874 /* if move is completed, then update installed storage to pkgmgr_parser db */
875 if (move_type == APP2EXT_MOVE_TO_EXT) {
876 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
877 INSTALL_EXTERNAL, uid);
878 if (pkgmgr_ret < 0) {
879 _E("failed to update installed location to db " \
880 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
881 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
882 return APP2EXT_ERROR_PKGMGR_ERROR;
885 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
886 INSTALL_INTERNAL, uid);
887 if (pkgmgr_ret < 0) {
888 _E("failed to update installed location to db " \
889 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
890 pkgid, INSTALL_INTERNAL, uid, pkgmgr_ret);
891 return APP2EXT_ERROR_PKGMGR_ERROR;
896 return APP2EXT_SUCCESS;
899 int app2sd_usr_post_move_installed_app(const char *pkgid,
900 app2ext_move_type move_type, uid_t uid)
903 char mmc_path[FILENAME_MAX] = { 0, };
904 char application_path[FILENAME_MAX] = { 0, };
905 char loopback_device[FILENAME_MAX] = { 0, };
907 char *encoded_id = NULL;
909 /* validate function arguments */
910 if (pkgid == NULL || move_type < APP2EXT_MOVE_TO_EXT
911 || move_type > APP2EXT_MOVE_TO_PHONE) {
912 _E("invalid function arguments");
913 return APP2EXT_ERROR_INVALID_ARGUMENTS;
916 if (move_type == APP2EXT_MOVE_TO_PHONE)
917 return APP2EXT_SUCCESS;
919 /* check whether MMC is present or not */
920 ret = _app2sd_check_mmc_status(&sdpath);
922 _E("MMC not present OR Not ready(%d)", ret);
923 return APP2EXT_ERROR_MMC_STATUS;
925 snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
929 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
930 if (encoded_id == NULL)
931 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
933 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
934 mmc_path, EXTIMG_DIR, encoded_id);
936 if (_is_global(uid)) {
937 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
938 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
940 tzplatform_set_user(uid);
941 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
942 tzplatform_getenv(TZ_USER_APP), pkgid);
943 tzplatform_reset_user();
946 ret = _app2sd_unmount_app_content(application_path);
948 _E("unmount error (%d)", ret);
950 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
951 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
953 _E("close dmcrypt device error(%d)", ret);
955 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
957 _E("unable to detach loopback setup for (%s)",
962 return APP2EXT_SUCCESS;
965 int app2sd_usr_pre_app_upgrade(const char *pkgid, GList *dir_list,
968 int ret = APP2EXT_SUCCESS;
969 char app2sd_path[FILENAME_MAX] = { 0, };
970 char loopback_device[FILENAME_MAX] = { 0, };
971 char application_path[FILENAME_MAX] = { 0, };
972 char temp_uid[32] = { 0, };
974 char *temp_pkgid = NULL;
975 char *temp_loopback_device = NULL;
976 char *temp_application_path = NULL;
977 char *device_node = NULL;
978 char *encoded_id = NULL;
979 char *temp_encoded_id = NULL;
981 unsigned long long curr_size = 0;
983 int reqd_disk_size = size + ceil(size * 0.2);
985 /* validate function arguments*/
986 if (pkgid == NULL || dir_list == NULL || size <= 0) {
987 _E("invalid function arguments");
988 return APP2EXT_ERROR_INVALID_ARGUMENTS;
991 /* check whether MMC is present or not */
992 ret = _app2sd_check_mmc_status(&sdpath);
994 _E("MMC not present OR Not ready (%d)", ret);
995 return APP2EXT_ERROR_MMC_STATUS;
997 snprintf(app2sd_path, FILENAME_MAX - 1, "%s/%s",
1002 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1003 if (encoded_id == NULL)
1004 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1006 if (_is_global(uid)) {
1007 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1008 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1009 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1010 app2sd_path, encoded_id);
1012 tzplatform_set_user(uid);
1013 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1014 tzplatform_getenv(TZ_USER_APP), pkgid);
1015 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1016 app2sd_path, encoded_id);
1017 tzplatform_reset_user();
1021 /* check app entry is there in sd card or not. */
1022 fp = fopen(loopback_device, "r+");
1024 _E("app entry is not present in SD Card");
1025 return APP2EXT_ERROR_INVALID_PACKAGE;
1029 /* get installed app size*/
1030 curr_size = _app2sd_calculate_file_size(loopback_device);
1031 curr_size = (curr_size) / (1024 * 1024);
1032 if (curr_size == 0) {
1033 _E("app entry is not present in SD Card");
1034 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
1036 if ((int)curr_size < reqd_disk_size) {
1037 len = strlen(pkgid) + strlen(".new");
1038 temp_pkgid = calloc(len + 1, sizeof(char));
1039 if (temp_pkgid == NULL) {
1040 _E("memory alloc failed");
1041 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1043 snprintf(temp_pkgid, len + 1, "%s.new", pkgid);
1045 if (_is_global(uid)) {
1046 len = strlen(tzplatform_getenv(TZ_SYS_RW_APP)) + strlen(temp_pkgid) + 1;
1047 temp_application_path = calloc(len + 1, sizeof(char));
1048 if (temp_application_path == NULL) {
1049 _E("memory alloc failed");
1051 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1053 snprintf(temp_application_path, len + 1, "%s/%s",
1054 tzplatform_getenv(TZ_SYS_RW_APP), temp_pkgid);
1056 temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1057 if (temp_encoded_id == NULL) {
1059 free(temp_application_path);
1060 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1062 len = strlen(app2sd_path) + strlen(temp_encoded_id) + 1;
1063 temp_loopback_device = calloc(len + 1, sizeof(char));
1064 if (temp_loopback_device == NULL) {
1065 _E("memory alloc failed");
1067 free(temp_application_path);
1068 free(temp_encoded_id);
1069 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1071 snprintf(temp_loopback_device, len + 1, "%s/%s",
1072 app2sd_path, temp_encoded_id);
1073 free(temp_encoded_id);
1075 tzplatform_set_user(uid);
1076 len = strlen(tzplatform_getenv(TZ_USER_APP)) + strlen(temp_pkgid) + 1;
1077 temp_application_path = calloc(len + 1, sizeof(char));
1078 if (temp_application_path == NULL) {
1079 _E("memory alloc failed");
1081 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1083 snprintf(temp_application_path, len + 1, "%s/%s",
1084 tzplatform_getenv(TZ_USER_APP), temp_pkgid);
1086 temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1087 if (temp_encoded_id == NULL) {
1089 free(temp_application_path);
1090 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1092 snprintf(temp_uid, 32, "%d", uid);
1093 len = strlen(app2sd_path) + strlen(temp_uid) + strlen(temp_encoded_id) + 2;
1094 temp_loopback_device = calloc(len + 1, sizeof(char));
1095 if (temp_loopback_device == NULL) {
1096 _E("memory alloc failed");
1098 free(temp_application_path);
1099 free(temp_encoded_id);
1100 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1102 snprintf(temp_loopback_device, len + 1, "%s/%s",
1103 app2sd_path, temp_encoded_id);
1104 free(temp_encoded_id);
1105 tzplatform_reset_user();
1107 ret = _app2sd_update_loopback_device_size(pkgid,
1108 loopback_device, application_path, temp_pkgid,
1109 temp_loopback_device, temp_application_path,
1110 reqd_disk_size, dir_list, uid);
1112 free(temp_application_path);
1113 free(temp_loopback_device);
1114 if (APP2EXT_SUCCESS != ret) {
1115 _E("failed to update loopback device size");
1120 /* get the associated device node for SD card applicationer */
1121 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1123 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1125 device_node = _app2sd_find_associated_device_node(loopback_device);
1127 if (NULL == device_node) {
1128 /* do loopback setup */
1129 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1130 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
1131 false, uid, &device_node);
1133 _E("dmcrypt open device error");
1134 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
1137 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
1138 loopback_device, uid);
1139 if (device_node == NULL) {
1140 _E("loopback encryption setup failed");
1141 return APP2EXT_ERROR_DO_LOSETUP;
1146 ret = _app2sd_mount_app_content(application_path, pkgid,
1147 device_node, MOUNT_TYPE_RW, dir_list,
1148 APP2SD_PRE_UPGRADE, uid);
1155 return APP2EXT_ERROR_MOUNT_PATH;
1158 /* do re-mounting */
1159 ret = _app2sd_mount_app_content(application_path, pkgid,
1160 device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
1161 APP2SD_PRE_UPGRADE, uid);
1163 _E("remount failed");
1168 return APP2EXT_ERROR_MOUNT_PATH;
1181 int app2sd_usr_post_app_upgrade(const char *pkgid,
1182 app2ext_status install_status, uid_t uid)
1184 char mmc_path[FILENAME_MAX] = { 0, };
1185 char loopback_device[FILENAME_MAX] = { 0, };
1186 char application_path[FILENAME_MAX] = { 0, };
1187 char *sdpath = NULL;
1188 char *device_name = NULL;
1189 char *encoded_id = NULL;
1190 int ret = APP2EXT_SUCCESS;
1192 /* validate the function parameter recieved */
1193 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
1194 || install_status > APP2EXT_STATUS_SUCCESS) {
1195 _E("invalid func parameters");
1196 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1199 /* check whether MMC is present or not */
1200 ret = _app2sd_check_mmc_status(&sdpath);
1202 _E("MMC not present OR Not ready (%d)", ret);
1203 return APP2EXT_ERROR_MMC_STATUS;
1205 snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
1209 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1210 if (encoded_id == NULL)
1211 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1213 if (_is_global(uid)) {
1214 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1215 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1216 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1217 mmc_path, EXTIMG_DIR, encoded_id);
1219 tzplatform_set_user(uid);
1220 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1221 tzplatform_getenv(TZ_USER_APP), pkgid);
1222 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1223 mmc_path, EXTIMG_DIR, encoded_id);
1224 tzplatform_reset_user();
1228 /* get the associated device node for SD card applicationer */
1229 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1231 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1233 _E("could not find associated dmcrypt device node" \
1234 " (%s_%d)", pkgid, uid);
1235 return APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE;
1238 device_name = _app2sd_find_associated_device_node(loopback_device);
1239 if (NULL == device_name)
1240 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
1243 ret = _app2sd_unmount_app_content(application_path);
1249 _E("unable to unmount the app content (%d)", ret);
1250 return APP2EXT_ERROR_UNMOUNT;
1253 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1254 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1260 _E("close dmcrypt device error(%d)", ret);
1261 return APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
1264 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
1270 _E("unable to detach the loopback encryption " \
1271 "setup for the application");
1272 return APP2EXT_ERROR_UNMOUNT;
1285 int app2sd_usr_force_clean(const char *pkgid, uid_t uid)
1287 char mmc_path[FILENAME_MAX] = { 0, };
1288 char loopback_device[FILENAME_MAX] = { 0, };
1289 char application_path[FILENAME_MAX] = { 0, };
1290 char *sdpath = NULL;
1291 char *encoded_id = NULL;
1292 int ret = APP2EXT_SUCCESS;
1294 /* validate the function parameter recieved */
1295 if (pkgid == NULL) {
1296 _E("invalid func parameters");
1297 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1300 /* check whether MMC is present or not */
1301 ret = _app2sd_check_mmc_status(&sdpath);
1303 _E("MMC not present OR Not ready (%d)", ret);
1304 return APP2EXT_ERROR_MMC_STATUS;
1306 snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
1310 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1311 if (encoded_id == NULL)
1312 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1314 if (_is_global(uid)) {
1315 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1316 tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1317 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1318 mmc_path, EXTIMG_DIR, encoded_id);
1320 tzplatform_set_user(uid);
1321 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1322 tzplatform_getenv(TZ_USER_APP), pkgid);
1323 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1324 mmc_path, EXTIMG_DIR, encoded_id);
1325 tzplatform_reset_user();
1329 ret = _app2sd_force_clean(pkgid, application_path, loopback_device, uid);
1335 int app2sd_enable_full_pkg(void)
1337 int ret = APP2EXT_SUCCESS;
1339 char buf[FILENAME_MAX] = { 0, };
1340 char app2sd_path[FILENAME_MAX] = { 0, };
1341 char loopback_device[FILENAME_MAX] = { 0, };
1342 char *sdpath = NULL;
1345 struct dirent entry;
1346 struct dirent *result = NULL;
1349 /* check whether MMC is present or not */
1350 ret = _app2sd_check_mmc_status(&sdpath);
1352 _E("MMC not present OR Not ready (%d)", ret);
1353 return APP2EXT_ERROR_MMC_STATUS;
1355 snprintf(app2sd_path, FILENAME_MAX - 1, "%s/%s",
1356 sdpath, EXTIMG_DIR);
1359 dir = opendir(app2sd_path);
1361 strerror_r(errno, buf, sizeof(buf));
1362 _E("failed to opendir (%s)", buf);
1363 return APP2EXT_ERROR_OPEN_DIR;
1366 ret = _app2sd_initialize_db();
1368 _E("app2sd db initialize failed");
1370 return APP2EXT_ERROR_SQLITE_REGISTRY;
1373 for (rc = readdir_r(dir, &entry, &result);
1374 rc == 0 && result != NULL;
1375 rc = readdir_r(dir, &entry, &result)) {
1376 if (strcmp(entry.d_name, ".") == 0 ||
1377 strcmp(entry.d_name, "..") == 0)
1379 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1380 app2sd_path, entry.d_name);
1381 ret = _app2sd_get_info_from_db(loopback_device,
1384 _E("failed to get info from db");
1388 _D("pkgid(%s), uid(%d)", pkgid, uid);
1389 ret = app2sd_usr_on_demand_setup_init(pkgid, uid);
1391 _E("error(%d)", ret);
1409 static int _app2sd_info_cb_func(const char *pkgid, uid_t uid)
1411 int ret = APP2EXT_SUCCESS;
1414 _D("pkgid(%s), uid(%d)", pkgid, uid);
1415 ret = app2sd_usr_on_demand_setup_exit(pkgid, uid);
1417 _E("error(%d)", ret);
1423 int app2sd_disable_full_pkg(void)
1425 int ret = APP2EXT_SUCCESS;
1427 ret = _app2sd_initialize_db();
1429 _E("app2sd db initialize failed");
1430 return APP2EXT_ERROR_SQLITE_REGISTRY;
1433 ret = _app2sd_get_foreach_info_from_db((app2sd_info_cb)_app2sd_info_cb_func);
1435 _E("disable full pkg error(%d)", ret);