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>
32 #define MAX_BUF_LEN 1024
33 #define APP2SD_TMP_PATH "/opt/usr/apps/tmp"
35 int app2sd_pre_app_install(const char *pkgid, GList* dir_list,
40 char *device_node = NULL;
44 /*Validate the function parameter recieved */
45 if (pkgid == NULL || dir_list == NULL || size <= 0) {
46 app2ext_print("App2Sd Error : Invalid function arguments\n");
47 return APP2EXT_ERROR_INVALID_ARGUMENTS;
49 /*Check whether MMC is present or not */
50 ret = _app2sd_check_mmc_status();
52 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
54 return APP2EXT_ERROR_MMC_STATUS;
56 /*Find available free memory in the MMC card */
57 ret = _app2sd_get_available_free_memory(MMC_PATH,
60 app2ext_print("App2Sd Error : Unable to get available free memory in MMC %d\n", ret);
61 return APP2EXT_ERROR_MMC_STATUS;
63 /*If avaialalbe free memory in MMC is less than required size + 5MB , return error */
64 if ((size + PKG_BUF_SIZE + MEM_BUF_SIZE) > free_mmc_mem) {
65 app2ext_print("Insufficient memory in MMC for application installation %d\n", ret);
66 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
68 /*Create a loopback device */
69 ret = _app2sd_create_loopback_device(pkgid, (size+PKG_BUF_SIZE));
71 app2ext_print("App2Sd Error : Package already present\n");
74 /*Perform Loopback encryption setup */
75 device_node = _app2sd_do_loopback_encryption_setup(pkgid);
77 app2ext_print("App2Sd Error : Loopback encryption setup failed\n");
78 _app2sd_delete_loopback_device(pkgid);
79 return APP2EXT_ERROR_DO_LOSETUP;
81 /*Check whether loopback device is associated with device node or not */
82 devi = _app2sd_find_associated_device_node(pkgid);
84 app2ext_print("App2Sd Error : finding associated device node failed\n");
85 ret = APP2EXT_ERROR_DO_LOSETUP;
89 /*Format the loopback file system */
90 ret = _app2sd_create_file_system(device_node);
92 app2ext_print("App2Sd Error : creating FS failed failed\n");
93 ret = APP2EXT_ERROR_CREATE_FS;
97 /*Mount the loopback encrypted pseudo device on application installation path as with Read Write permission */
98 ret =_app2sd_mount_app_content(pkgid, device_node, MOUNT_TYPE_RW,
99 dir_list, APP2SD_PRE_INSTALL);
101 app2ext_print("App2Sd Error : mounting dev path to app install path failed\n");
102 ret = APP2EXT_ERROR_MOUNT_PATH;
107 ret = APP2EXT_SUCCESS;
113 result = _app2sd_detach_loop_device(device_node);
118 _app2sd_delete_loopback_device(pkgid);
132 int app2sd_post_app_install(const char *pkgid,
133 app2ext_status install_status)
135 char *device_name = NULL;
136 char buf_dir[FILENAME_MAX] = { 0, };
137 int ret = APP2EXT_SUCCESS;
138 /*Validate the function parameter recieved */
139 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
140 || install_status > APP2EXT_STATUS_SUCCESS) {
141 app2ext_print("Invalid func parameters\n");
142 return APP2EXT_ERROR_INVALID_ARGUMENTS;
145 /*Check whether MMC is present or not */
146 ret = _app2sd_check_mmc_status();
148 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
150 return APP2EXT_ERROR_MMC_STATUS;
153 /*Get the associated device node for SD card applicationer */
154 device_name = _app2sd_find_associated_device_node(pkgid);
155 if (NULL == device_name) {
156 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
158 ret = _app2sd_unmount_app_content(pkgid);
164 app2ext_print("Unable to unmount the app content %d\n", ret);
165 return APP2EXT_ERROR_UNMOUNT;
167 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
174 ("Unable to Detach the loopback encryption setup for the application");
175 return APP2EXT_ERROR_UNMOUNT;
182 /*Take appropriate action based on installation
183 status of application package */
184 if (install_status == APP2EXT_STATUS_FAILED) {
185 /*Delete the loopback device from the SD card */
186 ret = _app2sd_delete_loopback_device(pkgid);
189 ("App2Sd Error : Unable to delete the loopback device from the SD Card\n");
190 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
192 ret = _app2sd_remove_password_from_db(pkgid);
196 ("App2Sd Error : Unable to delete the password\n");
199 snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
201 ret = _app2sd_delete_directory(buf_dir);
205 ("App2Sd Error : Unable to delete the directory %s\n",
210 /*If the status is success, then update installed storage to pkgmgr_parser db*/
212 pkgmgrinfo_pkgdbinfo_h handle = NULL;
213 rt = pkgmgrinfo_create_pkgdbinfo(pkgid, &handle);
215 app2ext_print("pkgmgrinfo_create_pkgdbinfo[%s] fail.. \n", pkgid);
217 rt = pkgmgrinfo_set_installed_storage_to_pkgdbinfo(handle, INSTALL_EXTERNAL);
219 app2ext_print("fail to update installed location to db[%s, %s]\n", pkgid, INSTALL_EXTERNAL);
221 rt =pkgmgrinfo_save_pkgdbinfo(handle);
223 app2ext_print("pkgmgrinfo_save_pkgdbinfo[%s] failed\n", pkgid);
225 rt =pkgmgrinfo_destroy_pkgdbinfo(handle);
227 app2ext_print("pkgmgrinfo_destroy_pkgdbinfo[%s] failed\n", pkgid);
233 int app2sd_on_demand_setup_init(const char *pkgid)
235 int ret = APP2EXT_SUCCESS;
236 char app_path[FILENAME_MAX] = { 0, };
237 char *device_node = NULL;
241 /*Validate the function parameter recieved */
244 ("App2Sd Error : Invalid function arguments to app launch setup\n");
245 return APP2EXT_ERROR_INVALID_ARGUMENTS;
248 /*Check whether MMC is present or not */
249 ret = _app2sd_check_mmc_status();
251 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
253 return APP2EXT_ERROR_MMC_STATUS;
256 /*check app entry is there in sd card or not. */
257 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
259 fp = fopen(app_path, "r+");
262 ("App2SD Error: App Entry is not present in SD Card\n");
263 return APP2EXT_ERROR_INVALID_PACKAGE;
266 result = (char *)_app2sd_find_associated_device(app_path);
267 /*process the string */
268 if ((result!=NULL) && strstr(result, "/dev") != NULL) {
269 app2ext_print("App2SD Error! Already associated\n");
272 return APP2EXT_ERROR_ALREADY_MOUNTED;
275 /*Do loopback setup */
276 device_node = _app2sd_do_loopback_encryption_setup(pkgid);
277 if (device_node == NULL) {
279 ("App2Sd Error : loopback encryption setup failed\n");
280 return APP2EXT_ERROR_DO_LOSETUP;
285 _app2sd_mount_app_content(pkgid, device_node, MOUNT_TYPE_RD,
286 NULL, APP2SD_APP_LAUNCH);
288 app2ext_print("App2Sd Error : Re-mount failed\n");
293 return APP2EXT_ERROR_MOUNT_PATH;
302 int app2sd_on_demand_setup_exit(const char *pkgid)
304 int ret = APP2EXT_SUCCESS;
305 char app_path[FILENAME_MAX] = { 0, };
308 /*Validate the function parameter recieved */
311 ("App2Sd Error : Invalid function arguments to app launch setup\n");
312 return APP2EXT_ERROR_INVALID_ARGUMENTS;
315 /*Check whether MMC is present or not */
316 ret = _app2sd_check_mmc_status();
318 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
320 return APP2EXT_ERROR_MMC_STATUS;
322 /*check app entry is there in sd card or not. */
323 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
325 fp = fopen(app_path, "r+");
328 ("App2SD Error: App Entry is not present in SD Card\n");
329 return APP2EXT_ERROR_INVALID_PACKAGE;
332 ret = _app2sd_unmount_app_content(pkgid);
335 ("App2SD Error: Unable to unmount the SD application\n");
336 return APP2EXT_ERROR_UNMOUNT;
338 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
340 app2ext_print("App2SD Error: Unable to remove loopback setup\n");
341 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
346 int app2sd_pre_app_uninstall(const char *pkgid)
348 int ret = APP2EXT_SUCCESS;
349 char app_path[FILENAME_MAX] = { 0, };
350 char *device_node = NULL;
353 /*Validate the function parameter recieved */
356 ("App2Sd Error : Invalid function arguments to app launch setup\n");
357 return APP2EXT_ERROR_INVALID_ARGUMENTS;
359 /*Check whether MMC is present or not */
360 ret = _app2sd_check_mmc_status();
362 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
364 return APP2EXT_ERROR_MMC_STATUS;
366 /*check app entry is there in sd card or not. */
367 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH, pkgid);
368 fp = fopen(app_path, "r+");
371 ("App2SD Error: App Entry is not present in SD Card\n");
372 return APP2EXT_ERROR_INVALID_PACKAGE;
376 /*Get the associated device node for SD card applicationer */
377 device_node = _app2sd_find_associated_device_node(pkgid);
378 if (NULL == device_node) {
379 /*Do loopback setup */
380 device_node = _app2sd_do_loopback_encryption_setup(pkgid);
382 if (device_node == NULL) {
384 ("App2Sd Error : loopback encryption setup failed\n");
385 return APP2EXT_ERROR_DO_LOSETUP;
389 _app2sd_mount_app_content(pkgid, device_node,
391 APP2SD_PRE_UNINSTALL);
394 app2ext_print("App2Sd Error : RW-mount failed\n");
399 return APP2EXT_ERROR_MOUNT_PATH;
404 _app2sd_mount_app_content(pkgid, device_node,
405 MOUNT_TYPE_RW_REMOUNT, NULL,
406 APP2SD_PRE_UNINSTALL);
409 app2ext_print("App2Sd Error : Re-mount failed\n");
414 return APP2EXT_ERROR_MOUNT_PATH;
425 * app2sd_post_app_uninstall_setup
426 * Uninstall Application and free all the allocated resources
427 * Called after dpkg remove, It deallocates dev node and loopback
429 int app2sd_post_app_uninstall(const char *pkgid)
431 char buf_dir[FILENAME_MAX] = { 0, };
432 int ret = APP2EXT_SUCCESS;
433 int ret1 = APP2EXT_SUCCESS;
434 /*Validate the function parameter recieved */
437 ("App2Sd Error : Invalid function arguments to Post Uninstall\n");
438 return APP2EXT_ERROR_INVALID_ARGUMENTS;
440 /*Check whether MMC is present or not */
441 ret = _app2sd_check_mmc_status();
443 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
445 return APP2EXT_ERROR_MMC_STATUS;
447 /*Unmount the loopback encrypted pseudo device from the application installation path */
448 ret = _app2sd_unmount_app_content(pkgid);
450 app2ext_print("Unable to unmount the app content %d\n", ret);
451 return APP2EXT_ERROR_UNMOUNT;
453 /*Detach the loopback encryption setup for the application */
454 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
457 ("Unable to Detach the loopback encryption setup for the application");
458 return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
460 /*Delete the loopback device from the SD card */
461 ret = _app2sd_delete_loopback_device(pkgid);
464 ("App2Sd Error : Unable to delete the loopback device from the SD Card\n");
465 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
467 memset((void *)&buf_dir, '\0', FILENAME_MAX);
468 snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
469 ret1 = _app2sd_delete_directory(buf_dir);
472 ("App2Sd Error : Unable to delete the directory %s\n",
475 /*remove encryption password from DB */
476 ret = _app2sd_initialize_db();
478 app2ext_print("\n app2sd db initialize failed");
479 return APP2EXT_ERROR_SQLITE_REGISTRY;
481 ret = _app2sd_remove_password_from_db(pkgid);
483 app2ext_print("cannot remove password from db \n");
484 return APP2EXT_ERROR_SQLITE_REGISTRY;
489 int app2sd_move_installed_app(const char *pkgid, GList* dir_list,
490 app2ext_move_type move_type)
494 /*Validate function arguments*/
495 if (pkgid == NULL || dir_list == NULL
496 || move_type < APP2EXT_MOVE_TO_EXT
497 || move_type > APP2EXT_MOVE_TO_PHONE) {
498 app2ext_print("App2Sd Error : Invalid function arguments\n");
499 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
503 ret = _app2sd_move_app(pkgid, move_type, dir_list);
505 app2ext_print("App2Sd Error : Unable to move application\n");
509 /*If move is completed, then update installed storage to pkgmgr_parser db*/
511 pkgmgrinfo_pkgdbinfo_h handle = NULL;
512 rt = pkgmgrinfo_create_pkgdbinfo(pkgid, &handle);
514 app2ext_print("App2Sd Error : pkgmgrinfo_create_pkgdbinfo[%s] fail.. \n", pkgid);
517 if (move_type == APP2EXT_MOVE_TO_EXT) {
518 rt = pkgmgrinfo_set_installed_storage_to_pkgdbinfo(handle, INSTALL_EXTERNAL);
520 app2ext_print("App2Sd Error : fail to update installed location to db[%s, %s]\n", pkgid, INSTALL_EXTERNAL);
523 rt = pkgmgrinfo_set_installed_storage_to_pkgdbinfo(handle, INSTALL_INTERNAL);
525 app2ext_print("App2Sd Error : fail to update installed location to db[%s, %s]\n", pkgid, INSTALL_INTERNAL);
528 rt =pkgmgrinfo_save_pkgdbinfo(handle);
530 app2ext_print("pkgmgrinfo_save_pkgdbinfo[%s] failed\n", pkgid);
532 rt =pkgmgrinfo_destroy_pkgdbinfo(handle);
534 app2ext_print("pkgmgrinfo_destroy_pkgdbinfo failed\n");
539 vconf_set_int(VCONFKEY_PKGMGR_STATUS, ret);
544 int app2sd_pre_app_upgrade(const char *pkgid, GList* dir_list,
547 int ret = APP2EXT_SUCCESS;
548 char app_path[FILENAME_MAX] = { 0, };
549 char *device_node = NULL;
550 unsigned long long curr_size = 0;
553 /*Validate function arguments*/
554 if (pkgid == NULL || dir_list == NULL || size<=0) {
556 ("App2Sd Error : Invalid function arguments \n");
557 return APP2EXT_ERROR_INVALID_ARGUMENTS;
559 /*Check whether MMC is present or not */
560 ret = _app2sd_check_mmc_status();
562 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
564 return APP2EXT_ERROR_MMC_STATUS;
566 /*check app entry is there in sd card or not. */
567 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
569 app2ext_print("App2Sd Log : Checking path %s\n", app_path);
570 fp = fopen(app_path, "r+");
573 ("App2SD Error: App Entry is not present in SD Card\n");
574 return APP2EXT_ERROR_INVALID_PACKAGE;
577 /*Get installed app size*/
578 curr_size = _app2sd_calculate_file_size(app_path);
579 curr_size = (curr_size/1024)/1024;
583 ("App2SD Error: App Entry is not present in SD Card\n");
584 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
586 if (curr_size<size) {
587 ret = _app2sd_update_loopback_device_size(pkgid, size, dir_list);
588 if(APP2EXT_SUCCESS !=ret) {
590 ("App2SD Error: _app2sd_update_loopback_device_size() failed\n");
595 /*Get the associated device node for SD card applicationer */
596 device_node = _app2sd_find_associated_device_node(pkgid);
597 if (NULL == device_node) {
598 /*Do loopback setup */
599 device_node = _app2sd_do_loopback_encryption_setup(pkgid);
600 if (device_node == NULL) {
602 ("App2Sd Error : loopback encryption setup failed\n");
603 return APP2EXT_ERROR_DO_LOSETUP;
607 _app2sd_mount_app_content(pkgid, device_node,
611 app2ext_print("App2Sd Error : Re-mount failed\n");
616 return APP2EXT_ERROR_MOUNT_PATH;
621 _app2sd_mount_app_content(pkgid, device_node,
622 MOUNT_TYPE_RW_REMOUNT, NULL,
625 app2ext_print("App2Sd Error : Re-mount failed\n");
630 return APP2EXT_ERROR_MOUNT_PATH;
642 int app2sd_post_app_upgrade(const char *pkgid,
643 app2ext_status install_status)
645 char *device_name = NULL;
646 int ret = APP2EXT_SUCCESS;
647 /*Validate the function parameter recieved */
648 if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
649 || install_status > APP2EXT_STATUS_SUCCESS) {
650 app2ext_print("Invalid func parameters\n");
651 return APP2EXT_ERROR_INVALID_ARGUMENTS;
653 /*Check whether MMC is present or not */
654 ret = _app2sd_check_mmc_status();
656 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
658 return APP2EXT_ERROR_MMC_STATUS;
661 /*Get the associated device node for SD card applicationer */
662 device_name = _app2sd_find_associated_device_node(pkgid);
663 if (NULL == device_name) {
664 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
666 ret = _app2sd_unmount_app_content(pkgid);
672 app2ext_print("Unable to unmount the app content %d\n", ret);
673 return APP2EXT_ERROR_UNMOUNT;
675 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
682 ("Unable to Detach the loopback encryption setup for the application");
683 return APP2EXT_ERROR_UNMOUNT;
694 * Reserved API for forced cleanup
697 int app2sd_force_cleanup(const char *pkgid){
698 char *device_name = NULL;
699 char buf_dir[FILENAME_MAX] = { 0, };
700 int ret = APP2EXT_SUCCESS;
703 /*Validate the function parameter recieved */
705 app2ext_print("invalid func parameters\n");
706 return APP2EXT_ERROR_INVALID_ARGUMENTS;
708 memset((void *)&buf_dir, '\0', FILENAME_MAX);
709 snprintf(buf_dir, FILENAME_MAX, "%s%s", APP2SD_PATH, pkgid);
710 fp = fopen(buf_dir, "r+");
712 app2ext_print("\"%s\" not installed on SD Card\n", pkgid);
713 return APP2EXT_ERROR_INVALID_PACKAGE;
716 /*Check whether MMC is present or not */
717 ret = _app2sd_check_mmc_status();
719 app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
721 return APP2EXT_ERROR_MMC_STATUS;
724 /*Get the associated device node for SD card applicationer */
725 device_name = _app2sd_find_associated_device_node(pkgid);
726 if (NULL != device_name) {
729 ret = _app2sd_unmount_app_content(pkgid);
731 app2ext_print("Unable to unmount the app content %d\n", ret);
732 return APP2EXT_ERROR_UNMOUNT;
734 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
737 ("Unable to Detach the loopback encryption setup for the application");
738 return APP2EXT_ERROR_UNMOUNT;
742 memset((void *)&buf_dir, '\0', FILENAME_MAX);
743 snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
744 ret = _app2sd_delete_directory(buf_dir);
747 ("App2Sd Error : Unable to delete the directory %s\n",
751 /*remove passwrd from DB*/
752 ret = _app2sd_initialize_db();
754 app2ext_print("\n app2sd db initialize failed");
755 return APP2EXT_ERROR_SQLITE_REGISTRY;
757 ret = _app2sd_remove_password_from_db(pkgid);
759 app2ext_print("cannot remove password from db \n");
760 return APP2EXT_ERROR_SQLITE_REGISTRY;
766 /* This is the plug-in load function. The plugin has to bind its functions to function pointers of handle
767 @param[in/out] st_interface Specifies the storage interface.
770 app2ext_on_load(app2ext_interface *st_interface)
773 st_interface->pre_install= app2sd_pre_app_install;
774 st_interface->post_install= app2sd_post_app_install;
775 st_interface->pre_uninstall= app2sd_pre_app_uninstall;
776 st_interface->post_uninstall= app2sd_post_app_uninstall;
777 st_interface->pre_upgrade= app2sd_pre_app_upgrade;
778 st_interface->post_upgrade= app2sd_post_app_upgrade;
779 st_interface->move= app2sd_move_installed_app;
780 st_interface->enable= app2sd_on_demand_setup_init;
781 st_interface->disable= app2sd_on_demand_setup_exit;