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 <app2sd_internals.h>
25 #include <app2sd_interface.h>
27 #include <sys/types.h>
29 #include <pkgmgr-info.h>
31 #define MAX_BUF_LEN 1024
32 #define APP2SD_TMP_PATH "/opt/usr/apps/tmp"
34 int app2sd_pre_app_install(const char *pkgid, GList* dir_list,
39 char *device_node = NULL;
43 /*Validate the function parameter recieved */
44 if (pkgid == NULL || dir_list == NULL || size <= 0) {
45 app2ext_print("App2Sd Error : Invalid function arguments\n");
46 return APP2EXT_ERROR_INVALID_ARGUMENTS;
48 /*Check whether MMC is present or not */
49 ret = _app2sd_check_mmc_status();
51 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
53 return APP2EXT_ERROR_MMC_STATUS;
55 /*Find available free memory in the MMC card */
56 ret = _app2sd_get_available_free_memory(MMC_PATH,
59 app2ext_print("App2Sd Error : Unable to get available free memory in MMC %d\n", ret);
60 return APP2EXT_ERROR_MMC_STATUS;
62 /*If avaialalbe free memory in MMC is less than required size + 5MB , return error */
63 if ((size + PKG_BUF_SIZE + MEM_BUF_SIZE) > free_mmc_mem) {
64 app2ext_print("Insufficient memory in MMC for application installation %d\n", ret);
65 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
67 /*Create a loopback device */
68 ret = _app2sd_create_loopback_device(pkgid, (size+PKG_BUF_SIZE));
70 app2ext_print("App2Sd Error : Package already present\n");
73 /*Perform Loopback encryption setup */
74 device_node = _app2sd_do_loopback_encryption_setup(pkgid);
76 app2ext_print("App2Sd Error : Loopback encryption setup failed\n");
77 _app2sd_delete_loopback_device(pkgid);
78 return APP2EXT_ERROR_DO_LOSETUP;
80 /*Check whether loopback device is associated with device node or not */
81 devi = _app2sd_find_associated_device_node(pkgid);
83 app2ext_print("App2Sd Error : finding associated device node failed\n");
84 ret = APP2EXT_ERROR_DO_LOSETUP;
88 /*Format the loopback file system */
89 ret = _app2sd_create_file_system(device_node);
91 app2ext_print("App2Sd Error : creating FS failed failed\n");
92 ret = APP2EXT_ERROR_CREATE_FS;
96 /*Mount the loopback encrypted pseudo device on application installation path as with Read Write permission */
97 ret =_app2sd_mount_app_content(pkgid, device_node, MOUNT_TYPE_RW,
98 dir_list, APP2SD_PRE_INSTALL);
100 app2ext_print("App2Sd Error : mounting dev path to app install path failed\n");
101 ret = APP2EXT_ERROR_MOUNT_PATH;
106 ret = APP2EXT_SUCCESS;
112 result = _app2sd_detach_loop_device(device_node);
117 _app2sd_delete_loopback_device(pkgid);
131 int app2sd_post_app_install(const char *pkgid,
132 app2ext_status install_status)
134 char *device_name = NULL;
135 char buf_dir[FILENAME_MAX] = { 0, };
136 int ret = APP2EXT_SUCCESS;
137 /*Validate the function parameter recieved */
138 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
139 || install_status > APP2EXT_STATUS_SUCCESS) {
140 app2ext_print("Invalid func parameters\n");
141 return APP2EXT_ERROR_INVALID_ARGUMENTS;
144 /*Check whether MMC is present or not */
145 ret = _app2sd_check_mmc_status();
147 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
149 return APP2EXT_ERROR_MMC_STATUS;
152 /*Get the associated device node for SD card applicationer */
153 device_name = _app2sd_find_associated_device_node(pkgid);
154 if (NULL == device_name) {
155 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
157 ret = _app2sd_unmount_app_content(pkgid);
163 app2ext_print("Unable to unmount the app content %d\n", ret);
164 return APP2EXT_ERROR_UNMOUNT;
166 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
173 ("Unable to Detach the loopback encryption setup for the application");
174 return APP2EXT_ERROR_UNMOUNT;
181 /*Take appropriate action based on installation
182 status of application package */
183 if (install_status == APP2EXT_STATUS_FAILED) {
184 /*Delete the loopback device from the SD card */
185 ret = _app2sd_delete_loopback_device(pkgid);
188 ("App2Sd Error : Unable to delete the loopback device from the SD Card\n");
189 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
191 ret = _app2sd_remove_password_from_db(pkgid);
195 ("App2Sd Error : Unable to delete the password\n");
198 snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
200 ret = _app2sd_delete_directory(buf_dir);
204 ("App2Sd Error : Unable to delete the directory %s\n",
209 /*If the status is success, then update installed storage to pkgmgr_parser db*/
211 pkgmgrinfo_pkgdbinfo_h handle = NULL;
212 rt = pkgmgrinfo_create_pkgdbinfo(pkgid, &handle);
214 app2ext_print("pkgmgrinfo_create_pkgdbinfo[%s] fail.. \n", pkgid);
216 rt = pkgmgrinfo_set_installed_storage_to_pkgdbinfo(handle, INSTALL_EXTERNAL);
218 app2ext_print("fail to update installed location to db[%s, %s]\n", pkgid, INSTALL_EXTERNAL);
220 rt =pkgmgrinfo_save_pkgdbinfo(handle);
222 app2ext_print("pkgmgrinfo_save_pkgdbinfo[%s] failed\n", pkgid);
224 rt =pkgmgrinfo_destroy_pkgdbinfo(handle);
226 app2ext_print("pkgmgrinfo_destroy_pkgdbinfo[%s] failed\n", pkgid);
232 int app2sd_on_demand_setup_init(const char *pkgid)
234 int ret = APP2EXT_SUCCESS;
235 char app_path[FILENAME_MAX] = { 0, };
236 char *device_node = NULL;
240 /*Validate the function parameter recieved */
243 ("App2Sd Error : Invalid function arguments to app launch setup\n");
244 return APP2EXT_ERROR_INVALID_ARGUMENTS;
247 /*Check whether MMC is present or not */
248 ret = _app2sd_check_mmc_status();
250 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
252 return APP2EXT_ERROR_MMC_STATUS;
255 /*check app entry is there in sd card or not. */
256 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
258 fp = fopen(app_path, "r+");
261 ("App2SD Error: App Entry is not present in SD Card\n");
262 return APP2EXT_ERROR_INVALID_PACKAGE;
265 result = (char *)_app2sd_find_associated_device(app_path);
266 /*process the string */
267 if ((result!=NULL) && strstr(result, "/dev") != NULL) {
268 app2ext_print("App2SD Error! Already associated\n");
271 return APP2EXT_ERROR_ALREADY_MOUNTED;
274 /*Do loopback setup */
275 device_node = _app2sd_do_loopback_encryption_setup(pkgid);
276 if (device_node == NULL) {
278 ("App2Sd Error : loopback encryption setup failed\n");
279 return APP2EXT_ERROR_DO_LOSETUP;
284 _app2sd_mount_app_content(pkgid, device_node, MOUNT_TYPE_RD,
285 NULL, APP2SD_APP_LAUNCH);
287 app2ext_print("App2Sd Error : Re-mount failed\n");
292 return APP2EXT_ERROR_MOUNT_PATH;
301 int app2sd_on_demand_setup_exit(const char *pkgid)
303 int ret = APP2EXT_SUCCESS;
304 char app_path[FILENAME_MAX] = { 0, };
307 /*Validate the function parameter recieved */
310 ("App2Sd Error : Invalid function arguments to app launch setup\n");
311 return APP2EXT_ERROR_INVALID_ARGUMENTS;
314 /*Check whether MMC is present or not */
315 ret = _app2sd_check_mmc_status();
317 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
319 return APP2EXT_ERROR_MMC_STATUS;
321 /*check app entry is there in sd card or not. */
322 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
324 fp = fopen(app_path, "r+");
327 ("App2SD Error: App Entry is not present in SD Card\n");
328 return APP2EXT_ERROR_INVALID_PACKAGE;
331 ret = _app2sd_unmount_app_content(pkgid);
334 ("App2SD Error: Unable to unmount the SD application\n");
335 return APP2EXT_ERROR_UNMOUNT;
337 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
339 app2ext_print("App2SD Error: Unable to remove loopback setup\n");
340 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
345 int app2sd_pre_app_uninstall(const char *pkgid)
347 int ret = APP2EXT_SUCCESS;
348 char app_path[FILENAME_MAX] = { 0, };
349 char *device_node = NULL;
352 /*Validate the function parameter recieved */
355 ("App2Sd Error : Invalid function arguments to app launch setup\n");
356 return APP2EXT_ERROR_INVALID_ARGUMENTS;
358 /*Check whether MMC is present or not */
359 ret = _app2sd_check_mmc_status();
361 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
363 return APP2EXT_ERROR_MMC_STATUS;
365 /*check app entry is there in sd card or not. */
366 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH, pkgid);
367 fp = fopen(app_path, "r+");
370 ("App2SD Error: App Entry is not present in SD Card\n");
371 return APP2EXT_ERROR_INVALID_PACKAGE;
375 /*Get the associated device node for SD card applicationer */
376 device_node = _app2sd_find_associated_device_node(pkgid);
377 if (NULL == device_node) {
378 /*Do loopback setup */
379 device_node = _app2sd_do_loopback_encryption_setup(pkgid);
381 if (device_node == NULL) {
383 ("App2Sd Error : loopback encryption setup failed\n");
384 return APP2EXT_ERROR_DO_LOSETUP;
388 _app2sd_mount_app_content(pkgid, device_node,
390 APP2SD_PRE_UNINSTALL);
393 app2ext_print("App2Sd Error : RW-mount failed\n");
398 return APP2EXT_ERROR_MOUNT_PATH;
403 _app2sd_mount_app_content(pkgid, device_node,
404 MOUNT_TYPE_RW_REMOUNT, NULL,
405 APP2SD_PRE_UNINSTALL);
408 app2ext_print("App2Sd Error : Re-mount failed\n");
413 return APP2EXT_ERROR_MOUNT_PATH;
424 * app2sd_post_app_uninstall_setup
425 * Uninstall Application and free all the allocated resources
426 * Called after dpkg remove, It deallocates dev node and loopback
428 int app2sd_post_app_uninstall(const char *pkgid)
430 char buf_dir[FILENAME_MAX] = { 0, };
431 int ret = APP2EXT_SUCCESS;
432 int ret1 = APP2EXT_SUCCESS;
433 /*Validate the function parameter recieved */
436 ("App2Sd Error : Invalid function arguments to Post Uninstall\n");
437 return APP2EXT_ERROR_INVALID_ARGUMENTS;
439 /*Check whether MMC is present or not */
440 ret = _app2sd_check_mmc_status();
442 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
444 return APP2EXT_ERROR_MMC_STATUS;
446 /*Unmount the loopback encrypted pseudo device from the application installation path */
447 ret = _app2sd_unmount_app_content(pkgid);
449 app2ext_print("Unable to unmount the app content %d\n", ret);
450 return APP2EXT_ERROR_UNMOUNT;
452 /*Detach the loopback encryption setup for the application */
453 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
456 ("Unable to Detach the loopback encryption setup for the application");
457 return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
459 /*Delete the loopback device from the SD card */
460 ret = _app2sd_delete_loopback_device(pkgid);
463 ("App2Sd Error : Unable to delete the loopback device from the SD Card\n");
464 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
466 memset((void *)&buf_dir, '\0', FILENAME_MAX);
467 snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
468 ret1 = _app2sd_delete_directory(buf_dir);
471 ("App2Sd Error : Unable to delete the directory %s\n",
474 /*remove encryption password from DB */
475 ret = _app2sd_initialize_db();
477 app2ext_print("\n app2sd db initialize failed");
478 return APP2EXT_ERROR_SQLITE_REGISTRY;
480 ret = _app2sd_remove_password_from_db(pkgid);
482 app2ext_print("cannot remove password from db \n");
483 return APP2EXT_ERROR_SQLITE_REGISTRY;
488 int app2sd_move_installed_app(const char *pkgid, GList* dir_list,
489 app2ext_move_type move_type)
492 char device_path[MAX_BUF_LEN] = {'\0', };
495 char buf[MAX_BUF_LEN] = {'\0'};
497 /*Validate function arguments*/
498 if (pkgid == NULL || dir_list == NULL
499 || move_type < APP2EXT_MOVE_TO_EXT
500 || move_type > APP2EXT_MOVE_TO_PHONE) {
501 app2ext_print("App2Sd Error : Invalid function arguments\n");
502 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
506 ret = _app2sd_move_app(pkgid, move_type, dir_list);
508 app2ext_print("App2Sd Error : Unable to move application\n");
512 /*If move is completed, then update installed storage to pkgmgr_parser db*/
514 pkgmgrinfo_pkgdbinfo_h handle = NULL;
515 rt = pkgmgrinfo_create_pkgdbinfo(pkgid, &handle);
517 app2ext_print("App2Sd Error : pkgmgrinfo_create_pkgdbinfo[%s] fail.. \n", pkgid);
520 if (move_type == APP2EXT_MOVE_TO_EXT) {
521 rt = pkgmgrinfo_set_installed_storage_to_pkgdbinfo(handle, INSTALL_EXTERNAL);
523 app2ext_print("App2Sd Error : fail to update installed location to db[%s, %s]\n", pkgid, INSTALL_EXTERNAL);
526 rt = pkgmgrinfo_set_installed_storage_to_pkgdbinfo(handle, INSTALL_INTERNAL);
528 app2ext_print("App2Sd Error : fail to update installed location to db[%s, %s]\n", pkgid, INSTALL_INTERNAL);
531 rt =pkgmgrinfo_save_pkgdbinfo(handle);
533 app2ext_print("pkgmgrinfo_save_pkgdbinfo[%s] failed\n", pkgid);
535 rt =pkgmgrinfo_destroy_pkgdbinfo(handle);
537 app2ext_print("pkgmgrinfo_destroy_pkgdbinfo failed\n");
541 snprintf(device_path, MAX_BUF_LEN, "%s/app2sd_%s", APP2SD_TMP_PATH, pkgid);
543 file = fopen(device_path, "w");
545 app2ext_print("fopen failed\n");
548 snprintf(buf, MAX_BUF_LEN - 1, "%d\n", ret);
549 fwrite(buf, 1, strlen(buf), file);
561 int app2sd_pre_app_upgrade(const char *pkgid, GList* dir_list,
564 int ret = APP2EXT_SUCCESS;
565 char app_path[FILENAME_MAX] = { 0, };
566 char *device_node = NULL;
567 unsigned long long curr_size = 0;
570 /*Validate function arguments*/
571 if (pkgid == NULL || dir_list == NULL || size<=0) {
573 ("App2Sd Error : Invalid function arguments \n");
574 return APP2EXT_ERROR_INVALID_ARGUMENTS;
576 /*Check whether MMC is present or not */
577 ret = _app2sd_check_mmc_status();
579 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
581 return APP2EXT_ERROR_MMC_STATUS;
583 /*check app entry is there in sd card or not. */
584 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
586 app2ext_print("App2Sd Log : Checking path %s\n", app_path);
587 fp = fopen(app_path, "r+");
590 ("App2SD Error: App Entry is not present in SD Card\n");
591 return APP2EXT_ERROR_INVALID_PACKAGE;
594 /*Get installed app size*/
595 curr_size = _app2sd_calculate_file_size(app_path);
596 curr_size = (curr_size/1024)/1024;
600 ("App2SD Error: App Entry is not present in SD Card\n");
601 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
603 if (curr_size<size) {
604 ret = _app2sd_update_loopback_device_size(pkgid, size, dir_list);
605 if(APP2EXT_SUCCESS !=ret) {
607 ("App2SD Error: _app2sd_update_loopback_device_size() failed\n");
612 /*Get the associated device node for SD card applicationer */
613 device_node = _app2sd_find_associated_device_node(pkgid);
614 if (NULL == device_node) {
615 /*Do loopback setup */
616 device_node = _app2sd_do_loopback_encryption_setup(pkgid);
617 if (device_node == NULL) {
619 ("App2Sd Error : loopback encryption setup failed\n");
620 return APP2EXT_ERROR_DO_LOSETUP;
624 _app2sd_mount_app_content(pkgid, device_node,
628 app2ext_print("App2Sd Error : Re-mount failed\n");
633 return APP2EXT_ERROR_MOUNT_PATH;
638 _app2sd_mount_app_content(pkgid, device_node,
639 MOUNT_TYPE_RW_REMOUNT, NULL,
642 app2ext_print("App2Sd Error : Re-mount failed\n");
647 return APP2EXT_ERROR_MOUNT_PATH;
659 int app2sd_post_app_upgrade(const char *pkgid,
660 app2ext_status install_status)
662 char *device_name = NULL;
663 int ret = APP2EXT_SUCCESS;
664 /*Validate the function parameter recieved */
665 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
666 || install_status > APP2EXT_STATUS_SUCCESS) {
667 app2ext_print("Invalid func parameters\n");
668 return APP2EXT_ERROR_INVALID_ARGUMENTS;
670 /*Check whether MMC is present or not */
671 ret = _app2sd_check_mmc_status();
673 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
675 return APP2EXT_ERROR_MMC_STATUS;
678 /*Get the associated device node for SD card applicationer */
679 device_name = _app2sd_find_associated_device_node(pkgid);
680 if (NULL == device_name) {
681 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
683 ret = _app2sd_unmount_app_content(pkgid);
689 app2ext_print("Unable to unmount the app content %d\n", ret);
690 return APP2EXT_ERROR_UNMOUNT;
692 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
699 ("Unable to Detach the loopback encryption setup for the application");
700 return APP2EXT_ERROR_UNMOUNT;
711 * Reserved API for forced cleanup
714 int app2sd_force_cleanup(const char *pkgid){
715 char *device_name = NULL;
716 char buf_dir[FILENAME_MAX] = { 0, };
717 int ret = APP2EXT_SUCCESS;
720 /*Validate the function parameter recieved */
722 app2ext_print("invalid func parameters\n");
723 return APP2EXT_ERROR_INVALID_ARGUMENTS;
725 memset((void *)&buf_dir, '\0', FILENAME_MAX);
726 snprintf(buf_dir, FILENAME_MAX, "%s%s", APP2SD_PATH, pkgid);
727 fp = fopen(buf_dir, "r+");
729 app2ext_print("\"%s\" not installed on SD Card\n", pkgid);
730 return APP2EXT_ERROR_INVALID_PACKAGE;
733 /*Check whether MMC is present or not */
734 ret = _app2sd_check_mmc_status();
736 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
738 return APP2EXT_ERROR_MMC_STATUS;
741 /*Get the associated device node for SD card applicationer */
742 device_name = _app2sd_find_associated_device_node(pkgid);
743 if (NULL != device_name) {
746 ret = _app2sd_unmount_app_content(pkgid);
748 app2ext_print("Unable to unmount the app content %d\n", ret);
749 return APP2EXT_ERROR_UNMOUNT;
751 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
754 ("Unable to Detach the loopback encryption setup for the application");
755 return APP2EXT_ERROR_UNMOUNT;
759 memset((void *)&buf_dir, '\0', FILENAME_MAX);
760 snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
761 ret = _app2sd_delete_directory(buf_dir);
764 ("App2Sd Error : Unable to delete the directory %s\n",
768 /*remove passwrd from DB*/
769 ret = _app2sd_initialize_db();
771 app2ext_print("\n app2sd db initialize failed");
772 return APP2EXT_ERROR_SQLITE_REGISTRY;
774 ret = _app2sd_remove_password_from_db(pkgid);
776 app2ext_print("cannot remove password from db \n");
777 return APP2EXT_ERROR_SQLITE_REGISTRY;
783 /* This is the plug-in load function. The plugin has to bind its functions to function pointers of handle
784 @param[in/out] st_interface Specifies the storage interface.
787 app2ext_on_load(app2ext_interface *st_interface)
790 st_interface->pre_install= app2sd_pre_app_install;
791 st_interface->post_install= app2sd_post_app_install;
792 st_interface->pre_uninstall= app2sd_pre_app_uninstall;
793 st_interface->post_uninstall= app2sd_post_app_uninstall;
794 st_interface->pre_upgrade= app2sd_pre_app_upgrade;
795 st_interface->post_upgrade= app2sd_post_app_upgrade;
796 st_interface->move= app2sd_move_installed_app;
797 st_interface->enable= app2sd_on_demand_setup_init;
798 st_interface->disable= app2sd_on_demand_setup_exit;