--- /dev/null
+Garima Shrivastava<garima.s@samsung.com>
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+#SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
+PROJECT(app2ext C)
+
+SET(VERSION_MAJOR 0)
+SET(VERSION "${VERSION_MAJOR}.4.2")
+
+#Add your submodule directory name
+ADD_SUBDIRECTORY(plugin/app2sd)
+### Required packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED dlog)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+pkg_check_modules(libpkgs REQUIRED dlog)
+
+FOREACH(flag ${libpkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+### Local include directories
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc ${CMAKE_SOURCE_DIR}/src)
+
+## build app2ext library
+SET(app2ext_dir "${CMAKE_SOURCE_DIR}")
+SET(app2ext_inc_dir "${app2ext_dir}/inc")
+SET(app2ext_src_dir "${app2ext_dir}/src")
+SET(APP2EXT "app2ext")
+SET(libapp2ext_SOURCES ${app2ext_src_dir}/app2ext_interface.c)
+SET(libapp2ext_LDFLAGS " -L${LIB_INSTALL_DIR} -module -avoid-version -ldl ")
+SET(libapp2ext_CFLAGS " ${CFLAGS} -fPIC -I${app2ext_inc_dir} ")
+
+ADD_DEFINITIONS("-DLIBPREFIX=\"${LIB_INSTALL_DIR}\"")
+
+ADD_LIBRARY(${APP2EXT} SHARED ${libapp2ext_SOURCES})
+SET_TARGET_PROPERTIES(${APP2EXT} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${APP2EXT} PROPERTIES VERSION ${VERSION})
+SET_TARGET_PROPERTIES(${APP2EXT} PROPERTIES COMPILE_FLAGS "${libapp2ext_CFLAGS}")
+TARGET_LINK_LIBRARIES(${APP2EXT} ${libpkgs_LDFLAGS})
+
+SET(CMAKE_INSTALL_PREFIX "/usr")
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/app2sd.manifest.in ${CMAKE_BINARY_DIR}/app2sd.manifest @ONLY)
+
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/app2sd.pc.in ${CMAKE_BINARY_DIR}/app2sd.pc @ONLY)
+
+INSTALL(TARGETS ${APP2EXT} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/app2sd.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/inc/app2ext_interface.h DESTINATION include)
+
--- /dev/null
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+ Apache License\r
+ Version 2.0, January 2004\r
+ http://www.apache.org/licenses/\r
+\r
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+ 1. Definitions.\r
+\r
+ "License" shall mean the terms and conditions for use, reproduction,\r
+ and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+ "Licensor" shall mean the copyright owner or entity authorized by\r
+ the copyright owner that is granting the License.\r
+\r
+ "Legal Entity" shall mean the union of the acting entity and all\r
+ other entities that control, are controlled by, or are under common\r
+ control with that entity. For the purposes of this definition,\r
+ "control" means (i) the power, direct or indirect, to cause the\r
+ direction or management of such entity, whether by contract or\r
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+ outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+ "You" (or "Your") shall mean an individual or Legal Entity\r
+ exercising permissions granted by this License.\r
+\r
+ "Source" form shall mean the preferred form for making modifications,\r
+ including but not limited to software source code, documentation\r
+ source, and configuration files.\r
+\r
+ "Object" form shall mean any form resulting from mechanical\r
+ transformation or translation of a Source form, including but\r
+ not limited to compiled object code, generated documentation,\r
+ and conversions to other media types.\r
+\r
+ "Work" shall mean the work of authorship, whether in Source or\r
+ Object form, made available under the License, as indicated by a\r
+ copyright notice that is included in or attached to the work\r
+ (an example is provided in the Appendix below).\r
+\r
+ "Derivative Works" shall mean any work, whether in Source or Object\r
+ form, that is based on (or derived from) the Work and for which the\r
+ editorial revisions, annotations, elaborations, or other modifications\r
+ represent, as a whole, an original work of authorship. For the purposes\r
+ of this License, Derivative Works shall not include works that remain\r
+ separable from, or merely link (or bind by name) to the interfaces of,\r
+ the Work and Derivative Works thereof.\r
+\r
+ "Contribution" shall mean any work of authorship, including\r
+ the original version of the Work and any modifications or additions\r
+ to that Work or Derivative Works thereof, that is intentionally\r
+ submitted to Licensor for inclusion in the Work by the copyright owner\r
+ or by an individual or Legal Entity authorized to submit on behalf of\r
+ the copyright owner. For the purposes of this definition, "submitted"\r
+ means any form of electronic, verbal, or written communication sent\r
+ to the Licensor or its representatives, including but not limited to\r
+ communication on electronic mailing lists, source code control systems,\r
+ and issue tracking systems that are managed by, or on behalf of, the\r
+ Licensor for the purpose of discussing and improving the Work, but\r
+ excluding communication that is conspicuously marked or otherwise\r
+ designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+ "Contributor" shall mean Licensor and any individual or Legal Entity\r
+ on behalf of whom a Contribution has been received by Licensor and\r
+ subsequently incorporated within the Work.\r
+\r
+ 2. Grant of Copyright License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ copyright license to reproduce, prepare Derivative Works of,\r
+ publicly display, publicly perform, sublicense, and distribute the\r
+ Work and such Derivative Works in Source or Object form.\r
+\r
+ 3. Grant of Patent License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ (except as stated in this section) patent license to make, have made,\r
+ use, offer to sell, sell, import, and otherwise transfer the Work,\r
+ where such license applies only to those patent claims licensable\r
+ by such Contributor that are necessarily infringed by their\r
+ Contribution(s) alone or by combination of their Contribution(s)\r
+ with the Work to which such Contribution(s) was submitted. If You\r
+ institute patent litigation against any entity (including a\r
+ cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+ or a Contribution incorporated within the Work constitutes direct\r
+ or contributory patent infringement, then any patent licenses\r
+ granted to You under this License for that Work shall terminate\r
+ as of the date such litigation is filed.\r
+\r
+ 4. Redistribution. You may reproduce and distribute copies of the\r
+ Work or Derivative Works thereof in any medium, with or without\r
+ modifications, and in Source or Object form, provided that You\r
+ meet the following conditions:\r
+\r
+ (a) You must give any other recipients of the Work or\r
+ Derivative Works a copy of this License; and\r
+\r
+ (b) You must cause any modified files to carry prominent notices\r
+ stating that You changed the files; and\r
+\r
+ (c) You must retain, in the Source form of any Derivative Works\r
+ that You distribute, all copyright, patent, trademark, and\r
+ attribution notices from the Source form of the Work,\r
+ excluding those notices that do not pertain to any part of\r
+ the Derivative Works; and\r
+\r
+ (d) If the Work includes a "NOTICE" text file as part of its\r
+ distribution, then any Derivative Works that You distribute must\r
+ include a readable copy of the attribution notices contained\r
+ within such NOTICE file, excluding those notices that do not\r
+ pertain to any part of the Derivative Works, in at least one\r
+ of the following places: within a NOTICE text file distributed\r
+ as part of the Derivative Works; within the Source form or\r
+ documentation, if provided along with the Derivative Works; or,\r
+ within a display generated by the Derivative Works, if and\r
+ wherever such third-party notices normally appear. The contents\r
+ of the NOTICE file are for informational purposes only and\r
+ do not modify the License. You may add Your own attribution\r
+ notices within Derivative Works that You distribute, alongside\r
+ or as an addendum to the NOTICE text from the Work, provided\r
+ that such additional attribution notices cannot be construed\r
+ as modifying the License.\r
+\r
+ You may add Your own copyright statement to Your modifications and\r
+ may provide additional or different license terms and conditions\r
+ for use, reproduction, or distribution of Your modifications, or\r
+ for any such Derivative Works as a whole, provided Your use,\r
+ reproduction, and distribution of the Work otherwise complies with\r
+ the conditions stated in this License.\r
+\r
+ 5. Submission of Contributions. Unless You explicitly state otherwise,\r
+ any Contribution intentionally submitted for inclusion in the Work\r
+ by You to the Licensor shall be under the terms and conditions of\r
+ this License, without any additional terms or conditions.\r
+ Notwithstanding the above, nothing herein shall supersede or modify\r
+ the terms of any separate license agreement you may have executed\r
+ with Licensor regarding such Contributions.\r
+\r
+ 6. Trademarks. This License does not grant permission to use the trade\r
+ names, trademarks, service marks, or product names of the Licensor,\r
+ except as required for reasonable and customary use in describing the\r
+ origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+ 7. Disclaimer of Warranty. Unless required by applicable law or\r
+ agreed to in writing, Licensor provides the Work (and each\r
+ Contributor provides its Contributions) on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+ implied, including, without limitation, any warranties or conditions\r
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+ PARTICULAR PURPOSE. You are solely responsible for determining the\r
+ appropriateness of using or redistributing the Work and assume any\r
+ risks associated with Your exercise of permissions under this License.\r
+\r
+ 8. Limitation of Liability. In no event and under no legal theory,\r
+ whether in tort (including negligence), contract, or otherwise,\r
+ unless required by applicable law (such as deliberate and grossly\r
+ negligent acts) or agreed to in writing, shall any Contributor be\r
+ liable to You for damages, including any direct, indirect, special,\r
+ incidental, or consequential damages of any character arising as a\r
+ result of this License or out of the use or inability to use the\r
+ Work (including but not limited to damages for loss of goodwill,\r
+ work stoppage, computer failure or malfunction, or any and all\r
+ other commercial damages or losses), even if such Contributor\r
+ has been advised of the possibility of such damages.\r
+\r
+ 9. Accepting Warranty or Additional Liability. While redistributing\r
+ the Work or Derivative Works thereof, You may choose to offer,\r
+ and charge a fee for, acceptance of support, warranty, indemnity,\r
+ or other liability obligations and/or rights consistent with this\r
+ License. However, in accepting such obligations, You may act only\r
+ on Your own behalf and on Your sole responsibility, not on behalf\r
+ of any other Contributor, and only if You agree to indemnify,\r
+ defend, and hold each Contributor harmless for any liability\r
+ incurred by, or claims asserted against, such Contributor by reason\r
+ of your accepting any such warranty or additional liability.\r
+\r
+ END OF TERMS AND CONDITIONS\r
+\r
+ APPENDIX: How to apply the Apache License to your work.\r
+\r
+ To apply the Apache License to your work, attach the following\r
+ boilerplate notice, with the fields enclosed by brackets "[]"\r
+ replaced with your own identifying information. (Don't include\r
+ the brackets!) The text should be enclosed in the appropriate\r
+ comment syntax for the file format. We also recommend that a\r
+ file or class name and description of purpose be included on the\r
+ same "printed page" as the copyright notice for easier\r
+ identification within third-party archives.\r
+\r
+ Copyright [yyyy] [name of copyright owner]\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
--- /dev/null
+#!/bin/sh
+
+export TET_INSTALL_PATH=/tetware # local tetware path
+export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target
+export PATH=$TET_TARGET_PATH/bin:$PATH
+export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH
+export TET_ROOT=$TET_TARGET_PATH
+
+export TET_SUITE_ROOT=`pwd`
+FILE_NAME_EXTENSION=`date +%s`
+
+RESULT_DIR=results
+HTML_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.html
+JOURNAL_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.journal
+
+mkdir -p $RESULT_DIR
+
+tcc -c -p ./
+tcc -b -j $JOURNAL_RESULT -p ./
+grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT
--- /dev/null
+#!/bin/sh
+export TET_INSTALL_PATH=/mnt/nfs/TETware
+export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target
+export PATH=$TET_TARGET_PATH/bin:$PATH
+export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH
+
+export TET_ROOT=$TET_TARGET_PATH
+
+export TET_SUITE_ROOT=`pwd`
+FILE_NAME_EXTENSION=`date +%s`
+
+RESULT_DIR=results
+HTML_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.html
+JOURNAL_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.journal
+
+mkdir -p $RESULT_DIR
+
+tcc -e -j $JOURNAL_RESULT -p ./
+grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT
--- /dev/null
+# TET reserved codes
+0 "PASS"
+1 "FAIL"
+2 "UNRESOLVED"
+3 "NOTINUSE"
+4 "UNSUPPORTED"
+5 "UNTESTED"
+6 "UNINITIATED"
+7 "NORESULT"
+
+# Test suite additional codes
+33 "INSPECT"
--- /dev/null
+all
+ ^TEST
+##### Scenarios for TEST #####
+
+# Test scenario
+TEST
+ :include:/unit/tslist
--- /dev/null
+TET_OUTPUT_CAPTURE=False
+TET_BUILD_TOOL=make
+TET_PASS_TC_NAME=True
--- /dev/null
+TET_OUTPUT_CAPTURE=False
+TET_CLEAN_TOOL=make clean
--- /dev/null
+TET_OUTPUT_CAPTURE=False
--- /dev/null
+CC ?= gcc
+
+TARGETS = utc_ApplicationFW_app2ext_init_func\
+ utc_ApplicationFW_app2ext_deinit_func\
+ utc_ApplicationFW_app3ext_get_app_location\
+ utc_ApplicationFW_app2ext_pre_install_func\
+ utc_ApplicationFW_app2ext_post_install_func\
+ utc_ApplicationFW_app2ext_pre_upgrade_func\
+ utc_ApplicationFW_app2ext_post_upgrade_func\
+ utc_ApplicationFW_app2ext_pre_uninstall_func\
+ utc_ApplicationFW_app2ext_post_uninstall_func\
+ utc_ApplicationFW_app2ext_move_func
+
+PKGS = app2sd glib-2.0
+
+LDFLAGS = `pkg-config --libs $(PKGS)`
+LDFLAGS += $(TET_ROOT)/lib/tet3/tcm_s.o
+LDFLAGS += -L$(TET_ROOT)/lib/tet3 -ltcm_s
+LDFLAGS += -L$(TET_ROOT)/lib/tet3 -lapi_s
+
+CFLAGS = -I. `pkg-config --cflags $(PKGS)`
+CFLAGS += -I$(TET_ROOT)/inc/tet3
+CFLAGS += -Wall
+
+all: $(TARGETS)
+
+$(TARGETS): %: %.c
+ $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
+
+clean:
+ rm -f $(TARGETS)
--- /dev/null
+#!/bin/sh
+
+TMPSTR=$0
+SCRIPT=${TMPSTR##*/}
+
+if [ $# -lt 2 ]; then
+ echo "Usage) $SCRIPT module_name api_name"
+ exit 1
+fi
+
+MODULE=$1
+API=$2
+TEMPLATE=utc_MODULE_API_func.c.in
+TESTCASE=utc_${MODULE}_${API}_func
+
+sed -e '
+ s^@API@^'"$API"'^g
+ s^@MODULE@^'"$MODULE"'^g
+ ' $TEMPLATE > $TESTCASE.c
+
+if [ ! -e "$TESTCASE.c" ]; then
+ echo "Failed"
+ exit 1
+fi
+echo "Testcase file is $TESTCASE.c"
+echo "Done"
+echo "please put \"$TESTCASE\" as Target in Makefile"
+echo "please put \"/unit/$TESTCASE\" in tslist"
--- /dev/null
+/unit/utc_ApplicationFW_app2ext_init_func
+/unit/utc_ApplicationFW_app2ext_deinit_func
+/unit/utc_ApplicationFW_app2ext_get_app_location_func
+/unit/utc_ApplicationFW_app2ext_pre_install_func
+/unit/utc_ApplicationFW_app2ext_post_install_func
+/unit/utc_ApplicationFW_app2ext_pre_upgrade_func
+/unit/utc_ApplicationFW_app2ext_post_upgrade_func
+/unit/utc_ApplicationFW_app2ext_move_func
+/unit/utc_ApplicationFW_app2ext_pre_uninstall_func
+/unit/utc_ApplicationFW_app2ext_post_uninstall_func
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <tet_api.h>
+#include <app2ext_interface.h>
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup) (void) = startup;
+void (*tet_cleanup) (void) = cleanup;
+
+static void utc_ApplicationFW_app2ext_deinit_func_01(void);
+static void utc_ApplicationFW_app2ext_deinit_func_02(void);
+static void utc_ApplicationFW_app2ext_deinit_func_03(void);
+
+enum {
+ POSITIVE_TC_IDX = 0x01,
+ NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+ {utc_ApplicationFW_app2ext_deinit_func_01, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_deinit_func_02, NEGATIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_deinit_func_03, NEGATIVE_TC_IDX},
+ {NULL, 0}
+};
+
+app2ext_handle *handle1 = NULL;
+app2ext_handle *handle2 = NULL;
+
+
+static void startup(void)
+{
+ handle1 = app2ext_init(APP2EXT_SD_CARD);
+ if (handle1 == NULL) {
+ tet_infoline("Unable to call app2ext_init()");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ handle2 = app2ext_init(APP2EXT_SD_CARD);
+ if (handle2 == NULL) {
+ tet_infoline("Unable to call app2ext_init()");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of app2ext_deinit()
+ */
+static void utc_ApplicationFW_app2ext_deinit_func_01(void)
+{
+ int ret = app2ext_deinit(handle1);
+
+ if (ret != 0) {
+ tet_infoline
+ ("app2ext_deinit() failed in positive test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_deinit()
+ */
+static void utc_ApplicationFW_app2ext_deinit_func_02(void)
+{
+ int ret = app2ext_deinit(NULL);
+
+ if (ret == 0) {
+ tet_infoline
+ ("app2ext_deinit() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_deinit()
+ */
+static void utc_ApplicationFW_app2ext_deinit_func_03(void)
+{
+ int ret = app2ext_deinit(handle2);
+
+ if (ret != 0) {
+ tet_infoline
+ ("app2ext_deinit() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ handle2= NULL;
+ ret = app2ext_deinit(handle2);
+
+ if (ret == 0) {
+ tet_infoline
+ ("app2ext_deinit() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+
+ tet_result(TET_PASS);
+}
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <tet_api.h>
+#include <app2ext_interface.h>
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup) (void) = startup;
+void (*tet_cleanup) (void) = cleanup;
+
+static void utc_ApplicationFW_app2ext_get_app_location_func_01(void);
+static void utc_ApplicationFW_app2ext_get_app_location_func_02(void);
+
+enum {
+ POSITIVE_TC_IDX = 0x01,
+ NEGATIVE_TC_IDX = 0x02,
+};
+
+struct tet_testlist tet_testlist[] = {
+ {utc_ApplicationFW_app2ext_get_app_location_func_01, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_get_app_location_func_02, NEGATIVE_TC_IDX},
+ {NULL, 0}
+};
+
+int ret = APP2EXT_SUCCESS;
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of app2ext_get_app_location()
+ */
+static void utc_ApplicationFW_app2ext_get_app_location_func_01(void)
+{
+ int result = 0;
+ char *appname = "com.samsung.calculator";
+ result = app2ext_get_app_location(appname);
+ if (result == APP2EXT_ERROR_INVALID_ARGUMENTS) {
+ tet_printf("app2ext_get_app_location() failed in positive test case\n");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_get_app_location()
+ */
+static void utc_ApplicationFW_app2ext_get_app_location_func_02(void)
+{
+ int result = app2ext_get_app_location(NULL);
+ if (result != APP2EXT_ERROR_INVALID_ARGUMENTS) {
+ tet_printf("app2ext_get_app_location() failed in negative test case\n");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <tet_api.h>
+#include <app2ext_interface.h>
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup) (void) = startup;
+void (*tet_cleanup) (void) = cleanup;
+
+static void utc_ApplicationFW_app2ext_init_func_01(void);
+static void utc_ApplicationFW_app2ext_init_func_02(void);
+static void utc_ApplicationFW_app2ext_init_func_03(void);
+
+enum {
+ POSITIVE_TC_IDX = 0x01,
+ NEGATIVE_TC_IDX = 0x02,
+};
+
+struct tet_testlist tet_testlist[] = {
+ {utc_ApplicationFW_app2ext_init_func_01, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_init_func_02, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_init_func_03, NEGATIVE_TC_IDX},
+ {NULL, 0}
+};
+
+int r = APP2EXT_SUCCESS;
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of app2ext_init()
+ */
+static void utc_ApplicationFW_app2ext_init_func_01(void)
+{
+ app2ext_handle *handle = NULL;
+ handle = app2ext_init(APP2EXT_SD_CARD);
+ if (handle == NULL) {
+ tet_infoline("app2ext_init() failed in positive test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Positive test case of app2ext_init()
+ */
+static void utc_ApplicationFW_app2ext_init_func_02(void)
+{
+ app2ext_handle *handle1 = NULL;
+ app2ext_handle *handle2 = NULL;
+ handle1 = app2ext_init(APP2EXT_SD_CARD);
+ if (handle1 == NULL) {
+ tet_infoline("app2ext_init() failed in positive test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ handle2 = app2ext_init(APP2EXT_SD_CARD);
+ if (handle2 == NULL) {
+ tet_infoline("app2ext_init() failed in positive test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_init()
+ */
+static void utc_ApplicationFW_app2ext_init_func_03(void)
+{
+ app2ext_handle *handle = NULL;
+ handle = app2ext_init(10);
+ if (handle != NULL) {
+ tet_infoline("app2ext_init() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expostss or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <tet_api.h>
+#include <app2ext_interface.h>
+
+static void startup(void);
+static void cleanup(void);
+
+char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
+
+void (*tet_startup) (void) = startup;
+void (*tet_cleanup) (void) = cleanup;
+
+static void utc_ApplicationFW_app2ext_move_func_01(void);
+static void utc_ApplicationFW_app2ext_move_func_02(void);
+static void utc_ApplicationFW_app2ext_move_func_03(void);
+static void utc_ApplicationFW_app2ext_move_func_04(void);
+static void utc_ApplicationFW_app2ext_move_func_05(void);
+
+enum {
+ POSITIVE_TC_IDX = 0x01,
+ NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+ {utc_ApplicationFW_app2ext_move_func_01, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_move_func_02, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_move_func_03, NEGATIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_move_func_04, NEGATIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_move_func_05, NEGATIVE_TC_IDX},
+ {NULL, 0}
+};
+
+app2ext_handle *handle = NULL;
+
+static void startup(void)
+{
+ int ret = -1;
+ ret = system("pkgcmd -it rpm -p /mnt/nfs/TC-tet/unit/com.samsung.calculator-0.1.36-1.armv7l.rpm -q");
+ if (ret != 0) {
+ tet_infoline("Unable to install");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ handle = app2ext_init(APP2EXT_SD_CARD);
+ if (handle == NULL) {
+ tet_infoline("Unable to call app2ext_init()");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+}
+
+static void cleanup(void)
+{
+ if (handle) {
+ app2ext_deinit(handle);
+ }
+}
+
+static GList * populate_dir_details()
+{
+ GList *dir_list = NULL;
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ int i;
+
+
+ for (i=0; i<3; i++) {
+ dir_detail = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
+ if (dir_detail == NULL) {
+ printf("\nMemory allocation failed\n");
+ goto FINISH_OFF;
+ }
+ dir_detail->name = (char*) calloc(1, sizeof(char)*(strlen(pkg_ro_content_rpm[i])+2));
+ if (dir_detail->name == NULL) {
+ printf("\nMemory allocation failed\n");
+ free(dir_detail);
+ goto FINISH_OFF;
+ }
+ snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i])+1), "%s", pkg_ro_content_rpm[i]);
+ dir_detail->type = APP2EXT_DIR_RO;
+ dir_list = g_list_append(dir_list, dir_detail);
+ }
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ list = g_list_next(list);
+ }
+ }
+ return dir_list;
+FINISH_OFF:
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+ return NULL;
+}
+
+static void clear_dir_list(GList* dir_list)
+{
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+}
+
+/**
+ * @brief Positive test case of app2ext_move()
+ */
+static void utc_ApplicationFW_app2ext_move_func_01(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ GList *dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ printf("\nError in populating the directory list\n");
+ return -1;
+ }
+
+ ret = handle->interface.move("com.samsung.calculator", dir_list, APP2EXT_MOVE_TO_PHONE);
+ if (ret != APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_move() failed in positive test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+/**
+ * @brief Positive test case of app2ext_move()
+ */
+static void utc_ApplicationFW_app2ext_move_func_02(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ GList *dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ printf("\nError in populating the directory list\n");
+ return -1;
+ }
+
+ ret = handle->interface.move("com.samsung.calculator", dir_list, APP2EXT_MOVE_TO_EXT);
+ if (ret != APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_move() failed in positive test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_move()
+ */
+static void utc_ApplicationFW_app2ext_move_func_03(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ GList *dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ printf("\nError in populating the directory list\n");
+ return -1;
+ }
+
+ ret = handle->interface.move(NULL, dir_list, APP2EXT_MOVE_TO_PHONE);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_move() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_move()
+ */
+static void utc_ApplicationFW_app2ext_move_func_04(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ ret = handle->interface.move("com.samsung.calculator", NULL, APP2EXT_MOVE_TO_PHONE);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_move() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+/**
+ * @brief Negative test case of app2ext_move()
+ */
+static void utc_ApplicationFW_app2ext_move_func_05(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ GList *dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ printf("\nError in populating the directory list\n");
+ return -1;
+ }
+
+ ret = handle->interface.move("com.samsung.calculator", dir_list, 10);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_move() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expostss or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <tet_api.h>
+#include <app2ext_interface.h>
+
+static void startup(void);
+static void cleanup(void);
+
+char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
+
+void (*tet_startup) (void) = startup;
+void (*tet_cleanup) (void) = cleanup;
+
+static void utc_ApplicationFW_app2ext_post_install_func_01(void);
+static void utc_ApplicationFW_app2ext_post_install_func_02(void);
+static void utc_ApplicationFW_app2ext_post_install_func_03(void);
+
+enum {
+ POSITIVE_TC_IDX = 0x01,
+ NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+ {utc_ApplicationFW_app2ext_post_install_func_01, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_post_install_func_02, NEGATIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_post_install_func_03, NEGATIVE_TC_IDX},
+ {NULL, 0}
+};
+
+app2ext_handle *handle = NULL;
+
+
+static GList * populate_dir_details()
+{
+ GList *dir_list = NULL;
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ int i;
+
+ for (i=0; i<3; i++) {
+ dir_detail = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
+ if (dir_detail == NULL) {
+ printf("\nMemory allocation failed\n");
+ goto FINISH_OFF;
+ }
+ dir_detail->name = (char*) calloc(1, sizeof(char)*(strlen(pkg_ro_content_rpm[i])+2));
+ if (dir_detail->name == NULL) {
+ printf("\nMemory allocation failed\n");
+ free(dir_detail);
+ goto FINISH_OFF;
+ }
+ snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i])+1), "%s", pkg_ro_content_rpm[i]);
+ dir_detail->type = APP2EXT_DIR_RO;
+ dir_list = g_list_append(dir_list, dir_detail);
+ }
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ list = g_list_next(list);
+ }
+ }
+ return dir_list;
+FINISH_OFF:
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+ return NULL;
+}
+
+static void clear_dir_list(GList* dir_list)
+{
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+}
+
+static void startup(void)
+{
+ GList *dir_list = NULL;
+ int ret = -1;
+ handle = app2ext_init(APP2EXT_SD_CARD);
+ if (handle == NULL) {
+ tet_infoline("Unable to call app2ext_init()");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+
+ dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ tet_infoline
+ ("Unable to populate dirlist");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ ret = handle->interface.pre_install("com.samsung.calculator", dir_list, 5);
+ if (ret) {
+ tet_infoline
+ ("Unable to do app2ext_pre_install()");
+ tet_result(TET_UNINITIATED);
+ handle->interface.post_install("com.samsung.calculator", 2);
+ return;
+ }
+}
+
+static void cleanup(void)
+{
+ app2ext_deinit(handle);
+}
+
+/**
+ * @brief Positive test case of app2ext_post_install()
+ */
+static void utc_ApplicationFW_app2ext_post_install_func_01(void)
+{
+ int ret = APP2EXT_SUCCESS;
+
+ ret = handle->interface.post_install("com.samsung.calculator", 1);
+ if (ret != APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_post_install() failed in positive test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_post_install()
+ */
+static void utc_ApplicationFW_app2ext_post_install_func_02(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ ret = handle->interface.post_install(NULL, 2);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_post_install() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_post_install()
+ */
+static void utc_ApplicationFW_app2ext_post_install_func_03(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ ret = handle->interface.post_install("com.samsung.calculator", 10);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_post_install() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expostss or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <tet_api.h>
+#include <app2ext_interface.h>
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup) (void) = startup;
+void (*tet_cleanup) (void) = cleanup;
+
+static void utc_ApplicationFW_app2ext_post_uninstall_func_01(void);
+static void utc_ApplicationFW_app2ext_post_uninstall_func_02(void);
+
+enum {
+ POSITIVE_TC_IDX = 0x01,
+ NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+ {utc_ApplicationFW_app2ext_post_uninstall_func_01, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_post_uninstall_func_02, NEGATIVE_TC_IDX},
+ {NULL, 0}
+};
+
+app2ext_handle *handle = NULL;
+
+static void startup(void)
+{
+ int ret = -1;
+ ret = system("pkgcmd -it rpm -p /mnt/nfs/TC-tet/unit/com.samsung.calculator-0.1.36-1.armv7l.rpm -q");
+ if (ret != 0) {
+ tet_infoline("Unable to install");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ handle = app2ext_init(APP2EXT_SD_CARD);
+ if (handle == NULL) {
+ tet_infoline("Unable to call app2ext_init()");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ ret = handle->interface.pre_uninstall("com.samsung.calculator");
+ if (ret) {
+ tet_infoline
+ ("Unable to do app2ext_pre_uninstall()");
+ tet_result(TET_UNINITIATED);
+ handle->interface.post_uninstall("com.samsung.calculator");
+ return;
+ }
+}
+
+static void cleanup(void)
+{
+ app2ext_deinit(handle);
+ int ret = -1;
+ ret = system("pkgcmd -ut rpm -n com.samsung.calculator -q");
+ if (ret != 0) {
+ tet_infoline("Unable to uninstall");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+}
+
+/**
+ * @brief Positive test case of app2ext_post_uninstall()
+ */
+static void utc_ApplicationFW_app2ext_post_uninstall_func_01(void)
+{
+ int ret = APP2EXT_SUCCESS;
+
+ ret = handle->interface.post_uninstall("com.samsung.calculator");
+ if (ret != APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_post_uninstall() failed in positive test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_post_uninstall()
+ */
+static void utc_ApplicationFW_app2ext_post_uninstall_func_02(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ ret = handle->interface.post_uninstall(NULL);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_post_uninstall() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expostss or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <tet_api.h>
+#include <app2ext_interface.h>
+
+static void startup(void);
+static void cleanup(void);
+
+char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
+
+void (*tet_startup) (void) = startup;
+void (*tet_cleanup) (void) = cleanup;
+
+static void utc_ApplicationFW_app2ext_post_upgrade_func_01(void);
+static void utc_ApplicationFW_app2ext_post_upgrade_func_02(void);
+static void utc_ApplicationFW_app2ext_post_upgrade_func_03(void);
+
+enum {
+ POSITIVE_TC_IDX = 0x01,
+ NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+ {utc_ApplicationFW_app2ext_post_upgrade_func_01, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_post_upgrade_func_02, NEGATIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_post_upgrade_func_03, NEGATIVE_TC_IDX},
+ {NULL, 0}
+};
+
+app2ext_handle *handle = NULL;
+
+static GList * populate_dir_details()
+{
+ GList *dir_list = NULL;
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ int i;
+
+
+ for (i=0; i<3; i++) {
+ dir_detail = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
+ if (dir_detail == NULL) {
+ printf("\nMemory allocation failed\n");
+ goto FINISH_OFF;
+ }
+ dir_detail->name = (char*) calloc(1, sizeof(char)*(strlen(pkg_ro_content_rpm[i])+2));
+ if (dir_detail->name == NULL) {
+ printf("\nMemory allocation failed\n");
+ free(dir_detail);
+ goto FINISH_OFF;
+ }
+ snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i])+1), "%s", pkg_ro_content_rpm[i]);
+ dir_detail->type = APP2EXT_DIR_RO;
+ dir_list = g_list_append(dir_list, dir_detail);
+ }
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ list = g_list_next(list);
+ }
+ }
+ return dir_list;
+FINISH_OFF:
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+ return NULL;
+}
+
+static void clear_dir_list(GList* dir_list)
+{
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+}
+
+
+static void startup(void)
+{
+ GList *dir_list = NULL;
+ int ret = -1;
+ ret = system("pkgcmd -it rpm -p /mnt/nfs/TC-tet/unit/com.samsung.calculator-0.1.36-1.armv7l.rpm -q");
+ if (ret != 0) {
+ tet_infoline("Unable to install");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ handle = app2ext_init(APP2EXT_SD_CARD);
+ if (handle == NULL) {
+ tet_infoline("Unable to call app2ext_init()");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+
+ dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ tet_infoline
+ ("Unable to populate dirlist");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ ret = handle->interface.pre_upgrade("com.samsung.calculator", dir_list, 10);
+ /*if (ret) {
+ tet_infoline
+ ("app2ext_pre_upgrade() failed in positive test case");
+ handle->interface.post_upgrade("com.samsung.calculator", 2);
+ tet_result(TET_UNINITIATED);
+ return;
+ }*/
+}
+
+static void cleanup(void)
+{
+ int ret = 0;
+ if (handle) {
+ app2ext_deinit(handle);
+ }
+
+ ret = system("pkgcmd -ut rpm -n com.samsung.calculator -q");
+ if (ret != 0) {
+ tet_infoline("Unable to uninstall");
+ }
+}
+
+/**
+ * @brief Positive test case of app2ext_post_upgrade()
+ */
+static void utc_ApplicationFW_app2ext_post_upgrade_func_01(void)
+{
+ int ret = APP2EXT_SUCCESS;
+
+ ret = handle->interface.post_upgrade("com.samsung.calculator", 1);
+ if (ret != APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_post_upgrade() failed in positive test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_post_upgrade()
+ */
+static void utc_ApplicationFW_app2ext_post_upgrade_func_02(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ ret = handle->interface.post_upgrade(NULL, 2);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_post_upgrade() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_post_upgrade()
+ */
+static void utc_ApplicationFW_app2ext_post_upgrade_func_03(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ ret = handle->interface.post_upgrade("com.samsung.calculator", 10);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_post_upgrade() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <tet_api.h>
+#include <app2ext_interface.h>
+
+static void startup(void);
+static void cleanup(void);
+
+char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
+
+void (*tet_startup) (void) = startup;
+void (*tet_cleanup) (void) = cleanup;
+
+static void utc_ApplicationFW_app2ext_pre_install_func_01(void);
+static void utc_ApplicationFW_app2ext_pre_install_func_02(void);
+static void utc_ApplicationFW_app2ext_pre_install_func_03(void);
+static void utc_ApplicationFW_app2ext_pre_install_func_04(void);
+
+enum {
+ POSITIVE_TC_IDX = 0x01,
+ NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+ {utc_ApplicationFW_app2ext_pre_install_func_01, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_pre_install_func_02, NEGATIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_pre_install_func_03, NEGATIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_pre_install_func_04, NEGATIVE_TC_IDX},
+ {NULL, 0}
+};
+
+app2ext_handle *handle = NULL;
+
+static void startup(void)
+{
+ handle = app2ext_init(APP2EXT_SD_CARD);
+ if (handle == NULL) {
+ tet_infoline("Unable to call app2ext_init()");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+}
+
+static void cleanup(void)
+{
+ if (handle) {
+ handle->interface.post_install("com.samsung.calculator", 1);
+ app2ext_deinit(handle);
+ }
+}
+
+static GList * populate_dir_details()
+{
+ GList *dir_list = NULL;
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ int i;
+
+
+ for (i=0; i<3; i++) {
+ dir_detail = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
+ if (dir_detail == NULL) {
+ printf("\nMemory allocation failed\n");
+ goto FINISH_OFF;
+ }
+ dir_detail->name = (char*) calloc(1, sizeof(char)*(strlen(pkg_ro_content_rpm[i])+2));
+ if (dir_detail->name == NULL) {
+ printf("\nMemory allocation failed\n");
+ free(dir_detail);
+ goto FINISH_OFF;
+ }
+ snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i])+1), "%s", pkg_ro_content_rpm[i]);
+ dir_detail->type = APP2EXT_DIR_RO;
+ dir_list = g_list_append(dir_list, dir_detail);
+ }
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ list = g_list_next(list);
+ }
+ }
+ return dir_list;
+FINISH_OFF:
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+ return NULL;
+}
+
+static void clear_dir_list(GList* dir_list)
+{
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+}
+
+/**
+ * @brief Positive test case of app2ext_pre_install()
+ */
+static void utc_ApplicationFW_app2ext_pre_install_func_01(void)
+{
+ GList *dir_list = NULL;
+ int ret = APP2EXT_SUCCESS;
+
+ dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ tet_infoline
+ ("Unable to populate dirlist");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ ret = handle->interface.pre_install("com.samsung.calculator", dir_list, 5);
+ if (ret != APP2EXT_SUCCESS) {
+ tet_printf("app2ext_pre_install() failed. Reason :%d", ret);
+ tet_infoline
+ ("app2ext_pre_install() failed in positive test case");
+ handle->interface.post_install("com.samsung.calculator", 2);
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_pre_install()
+ */
+static void utc_ApplicationFW_app2ext_pre_install_func_02(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ ret = handle->interface.pre_install("com.samsung.calculator", NULL, 10);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_pre_install() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_pre_install()
+ */
+static void utc_ApplicationFW_app2ext_pre_install_func_03(void)
+{
+ GList *dir_list = NULL;
+ int ret = APP2EXT_SUCCESS;
+
+ dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ tet_infoline
+ ("Unable to populate dirlist");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ ret = handle->interface.pre_install(NULL, dir_list, 10);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_pre_install() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_pre_install()
+ */
+static void utc_ApplicationFW_app2ext_pre_install_func_04(void)
+{
+ GList *dir_list = NULL;
+ int ret = APP2EXT_SUCCESS;
+
+ dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ tet_infoline
+ ("Unable to populate dirlist");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ ret = handle->interface.pre_install("com.samsung.calculator", dir_list, 0);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_pre_install() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <tet_api.h>
+#include <app2ext_interface.h>
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup) (void) = startup;
+void (*tet_cleanup) (void) = cleanup;
+
+static void utc_ApplicationFW_app2ext_pre_uninstall_func_01(void);
+static void utc_ApplicationFW_app2ext_pre_uninstall_func_02(void);
+
+enum {
+ POSITIVE_TC_IDX = 0x01,
+ NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+ {utc_ApplicationFW_app2ext_pre_uninstall_func_01, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_pre_uninstall_func_02, NEGATIVE_TC_IDX},
+ {NULL, 0}
+};
+
+app2ext_handle *handle = NULL;
+
+static void startup(void)
+{
+ int ret = -1;
+ ret = system("pkgcmd -it rpm -p /mnt/nfs/TC-tet/unit/com.samsung.calculator-0.1.36-1.armv7l.rpm -q");
+ if (ret != 0) {
+ tet_infoline("Unable to install");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ handle = app2ext_init(APP2EXT_SD_CARD);
+ if (handle == NULL) {
+ tet_infoline("Unable to call app2ext_init()");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+}
+
+static void cleanup(void)
+{
+ int ret = 0;
+ if (handle) {
+// handle->interface.post_uninstall("com.samsung.calculator");
+ app2ext_deinit(handle);
+ }
+ ret = system("pkgcmd -ut rpm -n com.samsung.calculator -q");
+ if (ret != 0) {
+ tet_infoline("Unable to uninstall");
+ }
+}
+
+
+/**
+ * @brief Positive test case of app2ext_pre_uninstall()
+ */
+static void utc_ApplicationFW_app2ext_pre_uninstall_func_01(void)
+{
+ int ret = APP2EXT_SUCCESS;
+
+ ret = handle->interface.pre_uninstall("com.samsung.calculator");
+ if (ret != APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_pre_uninstall() failed in positive test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_pre_uninstall()
+ */
+static void utc_ApplicationFW_app2ext_pre_uninstall_func_02(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ ret = handle->interface.pre_uninstall(NULL);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_pre_uninstall() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <tet_api.h>
+#include <app2ext_interface.h>
+
+static void startup(void);
+static void cleanup(void);
+
+char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
+
+void (*tet_startup) (void) = startup;
+void (*tet_cleanup) (void) = cleanup;
+
+static void utc_ApplicationFW_app2ext_pre_upgrade_func_01(void);
+static void utc_ApplicationFW_app2ext_pre_upgrade_func_02(void);
+static void utc_ApplicationFW_app2ext_pre_upgrade_func_03(void);
+static void utc_ApplicationFW_app2ext_pre_upgrade_func_04(void);
+static void utc_ApplicationFW_app2ext_pre_upgrade_func_05(void);
+
+enum {
+ POSITIVE_TC_IDX = 0x01,
+ NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+ {utc_ApplicationFW_app2ext_pre_upgrade_func_01, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_pre_upgrade_func_02, POSITIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_pre_upgrade_func_03, NEGATIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_pre_upgrade_func_04, NEGATIVE_TC_IDX},
+ {utc_ApplicationFW_app2ext_pre_upgrade_func_05, NEGATIVE_TC_IDX},
+ {NULL, 0}
+};
+
+app2ext_handle *handle = NULL;
+
+static void startup(void)
+{
+ int ret = -1;
+ ret = system("pkgcmd -it rpm -p /mnt/nfs/TC-tet/unit/com.samsung.calculator-0.1.36-1.armv7l.rpm -q");
+ if (ret != 0) {
+ tet_infoline("Unable to install");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ handle = app2ext_init(APP2EXT_SD_CARD);
+ if (handle == NULL) {
+ tet_infoline("Unable to call app2ext_init()");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+}
+
+static void cleanup(void)
+{
+ int ret = 0;
+ if (handle) {
+ handle->interface.post_upgrade("com.samsung.calculator", 1);
+ app2ext_deinit(handle);
+ }
+
+ ret = system("pkgcmd -ut rpm -n com.samsung.calculator -q");
+ if (ret != 0) {
+ tet_infoline("Unable to uninstall");
+ }
+}
+
+static GList * populate_dir_details()
+{
+ GList *dir_list = NULL;
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ int i;
+
+
+ for (i=0; i<3; i++) {
+ dir_detail = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
+ if (dir_detail == NULL) {
+ printf("\nMemory allocation failed\n");
+ goto FINISH_OFF;
+ }
+ dir_detail->name = (char*) calloc(1, sizeof(char)*(strlen(pkg_ro_content_rpm[i])+2));
+ if (dir_detail->name == NULL) {
+ printf("\nMemory allocation failed\n");
+ free(dir_detail);
+ goto FINISH_OFF;
+ }
+ snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i])+1), "%s", pkg_ro_content_rpm[i]);
+ dir_detail->type = APP2EXT_DIR_RO;
+ dir_list = g_list_append(dir_list, dir_detail);
+ }
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ list = g_list_next(list);
+ }
+ }
+ return dir_list;
+FINISH_OFF:
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+ return NULL;
+}
+
+static void clear_dir_list(GList* dir_list)
+{
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+}
+
+/**
+ * @brief Positive test case of app2ext_pre_upgrade()
+ */
+static void utc_ApplicationFW_app2ext_pre_upgrade_func_01(void)
+{
+ GList *dir_list = NULL;
+ int ret = APP2EXT_SUCCESS;
+
+ dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ tet_infoline
+ ("Unable to populate dirlist");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ ret = handle->interface.pre_upgrade("com.samsung.calculator", dir_list, 10);
+ if (ret != APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_pre_upgrade() failed in positive test case");
+ handle->interface.post_upgrade("com.samsung.calculator", 2);
+ tet_result(TET_FAIL);
+ return;
+ }
+ handle->interface.post_upgrade("com.samsung.calculator", 1);
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Positive test case of app2ext_pre_upgrade()
+ */
+static void utc_ApplicationFW_app2ext_pre_upgrade_func_02(void)
+{
+ GList *dir_list = NULL;
+ int ret = APP2EXT_SUCCESS;
+
+ dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ tet_infoline
+ ("Unable to populate dirlist");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ ret = handle->interface.pre_upgrade("com.samsung.calculator", dir_list, 15);
+ if (ret != APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_pre_upgrade() failed in positive test case");
+ handle->interface.post_upgrade("com.samsung.calculator", 2);
+ tet_result(TET_FAIL);
+ return;
+ }
+ handle->interface.post_upgrade("com.samsung.calculator", 1);
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_pre_upgrade()
+ */
+static void utc_ApplicationFW_app2ext_pre_upgrade_func_03(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ ret = handle->interface.pre_upgrade("com.samsung.calculator", NULL, 10);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_pre_upgrade() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_pre_upgrade()
+ */
+static void utc_ApplicationFW_app2ext_pre_upgrade_func_04(void)
+{
+ GList *dir_list = NULL;
+ int ret = APP2EXT_SUCCESS;
+
+ dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ tet_infoline
+ ("Unable to populate dirlist");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ ret = handle->interface.pre_upgrade(NULL, dir_list, 10);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_pre_upgrade() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of app2ext_pre_upgrade()
+ */
+static void utc_ApplicationFW_app2ext_pre_upgrade_func_05(void)
+{
+ GList *dir_list = NULL;
+ int ret = APP2EXT_SUCCESS;
+
+ dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ tet_infoline
+ ("Unable to populate dirlist");
+ tet_result(TET_UNINITIATED);
+ return;
+ }
+ ret = handle->interface.pre_upgrade("com.samsung.calculator", dir_list, 0);
+ if (ret == APP2EXT_SUCCESS) {
+ tet_infoline
+ ("app2ext_pre_upgrade() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
--- /dev/null
+#include <tet_api.h>
+#include "pkgname.h"
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+static void utc_@MODULE@_@API@_func_01(void);
+static void utc_@MODULE@_@API@_func_02(void);
+
+enum {
+ POSITIVE_TC_IDX = 0x01,
+ NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+ { utc_@MODULE@_@API@_func_01, POSITIVE_TC_IDX },
+ { utc_@MODULE@_@API@_func_02, NEGATIVE_TC_IDX },
+};
+
+static int pid;
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of @API@()
+ */
+static void utc_@MODULE@_@API@_func_01(void)
+{
+ int r = 0;
+ char buf[MAX_LOCAL_BUFSZ];
+
+ r = @API@(...);
+
+ if (r<0) {
+ tet_infoline("@API@() failed in positive test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of ug_init @API@()
+ */
+static void utc_@MODULE@_@API@_func_02(void)
+{
+ int r = 0;
+ char buf[MAX_LOCAL_BUFSZ];
+
+ r = @API@(...);
+
+ if (r>=0) {
+ tet_infoline("@API@() failed in negative test case");
+ tet_result(TET_FAIL);
+ return;
+ }
+ tet_result(TET_PASS);
+}
--- /dev/null
+<manifest>
+ <define>
+ <domain name="app2sd"/>
+ </define>
+ <request>
+ <domain name="app2sd"/>
+ </request>
+ <assign>
+ <filesystem path="/usr/lib/libapp2ext.so.0" label="_"/>
+ <filesystem path="/usr/lib/libapp2ext.so.0.4.2" label="_"/>
+ <filesystem path="/usr/lib/libapp2sd.so" label="_"/>
+ <filesystem path="/usr/lib/libapp2sd.so.0" label="_"/>
+ <filesystem path="/usr/lib/libapp2sd.so.0.4.2" label="_"/>
+ </assign>
+</manifest>
--- /dev/null
+<manifest>
+ <define>
+ <domain name="app2sd"/>
+ </define>
+ <request>
+ <domain name="app2sd"/>
+ </request>
+ <assign>
+ <filesystem path="@LIB_INSTALL_DIR@/libapp2ext.so.0" label="_"/>
+ <filesystem path="@LIB_INSTALL_DIR@/libapp2ext.so.0.4.2" label="_"/>
+ <filesystem path="@LIB_INSTALL_DIR@/libapp2sd.so" label="_"/>
+ <filesystem path="@LIB_INSTALL_DIR@/libapp2sd.so.0" label="_"/>
+ <filesystem path="@LIB_INSTALL_DIR@/libapp2sd.so.0.4.2" label="_"/>
+ </assign>
+</manifest>
--- /dev/null
+# Package information for app2sd
+prefix=/usr
+exec_prefix=${prefix}
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDE_INSTALL_DIR@
+
+Name: app2sd
+Description: The app2sd Library
+Version: 1.1.0
+Requires: vconf dlog
+Cflags: -I${includedir}
+Libs: -L${libdir} -lapp2sd -lapp2ext
--- /dev/null
+@PREFIX@/include/app2sd_interface.h
+@PREFIX@/lib/pkgconfig/*.pc
--- /dev/null
+@PREFIX@/lib/*.so*
--- /dev/null
+app2sd (0.2.1) unstable; urgency=low
+
+ * Initial release
+ * Git: slp/pkgs/a/app2sd
+ * Tag: app2sd_0.2.1
+
+ -- Jaeho Lee <jaeho81.lee@samsung.com> Thu, 24 May 2012 12:04:51 +0530
+
--- /dev/null
+Source: app2sd
+Section: devel
+Priority: extra
+Maintainer: Garima Shrivastava <garima.s@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+Build-Depends: debhelper (>= 5),libssl-dev, libslp-setting-dev, libslp-db-util-dev
+Standards-Version: 3.7.2
+
+Package: app2sd
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: <App2sd is a utility for enabling installation of applications to sd card and also to move to and from sd card.>
+
+Package: app2sd-dev
+Architecture: any
+Depends: app2sd (= ${Source-Version})
+Description: App2sd dev package
+
+Package: app2sd-doc
+Architecture: all
+Description: <App2sd is a utility for enabling installation of applications to sd card and also to move to and from sd card.>
+
+Package: app2sd-dbg
+Section: debug
+Architecture: any
+Depends: app2sd (= ${Source-Version})
+Description: App2sd dbg package
+
--- /dev/null
+/*
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
--- /dev/null
+usr/bin
+usr/sbin
--- /dev/null
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
+DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_GNU_OS)
+
+CFLAGS ?= -Wall -g
+LDFLAGS ?=
+PREFIX ?= /usr
+DATADIR ?= /opt
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
+endif
+
+# architecture is not arm
+ifneq (, $(findstring arm, $(DEB_HOST_ARCH)))
+ # do something here
+else
+ # do something here for arm
+endif
+
+CFLAGS += -fvisibility=hidden -fPIC
+LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed
+
+CMAKE_TMP_DIR = $(CURDIR)/cmake_tmp
+
+config.status:
+
+configure: configure-stamp
+
+configure-stamp:
+ dh_testdir
+ mkdir -p $(CMAKE_TMP_DIR);
+ export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):$(CMAKE_TMP_DIR) && cd $(CMAKE_TMP_DIR); CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" cmake .. -DCMAKE_INSTALL_PREFIX=$(PREFIX)
+ touch configure-stamp
+
+build: build-stamp
+
+build-stamp: configure-stamp
+ dh_testdir
+ # Add here commands to compile the package.
+ cd $(CMAKE_TMP_DIR) && $(MAKE) all
+
+ for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+ cat $$f > $${f%.in}; \
+ sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \
+ sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \
+ done
+
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f *-stamp
+
+ rm -rf $(CMAKE_TMP_DIR)
+
+ for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+ rm -f $${f%.in}; \
+ done
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/ncurses.
+ cd $(CMAKE_TMP_DIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs
+# dh_installdocs
+ dh_installexamples
+ dh_install --list-missing --sourcedir=debian/tmp
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_python
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+ dh_strip --dbg-package=app2sd-dbg
+ dh_compress
+ dh_fixperms
+# dh_perl
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ *
+ * @ingroup SLP_PG
+ * @defgroup app2ext_PG App2Ext
+ * @{
+
+<h1 class="pg">Introduction</h1>
+App2Ext is a feature that enables package installers to install applications on external storage like SD card, Micro USB flash drive or Cloud.
+It also provides option to move installed applications from external memory to internal memory and vice versa.
+
+<h1 class="pg">App2Ext process view</h1>
+\image html app2ext_diag.png "Picture 1. App2Ext Process View Diagram"
+\image rtf app2ext_diag.png "Picture 1. App2Ext Process View Diagram"
+
+<h1 class="pg">Installation to SD Card</h1>
+Package installer should call the App2Ext's Init API to initialize SD plug-in. Once the plug-in initialization is done App2Ext returns a storage handle to the Package installer. Package installer should then call the pre-install setup API with respect to the storage handle which will be mapped to app2sd's pre-install API. The App2Ext Pre-install API performs the setup required for the installation based on the external storage type.
+After pre-install setup is done Package installer can proceed with the installation of the application. When package installation is completed by the package installer, post-install setup API should be called. This API removes the setup created for installation during pre-install API.
+
+Refer to Picture 2. for flow diagram.
+
+<h1 class="pg">Installation Setup Flow for App2SD plug-in</h1>
+\image html app2ext_install_diag.png "Picture 2. Installation on SD card Flow Diagram"
+\image rtf app2ext_install_diag.png "Picture 2. Installation on SD card Flow Diagram"
+
+<h1 class="pg">Un-installation from SD Card</h1>
+Package installer should call the App2Ext's Init API to initialize SD plug-in. Once the plug-in initialization is done App2Ext returns a storage handle to the Package installer. Package installer should then call the pre-uninstall setup API with respect to the storage handle which will be mapped to app2sd's pre-uninstall API. Pre-uninstall API performs the setup required for the package un-installation based on the external storage type.
+After pre-uninstall setup is done Package installer can proceed with un-installation of the package. When package un-installation is completed by the package installer, post-uninstall setup API should be called. This API removes the setup created for un-installation during pre-uninstall API.
+
+Refer to Picture 3. for flow diagram.
+
+<h1 class="pg">Un-installation Setup Flow for App2SD plug-in</h1>
+\image html app2ext_uninstall_diag.png "Picture 3. Un-installation from SD card Flow Diagram"
+\image rtf app2ext_uninstall_diag.png "Picture 3. Un-installation from SD card Flow Diagram"
+
+
+<h1 class="pg">API list and description</h1>
+<ul>
+ <li>app2ext_init() : Initialize plug-in based on storage type </li>
+ <li>app2ext_deinit() : De-initialize plug-in</li>
+ <li>app2ext_get_app_location() : Returns application current location</li>
+</ul>
+
+ * @}
+ */
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __APP2EXT_INTERFACE_H__
+#define __APP2EXT_INTERFACE_H__
+
+/**
+ * @file app2ext_interface.h
+ * @version 0.5
+ * @brief This file declares API of app2ext library
+ */
+/**
+ * @addtogroup APPLICATION_FRAMEWORK
+ * @{
+ *
+ * @defgroup app2ext
+ * @version 0.5
+ *
+ * @section Header to use them:
+ * @code
+ * #include <app2ext_interface.h>
+ * @endcode
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#include <dlog/dlog.h>
+#include <glib.h>
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "APP2EXT"
+
+#ifdef _DEBUG_MODE_
+#define app2ext_print(fmt, arg...) LOGD(fmt,##arg)
+#else
+#define app2ext_print(FMT, ARG...) SLOGD(FMT,##ARG);
+#endif
+
+#define APP2EXT_SUCCESS 0
+#define MMC_PATH "/opt/storage/sdcard"
+#define APP2SD_PATH MMC_PATH"/app2sd/"
+#define APP_INSTALLATION_PATH "/opt/usr/apps/"
+
+/**
+ * Enum for application installation location
+ */
+typedef enum app2ext_install_location_t {
+ APP2EXT_INTERNAL_MEM = 0,
+ APP2EXT_SD_CARD,
+ APP2EXT_MICRO_USB,
+ APP2EXT_CLOUD,
+ APP2EXT_NOT_INSTALLED
+} app2ext_install_location;
+
+/**
+ * Enum for installation/upgrade status[success/failure]
+ */
+typedef enum app2ext_status_t {
+ APP2EXT_STATUS_FAILED = 1,
+ APP2EXT_STATUS_SUCCESS
+} app2ext_status;
+
+/**
+ * Enum for directory type
+ */
+typedef enum app2ext_dir_type_t {
+ APP2EXT_DIR_RO,
+ APP2EXT_DIR_RW,
+} app2ext_dir_type;
+
+/**
+ * Enum for move command
+ * @see app2sd_move_installed_app()
+ */
+typedef enum app2ext_move_type_t {
+ APP2EXT_MOVE_TO_EXT = 1,
+ APP2EXT_MOVE_TO_PHONE
+} app2ext_move_type;
+
+/**
+ * Enum for error codes
+ */
+typedef enum app2ext_error_t {
+ APP2EXT_ERROR_INVALID_ARGUMENTS = 2,
+ APP2EXT_ERROR_MOVE,
+ APP2EXT_ERROR_PRE_UNINSTALL,
+ APP2EXT_ERROR_MMC_STATUS,
+ APP2EXT_ERROR_DB_INITIALIZE,
+ APP2EXT_ERROR_SQLITE_REGISTRY,
+ APP2EXT_ERROR_PASSWD_GENERATION,
+ APP2EXT_ERROR_MMC_INFORMATION,
+ APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY,
+ APP2EXT_ERROR_DELETE_DIRECTORY,
+ APP2EXT_ERROR_CREATE_SYMLINK,
+ APP2EXT_ERROR_CREATE_DIRECTORY,
+ APP2EXT_ERROR_DELETE_LINK_FILE,
+ APP2EXT_ERROR_PKG_EXISTS,
+ APP2EXT_ERROR_ACCESS_FILE,
+ APP2EXT_ERROR_OPEN_DIR,
+ APP2EXT_ERROR_ALREADY_FILE_PRESENT,
+ APP2EXT_ERROR_FILE_ABSENT,
+ APP2EXT_ERROR_STRCMP_FAILED,
+ APP2EXT_ERROR_INVALID_PACKAGE,
+ APP2EXT_ERROR_CREATE_DIR_ENTRY,
+ APP2EXT_ERROR_PASSWORD_GENERATION,
+ APP2EXT_ERROR_COPY_DIRECTORY,
+ APP2EXT_ERROR_INVALID_CASE,
+ APP2EXT_ERROR_SYMLINK_ALREADY_EXISTS,
+ APP2EXT_ERROR_APPEND_HASH_TO_FILE,
+ APP2EXT_ERROR_CREATE_DEVICE,
+ APP2EXT_ERROR_DO_LOSETUP,
+ APP2EXT_ERROR_CREATE_FS,
+ APP2EXT_ERROR_MOUNT_PATH,
+ APP2EXT_ERROR_CLEANUP,
+ APP2EXT_ERROR_MOUNT,
+ APP2EXT_ERROR_REMOUNT,
+ APP2EXT_ERROR_PIPE_CREATION,
+ APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE,
+ APP2EXT_ERROR_VCONF_REGISTRY,
+ APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE,
+ APP2EXT_ERROR_UNMOUNT,
+ APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE,
+ APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE,
+ APP2EXT_ERROR_ALREADY_MOUNTED,
+ APP2EXT_ERROR_PLUGIN_INIT_FAILED,
+ APP2EXT_ERROR_PLUGIN_DEINIT_FAILED
+} app2ext_error;
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called before application is to be installed.
+ *
+ * @param[in] appname application package name which is to be installed
+ * @param[in] dir_list directory structure of the application
+ * This should be polulated by the package manager
+ * before calling pre_install and should be freed after
+ * pre_install returns.
+ * Each node of dir_list is of type app2ext_dir_details
+ * which has members Name(dirname) and Type (RO/RW)
+ * For eg for rpm the dir_list should be populated with
+ * nodes like : (lib, APP2EXT_DIR_RO), (res, APP2EXT_DIR_RO),
+ (bin, APP2EXT_DIR_RO), (data, APP2EXT_DIR_RW)
+ * @param[in] size Size of the application
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_pre_install)(const char *appname, GList* dir_list, int size);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called after application installation.
+ *
+ * @param[in] appname application package name which is to be installed
+ * @param[in] install_status Installation status (Success/Failure)
+ * [ Enum :APP2EXT_STATUS_SUCCESS,
+ * APP2EXT_STATUS_FAILED]
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_post_install)(const char *appname, app2ext_status install_status);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called before application upgrade.
+ *
+ * @param[in] appname application package name which is to be upgraded
+ * @param[in] dir_list directory structure of the application
+ * This should be polulated by the package manager
+ * before calling pre_upgrade and should be freed after
+ * pre_upgrade returns.
+ * Each node of dir_list is of type app2ext_dir_details
+ * which has members Name(dirname) and Type (RO/RW)
+ * For eg for rpm the dir_list should be populated with
+ * nodes like : (lib, APP2EXT_DIR_RO), (res, APP2EXT_DIR_RO),
+ (bin, APP2EXT_DIR_RO), (data, APP2EXT_DIR_RW)
+ * @param[in] size Size of the application
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_pre_upgrade)(const char *appname, GList* dir_list, int size);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called before application upgradation.
+ *
+ * @param[in] appname application package name which is to be upgraded
+ * @param[in] upgrade_status Upgrade status (Success/Failure)
+ * [ Enum :APP2EXT_STATUS_SUCCESS,
+ * APP2EXT_STATUS_FAILED]
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_post_upgrade)(const char *appname, app2ext_status upgrade_status);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called before application uninstallation.
+ *
+ * @param[in] appname application package name which is to be uninstalled
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_pre_uninstall)(const char *appname);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called after application uninstallation.
+ *
+ * @param[in] appname application package name which is to be uninstalled
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_post_uninstall)(const char *appname);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called when application is to be moved from extrenal memory
+ *to internal memory or vice versa.
+ *
+ * @param[in] appname application package name which is to be moved
+ * @param[in] dir_list directory structure of the application
+ * This should be polulated by the package manager
+ * before calling move and should be freed after
+ * move returns.
+ * Each node of dir_list is of type app2ext_dir_details
+ * which has members Name(dirname) and Type (RO/RW)
+ * For eg for rpm the dir_list should be populated with
+ * nodes like : (lib, APP2EXT_DIR_RO), (res, APP2EXT_DIR_RO),
+ (bin, APP2EXT_DIR_RO), (data, APP2EXT_DIR_RW)
+ * @param[in] move_type move type
+ * [Enum: APP2EXT_MOVE_TO_EXT, APP2EXT_MOVE_TO_PHONE]
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_move)(const char *appname, GList* dir_list, app2ext_move_type move_type);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called to enable application before application launch.
+ *
+ * @param[in] appname application package name which is to be enabled
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_enable)(const char *appname);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called to disable application before application exit.
+ *
+ * @param[in] appname application package name which is to be disabled
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_disable)(const char *appname);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called after application uninstallation.
+ *
+ * @param[in] pkgid application package name which is to be uninstalled
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_force_clean)(const char *pkgid);
+
+/**
+ * This structure defines the app2ext interfaces. Plugins have to implement these functions
+ */
+typedef struct app2ext_interface_t{
+ app2ext_pre_install pre_install;
+ app2ext_post_install post_install;
+ app2ext_pre_upgrade pre_upgrade;
+ app2ext_post_upgrade post_upgrade;
+ app2ext_pre_uninstall pre_uninstall;
+ app2ext_post_uninstall post_uninstall;
+ app2ext_move move;
+ app2ext_force_clean force_clean;
+ app2ext_enable enable;
+ app2ext_disable disable;
+} app2ext_interface;
+
+/**
+ * This structure defines app2ext handle .Each storage type maps to a different plugin
+ * type : storage type
+ * plugin_handle : plugin handle
+ */
+typedef struct {
+ app2ext_install_location type;
+ void *plugin_handle;
+ app2ext_interface interface;
+} app2ext_handle;
+
+/**
+ * This structure defines directory details
+ * name : directory name
+ * type : permission (rw/ro)
+ */
+typedef struct {
+ char * name;
+ app2ext_dir_type type;
+} app2ext_dir_details;
+
+/**
+ * @brief : This API initializes the appropriate plugin based on storage type.
+ * It should be called before installation/uninstallation/upgrade
+ * @param[in] storage_type Location where package should be installed
+ * [Ex: SD card, MicroUSB, Cloud]
+ * @return app2ext_handle pointer if success, NULL if fail
+ *
+ @code
+ #include <app2ext_interface.h>
+ app2ext_handle *handle = NULL;
+ GLIst *dir_list = NULL;
+ handle = app2ext_init(APP2EXT_SD_CARD); //Initializes SD card plug-in
+ if(handle)
+ {
+ printf("\n SUCCESS");
+ // Perform package install/uninstall/upgrade/move here
+ // Packge install example
+ // Package manager should polulate dir_list with directory structure information of the package
+ ret = handle->interface.pre_install("com.samsung.calculator", dir_list, 20);
+ if (ret) {
+ printf("\n TC : pre app install API fail. Reason %s", error_list[ret]);
+ return -1;
+ }
+
+ // Package manager installs the package
+
+ ret = handle->interface.post_install("com.samsung.calculator", APP2EXT_STATUS_SUCCESS);
+ if (ret) {
+ printf("\n TC : post app install API fail Reason %s", error_list[ret]);
+
+ return -1;
+ }
+ // Package manager should free dir_list
+ return;
+ } else
+ printf("\n FAILURE");
+ @endcode
+ */
+API app2ext_handle *app2ext_init(int storage_type);
+
+/**
+ * @brief : This API deinitializes the plugin
+ * This should be called when use of the plugin is completed
+ * @param[in] handle pointer to app2ext_handle which is to be deinitialized
+ * @pre Initialization is done for the storage handle
+ * @return 0 if success, error code(>0) if fail
+ *
+ @code
+ #include <app2ext_interface.h>
+ app2ext_handle *handle = NULL;
+ handle = app2ext_init(APP2EXT_SD_CARD); //Initializes SD card plug-in
+ int ret = -1;
+ ret = app2ext_deinit(handle); // De-initializes the SD plugin
+ if(!ret)
+ {
+ printf("\n SUCCESS");
+ }
+ else
+ printf("\n FAILURE");
+ @endcode
+ */
+API int app2ext_deinit(app2ext_handle *handle);
+
+/**
+ * @brief : This API returns the application location
+ * by refering to package manager DB
+ * This should be called to know location of an application
+ * @param[in] appname name of the application
+ * @return APP2EXT_SD_CARD if app is in SD card,
+ * APP2EXT_INTERNAL_MEM if app is in internal memory
+ * error code(>0) if fail
+ *@remarks see app2ext_install_location for more details
+ @code
+ #include <app2ext_interface.h>
+int ret = -1;
+
+ret = app2ext_get_app_location("com.samsung.calculator");
+if (ret == APP2EXT_SD_CARD) {
+ printf("\n app is in sd card ");
+} else if (ret == APP2EXT_INTERNAL_MEM) {
+ printf("\n app is in internal memory ");
+} else {
+ printf("\napp is not installed");
+}
+ @endcode
+ */
+API int app2ext_get_app_location(const char *appname);
+
+/**
+ * @brief : This API enable the package which is located in external memory
+ * @param[in] pkgid package id
+ * @return error < 0 if pkg enable fail ,
+ @code
+ #include <app2ext_interface.h>
+int ret = -1;
+
+ret = app2ext_enable_external_pkg("com.samsung.calculator");
+if (ret < 0) {
+ printf("\n pkg is not enabled ");
+} else {
+ printf("\n pkg is enabled ");
+}
+ @endcode
+ */
+API int app2ext_enable_external_pkg(const char *pkgid);
+
+/**
+ * @brief : This API disable the package which is located in external memory
+ * @param[in] pkgid package id
+ * @return error < 0 if pkg enable fail ,
+ @code
+ #include <app2ext_interface.h>
+int ret = -1;
+
+ret = app2ext_disable_external_pkg("com.samsung.calculator");
+if (ret < 0) {
+ printf("\n pkg is not enabled ");
+} else {
+ printf("\n pkg is enabled ");
+}
+ @endcode
+ */
+API int app2ext_disable_external_pkg(const char *pkgid);
+
+/**
+ * @brief : This API enable the directory which has package that is located in external memory
+ * @return error < 0 if pkg enable fail ,
+ @code
+ #include <app2ext_interface.h>
+int ret = -1;
+
+ret = app2ext_enable_external_dir();
+if (ret < 0) {
+ printf("\n app2sd dir is not enabled ");
+} else {
+ printf("\n app2sd dir is enabled ");
+}
+ @endcode
+ */
+API int app2ext_enable_external_dir(void);
+
+/**
+ * @brief : This API disable the directory which has package that is located in external memory
+ * @return error < 0 if pkg enable fail ,
+ @code
+ #include <app2ext_interface.h>
+int ret = -1;
+
+ret = app2ext_enable_external_dir();
+if (ret < 0) {
+ printf("\n app2sd dir is not enabled ");
+} else {
+ printf("\n app2sd dir is enabled ");
+}
+ @endcode
+ */
+API int app2ext_disable_external_dir(void);
+
+/**
+ * @brief : This API clean the directory and symbolic link which are made by app2ext
+ * @return error < 0 if pkg enable fail ,
+ @code
+ #include <app2ext_interface.h>
+int ret = -1;
+
+ret = app2ext_force_clean_pkg("docomo6002");
+if (ret < 0) {
+ printf("\n force_clean fail ");
+} else {
+ printf("\n force_clean success");
+}
+ @endcode
+ */
+API int app2ext_force_clean_pkg(const char *pkgid);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--- /dev/null
+Name: app2sd
+Summary: Application installation on external memory
+Version: 0.5.36
+Release: 1
+Group: Application Framework/Application Installer
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+
+BuildRequires: pkgconfig(libssl)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(openssl)
+BuildRequires: pkgconfig(db-util)
+BuildRequires: pkgconfig(pkgmgr-info)
+BuildRequires: pkgconfig(libprivilege-control)
+BuildRequires: cmake
+
+%description
+Tizen application installation on external memory
+
+%package devel
+Summary: Application install on external memory (devel)
+Group: Development/Libraries
+Requires: app2sd = %{version}-%{release}
+
+%description devel
+Tizen application installation on external memory (devel)
+
+%prep
+%setup -q
+
+%build
+
+%if 0%{?tizen_build_binary_release_type_eng}
+export CFLAGS="$CFLAGS -DTIZEN_ENGINEER_MODE"
+export CXXFLAGS="$CXXFLAGS ?DTIZEN_ENGINEER_MODE"
+export FFLAGS="$FFLAGS -DTIZEN_ENGINEER_MODE"
+%endif
+
+%cmake .
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE %{buildroot}/usr/share/license/%{name}
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest app2sd.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libapp2ext.so.*
+%{_libdir}/libapp2sd.so*
+/usr/share/license/%{name}
+
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/app2ext_interface.h
+%{_libdir}/pkgconfig/app2sd.pc
+%{_libdir}/libapp2sd.so
+%{_libdir}/libapp2ext.so
+
+
+
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(app2sd C)
+
+### Required packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED libssl dlog openssl db-util pkgmgr-info vconf libprivilege-control)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+pkg_check_modules(libpkgs REQUIRED libssl dlog openssl db-util pkgmgr-info vconf libprivilege-control)
+
+FOREACH(flag ${libpkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+### Local include directories
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc ${CMAKE_SOURCE_DIR}/src)
+
+## build app2sd library
+SET(app2sd_dir "${CMAKE_SOURCE_DIR}/plugin/app2sd")
+SET(app2sd_inc_dir "${app2sd_dir}/inc")
+SET(app2sd_src_dir "${app2sd_dir}/src")
+SET(APP2SD "app2sd")
+SET(libapp2sd_SOURCES ${app2sd_src_dir}/app2sd_internals.c ${app2sd_src_dir}/app2sd_interface.c ${app2sd_src_dir}/app2sd_internals_registry.c ${app2sd_src_dir}/app2sd_internals_utils.c)
+SET(libapp2sd_LDFLAGS " -L${LIB_INSTALL_DIR} -lcrypto -module -avoid-version ")
+SET(libapp2sd_CFLAGS " ${CFLAGS} -fPIC -I${app2sd_inc_dir} ")
+
+ADD_LIBRARY(${APP2SD} SHARED ${libapp2sd_SOURCES})
+SET_TARGET_PROPERTIES(${APP2SD} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${APP2SD} PROPERTIES VERSION ${VERSION})
+SET_TARGET_PROPERTIES(${APP2SD} PROPERTIES COMPILE_FLAGS "${libapp2sd_CFLAGS}")
+TARGET_LINK_LIBRARIES(${APP2SD} ${libpkgs_LDFLAGS})
+
+SET(CMAKE_INSTALL_PREFIX "/usr")
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+
+INSTALL(TARGETS ${APP2SD} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+
+
--- /dev/null
+/*
+ * app2sd
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ * Jyotsna Dhumale <jyotsna.a@samsung.com>
+ * Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ *
+ * @ingroup SLP_PG
+ * @defgroup app2sd_PG App2sd
+ * @{
+
+<h1 class="pg">Introduction</h1>
+App2sd is a feature that enables package installers to install applications on sdcard.
+It also provides API to move installed applications from sd card to internal memory and vice versa.
+App2sd provides an API for validating the integrity of the package before launching by the launchpad.
+
+<h1 class="pg">App2sd process view</h1>
+\image html app2sd_diag.png "Picture 1. Process View Diagram"
+\image rtf app2sd_diag.png "Picture 1. Process View Diagram"
+
+<h1 class="pg">Installation to SD Card</h1>
+Package installer should call the App2sd pre-install setup API before installation.
+This API creates directory structure in SD card.
+Refer to Picture 2. for flow diagram.
+
+<h1 class="pg">App2sd Installation Setup Flow</h1>
+\image html app2sd_install_diag.png "Picture 2. Installation Flow Diagram"
+\image rtf app2sd_install_diag.png "Picture 2. Installation Flow Diagram"
+
+<h1 class="pg">Uninstallation to SD Card</h1>
+Package installer should call the App2sd pre-uninstall setup API before uninstallation.
+Once the uninstallation is done by the package installer
+then App2sd post-uninstall setup API should be called.
+This API will clean up the directory structure and remove password from sqlite db.
+Refer to Picture 3. for flow diagram.
+<h1 class="pg">App2sd Uninstallation Setup Flow</h1>
+\image html app2sd_uninstall_diag.png "Picture 3. Uninstallation Flow Diagram"
+\image rtf app2sd_uninstall_diag.png "Picture 3. Uninstallation Flow Diagram"
+
+<h1 class="pg">API list and description</h1>
+<ul>
+ <li>app2sd_pre_app_install() : Pre app installation setup.</li>
+ <li>app2sd_post_app_install() : Post app installation setup.</li>
+ <li>app2sd_pre_app_upgrade() : Pre app upgrade setup.</li>
+ <li>app2sd_post_app_upgrade() : Post app upgarde setup.</li>
+ <li>app2sd_pre_app_uninstall() : Pre app uninstall setup.</li>
+ <li>app2sd_post_app_uninstall() : Post app uninstall setup.</li>
+ <li>app2sd_move_installed_app() : Move installed application to/from sdcard</li>
+ <li>app2sd_get_app_install_location() : Get application installation location[external\internal memory].</li>
+ <li>app2sd_on_demand_setup_init() : Enables the application installed in sdcard.</li>
+ <li>app2sd_on_demand_setup_exit() : Disables the application installed in sdcard.</li>
+ <li></li>
+</ul>
+
+ * @}
+ */
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ * Jyotsna Dhumale <jyotsna.a@samsung.com>
+ * Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __APPTOSD_INTERFACE_H__
+#define __APPTOSD_INTERFACE_H__
+
+/**
+ * @file app2sd_interface.h
+ * @version 0.2
+ * @brief This file declares API of app2sd library
+ */
+/**
+ * @addtogroup APPLICATION_FRAMEWORK
+ * @{
+ *
+ * @defgroup app2sd
+ * @version 0.2
+ *
+ * @section Header to use them:
+ * @code
+ * #include <app2sd_interface.h>
+ * @endcode
+ *
+ * @addtogroup app2sd
+ * @{
+ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <app2ext_interface.h>
+
+
+ /**
+ * @brief : This API prepares the setup for installation in SD card.
+ * It should be called before actual installation is done.
+ * @pre vfat type sd card must be present.
+ * @post Installation is done by package installer.
+ Encryption password is saved in db /opt/dbspace/.app2sd.db
+ * @param[in] appname application package name
+ * [Ex: com.samsung.calculator]
+ *This entry is parsed from application package control/manifest file.
+ * @param[in] dir_list directory structure of the application
+ * @param[in] size size of memory required by application(in MB).
+ *This entry is parsed from application package control/manifest file.
+ * @return 0 if success, error code(>0) if fail
+ * @remark None.
+ *
+ *
+ @code
+ #include <app2sd_interface.h>
+ int ret = -1;
+ GList* dir_list = NULL;
+ // Package manager populates dir_list with directory structure information
+ ret= app2sd_pre_app_install
+ ("com.samsung.calculotor", dir_list, 10);
+ if(!ret)
+ {
+ printf("\n SUCCESS");
+ // Package installer performs installation
+ // app2sd_post_app_install() API should be called
+ return;
+ }
+ else
+ printf("\n FAILURE");
+ @endcode
+ */
+ API int app2sd_pre_app_install(const char *appname,
+ GList* dir_list, int size);
+
+ /**
+ * @brief : This API does post installation operations after
+ * the installation in SD card
+ * @param[in] appname application package name
+ * [Ex: com.samsung.calculator]
+ * @param[in] install_status Status of installation of package
+ *[ enum app2ext_status].If package installation failed then
+ * install_status= APP2EXT_STATUS_FAILURE else if installation
+ * was successful then install_status = APP2EXT_ISTATUS_SUCCESS.
+ * @pre Installation should be done by package installer.
+ * @return 0 if success, error code(>0) if fail
+ * @remark @see enum app2sd_install_status
+ *
+ *
+ @code
+ #include <app2sd_interface.h>
+ int ret = -1;
+ ret= app2sd_pre_app_install
+ ("com.samsung.calculotor", APP2EXT_NATIVE_APP, 10);
+ if(!ret)
+ {
+ printf("\n SUCCESS");
+ // Package installer performs installation
+ //Package was installed successfully.
+ if(package_installation _success)
+ {
+ ret = app2sd_post_app_install
+ ("com.samsung.calculator",APP2EXT_STATUS_SUCCESS);
+ if(!ret)
+ printf("\n SUCCESS");
+ else
+ printf("\n FAILURE");
+ return;
+ }
+ else
+ {
+ //Package installation failed
+ ret = app2sd_post_app_install
+ ("com.samsung.calculator",APP2EXT_STATUS_FAILURE);
+ if(!ret)
+ printf("\n SUCCESS");
+ else
+ printf("\n FAILURE");
+ return;
+ }
+ }
+ else
+ printf("\n FAILURE");
+ @endcode
+ */
+ API int app2sd_post_app_install(const char *appname,
+ app2ext_status install_status);
+
+ /**
+ * @brief : This API prepares the setup for upgradation of
+ * application package
+ * @pre vfat type sd card must be present.
+ * @post Upgradation is done by package installer.
+ * @param[in] appname application package name
+ * [Ex: com.samsung.calculator]
+ * @param[in] dir_list directory structure of the application
+ * @param[in] size size of memory required by application(in MB).
+ *This entry is parsed from application package control/manifest file.
+ * @return 0 if success, error code(>0) if fail
+ * @remark None.
+ *
+ *
+ @code
+ #include <app2sd_interface.h>
+ int ret = -1;
+ GList* dir_list = NULL;
+ // Package manager populates dir_list with directory structure information
+ ret= app2sd_pre_app_upgrade
+ ("com.samsung.calculator", dir_list, 10);
+ if(!ret)
+ {
+ printf("\n SUCCESS");
+ // Package installer performs upgradation
+ // app2sd_post_app_upgrade() API should be called
+ return;
+ }
+ else
+ printf("\n FAILURE");
+ @endcode
+ */
+ API int app2sd_pre_app_upgrade(const char *appname,
+ GList* dir_list, int size);
+
+ /**
+ * @brief : This API does post upgradation operations after
+ * the installation in SD card
+ * @param[in] appname application package name
+ * [Ex: com.samsung.calculator]
+ * @param[in] install_status Status of installation of package
+ *[ enum app2extl_status].If package upgradation failed then
+ * upgrade_status= APP2EXT_STATUS_FAILURE else if upgradation
+ * was successful then upgrade_status = APP2EXT_STATUS_SUCCESS.
+ * @pre Upgradation should be done by package installer.
+ * @return 0 if success, error code(>0) if fail
+ * @remark @see enum app2ext_status
+ *
+ *
+ @code
+ #include <app2sd_interface.h>
+ int ret = -1;
+ ret= app2sd_pre_app_upgrade
+ ("com.samsung.calculator", APP2EXT_NATIVE_APP, 10);
+ if(!ret)
+ {
+ printf("\n SUCCESS");
+ // Package installer performs upgradation
+ //Package was upgraded successfully.
+ if(package_upgradation _success)
+ {
+ ret = app2sd_post_app_upgrade
+ ("com.samsung.calculator",APP2EXT_STATUS_SUCCESS);
+ if(!ret)
+ printf("\n SUCCESS");
+ else
+ printf("\n FAILURE");
+ return;
+ }
+ else
+ {
+ //Package upgradation failed
+ ret = app2sd_post_app_upgrade
+ ("com.samsung.calculator",APP2EXT_STATUS_FAILURE);
+ if(!ret)
+ printf("\n SUCCESS");
+ else
+ printf("\n FAILURE");
+ return;
+ }
+ }
+ else
+ printf("\n FAILURE");
+ @endcode
+ */
+ API int app2sd_post_app_upgrade(const char *appname,
+ app2ext_status upgrade_status);
+
+ /**
+ * @brief: This API prepares the setup for uninstallation
+ * @pre Package must be installed in sdcard.
+ * @post Package is uninstalled by the package installer.
+ * @param[in] appname application package name
+ * [Ex: com.samsung.calculator]
+ * @return 0 if success, error code(>0) if fail
+ * @remark None.
+ *
+ *
+ @code
+ #include <app2sd_interface.h>
+ int ret = -1;
+ ret= app2sd_pre_app_uninstall
+ ("com.samsung.calculator");
+ if(!ret)
+ {
+ printf("\n SUCCESS");
+ // Package installer performs uninstallation
+ // app2sd_post_app_uninstall() API should be called
+ return;
+ }
+ else
+ printf("\n FAILURE");
+ @endcode
+ */
+ API int app2sd_pre_app_uninstall(const char *appname);
+
+ /**
+ * @brief This API removes the resources created during
+ app2sd setup.It is called after uninstallation.
+ * @pre Package must be uninstalled .
+ * @post Encryption password is removed from sqlite db.
+ * @param[in] appname application package name
+ * [Ex: com.samsung.calculator]
+ * @return 0 if success, error code(>0) if fail
+ * @remark None.
+ *
+ *
+ @code
+ #include <app2sd_interface.h>
+ int ret = -1;
+ ret= app2sd_pre_app_uninstall
+ ("com.samsung.calculator");
+ if(!ret)
+ {
+ printf("\n SUCCESS");
+ // Package installer performs uninstallation
+ ret = app2sd_post_app_uninstall("com.samsung.calculator");
+ if(!ret)
+ printf("\n SUCCESS");
+ else
+ printf("\n FAILURE");
+ return;
+ }
+ else
+ printf("\n FAILURE");
+ @endcode
+ */
+ API int app2sd_post_app_uninstall(const char *appname);
+
+ /**
+ * @brief : This API moves the package from sd card
+ to internal memory and vice versa.
+ * @param[in] pkgid application package id
+ * [Ex: com.samsung.calculator]
+ * @param[in] move_type Move type[enum app2ext_move_type]
+ * [sd card to internal/internal to sd card]
+ * @param[in] dir_list directory structure of the application
+ * @pre Package must be installed and its installation
+ * location should be known.Use app2sd_get_app_install_location()
+ * to get installation location.
+ * @see app2sd_get_app_install_location().
+ * @post Package is moved to new location.
+ * @return 0 if success, error code(>0) if fail
+ * @remark None.
+ *
+ *
+ @code
+ #include <app2sd_interface.h>
+ int ret = -1;
+ GList* dir_list = NULL;
+ // Package manager populates dir_list with directory structure information
+ ret = app2sd_get_app_install_location("com.samsung.calculator");
+ if(ret == APP2SD_INTERNAL_MEM)
+ {
+ ret= app2sd_move_installed_app("com.samsung.calculator",
+ dir_list, APP2EXT_MOVE_TO_EXT);
+ if(!ret)
+ printf("\n SUCCESS");
+ else
+ printf("\n FAILURE");
+ }
+ else if(ret == APP2SD_EXTERNAL_MEM)
+ {
+ ret= app2sd_move_installed_app("com.samsung.calculator",
+ dir_list, APP2SD_MOVE_TO PHONE);
+ if(!ret)
+ printf("\n SUCCESS");
+ else
+ printf("\n FAILURE");
+ }
+ @endcode
+ */
+ API int app2sd_move_installed_app(const char *pkgid,
+ GList* dir_list, app2ext_move_type move_type);
+
+ /**
+ * @brief : This API Enables the application in sd card
+ for use. This API should be called by AUL.
+ * @param[in] pkgid application package id
+ * [Ex: com.samsung.calculator]
+ * @pre Package must be installed
+ * @post application is enabled in SD card.
+ * @return 0 if success, error code(>0) if fail
+ * @remark None.
+ *
+ *
+ @code
+ #include <app2sd_interface.h>
+ int ret = -1;
+ ret= app2sd_on_demand_setup_init("com.samsung.calculator");
+ if(!ret)
+ printf("\n SUCCESS");
+ else
+ printf("\n FAILURE");
+ }
+ @endcode
+ */
+ API int app2sd_on_demand_setup_init(const char *pkgid);
+
+
+ /**
+ * @brief : This API Disables the application in sd card
+ . This API should be called by Launchpad callback which will be registered
+ during app launch for exit action of the application
+ * @param[in] pkgid application package id
+ * [Ex: com.samsung.calculator]
+ * @pre Package must be installed and enabled
+ * and application must be running in SD card
+ * @post application is disabked in SD card.
+ * @return 0 if success, error code(>0) if fail
+ * @remark None.
+ *
+ *
+ @code
+ #include <app2sd_interface.h>
+ int ret = -1;
+ ret= app2sd_on_demand_setup_exit("com.samsung.calculator");
+ if(!ret)
+ printf("\n SUCCESS");
+ else
+ printf("\n FAILURE");
+ }
+ @endcode
+ */
+ API int app2sd_on_demand_setup_exit(const char *pkgid);
+
+ /**
+ * @brief : This is the plug-in load function.
+ The plugin has to bind its functions to function pointers of storage handle
+ * @param[in/out] st_interface Specifies the storage interface.
+ * @return None
+ */
+ API void app2ext_on_load(app2ext_interface *st_interface);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ * Jyotsna Dhumale <jyotsna.a@samsung.com>
+ * Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _APP2SD_INTERNAL_H
+#define _APP2SD_INTERNAL_H
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+
+/*Include Headers*/
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/mount.h>
+#include <app2sd_interface.h>
+
+#define DIR_PERMS (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
+
+#define BUF_SIZE 256
+#define MEM_BUF_SIZE 5 /*Memory buffer size in MB*/
+#define PKG_BUF_SIZE 2 /*Memory buffer size in MB*/
+
+/*Device entry defines*/
+#define DEV_MAJOR 7
+
+#define FS_TYPE "ext4"
+
+typedef enum mount_type_t {
+ MOUNT_TYPE_RD = 0,
+ MOUNT_TYPE_RW,
+ MOUNT_TYPE_RW_NOEXEC,
+ MOUNT_TYPE_RD_REMOUNT,
+ MOUNT_TYPE_RW_REMOUNT
+} mount_type;
+
+typedef enum app2sd_cmd_t {
+ APP2SD_PRE_INSTALL = 1,
+ APP2SD_POST_INSTALL,
+ APP2SD_PRE_UNINSTALL,
+ APP2SD_POST_UNINSTALL,
+ APP2SD_PRE_UPGRADE,
+ APP2SD_POST_UPGRADE,
+ APP2SD_APP_LAUNCH,
+ APP2SD_APP_TERMINATE,
+ APP2SD_MOVE_APP_TO_MMC,
+ APP2SD_MOVE_APP_TO_PHONE
+} app2sd_cmd;
+
+/*This will store password in DB*/
+int _app2sd_set_passwod_in_db(const char *pkgid, const char *password);
+
+/*This will remove password from db*/
+int _app2sd_remove_password_from_db(const char *pkgid);
+
+/*This will fetch password from db*/
+char *_app2sd_get_passowrd_from_db(const char *pkgid);
+
+/*Checks whether mmc is present or not*/
+int _app2sd_check_mmc_status(void);
+
+/*this function is similar to system()*/
+int _xsystem(const char *argv[]);
+
+/*this function will return the free available memory on the SD Card*/
+int _app2sd_get_available_free_memory(const char *sd_path, int *free_mem);
+
+/*Function to move the application from/to SD Card*/
+int _app2sd_move_app(const char *pkgid, app2ext_move_type move_cmd, GList* dir_list);
+
+/*utility to delete the directory*/
+int _app2sd_delete_directory(char *dirname);
+
+/*utility to delete symbolic link*/
+void _app2sd_delete_symlink(const char *dirname);
+
+/*utility to calculate the size of a directory in MB*/
+unsigned long long _app2sd_calculate_dir_size(char *dirname);
+
+/*utility to calculate the size of a file in MB*/
+unsigned long long _app2sd_calculate_file_size(const char *filename);
+
+/*Utility to copy a directory*/
+int _app2sd_copy_dir(const char *src, const char *dest);
+
+/*Utility to rename a directory*/
+int _app2sd_rename_dir(const char *old_name, const char *new_name);
+
+/*Utility to create application directory structure entry as per package type*/
+int _app2sd_create_directory_entry(const char *pkgid, GList* dir_list);
+
+/* Utility to create symlinks */
+int _app2sd_create_symlink(char *pkgid);
+
+/*This function finds the associated device node for the app*/
+char *_app2sd_find_associated_device_node(const char *pkgid);
+
+/*This function does the loopback encryption for app*/
+char *_app2sd_do_loopback_encryption_setup(const char *pkgid);
+
+/*This function detaches the loopback device*/
+char *_app2sd_detach_loop_device(const char *device);
+
+/*This function finds loopback device associated with the app*/
+char *_app2sd_find_associated_device(const char *mmc_app_path);
+
+/*This function creates loopback device*/
+int _app2sd_create_loopback_device(const char *pkgid, int size);
+
+/*This function deletes loopback device associated with the app*/
+int _app2sd_delete_loopback_device(const char *pkgid);
+
+/*This function creates ext4 FS on the device path*/
+int _app2sd_create_file_system(const char *device_path);
+
+/*This function mounts the app content on the device node*/
+int _app2sd_mount_app_content(const char *pkgid, const char *dev,
+ int mount_type, GList* dir_list, app2sd_cmd cmd);
+
+/*This function unmounts the app content */
+int _app2sd_unmount_app_content(const char *pkgid);
+
+/*This function removes the loopbck encryption setup for the app*/
+int _app2sd_remove_loopback_encryption_setup(const char *pkgid);
+
+/*This function removes all of loopbck encryption setup for the app*/
+int _app2sd_remove_all_loopback_encryption_setups(const char *pkgid);
+
+/*This function updates loopback device size*/
+int _app2sd_update_loopback_device_size(const char *pkgid,
+ int size, GList* dir_list);
+
+/* This generates password */
+char *_app2sd_generate_password(const char *pkgid);
+
+/*This function encrypts device*/
+char *_app2sd_encrypt_device(const char *device, const char *pkgid,
+ char *passwd);
+
+/*This function finds free device*/
+char *_app2sd_find_free_device(void);
+
+/*This function initializes app2sd DB*/
+int _app2sd_initialize_db();
+
+/*This function is used to get password from db*/
+char *_app2sd_get_password_from_db(const char *pkgid);
+
+/*This function removes password from db */
+int _app2sd_remove_password_from_db(const char *pkgid);
+
+/* This functions saved password in db */
+int _app2sd_set_password_in_db(const char *pkgid,
+ const char *passwd);
+
+/* This functions make result file */
+void _app2sd_make_result_info_file(char *pkgid, int size);
+
+#endif
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ * Jyotsna Dhumale <jyotsna.a@samsung.com>
+ * Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <app2sd_internals.h>
+#include <app2sd_interface.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <pkgmgr-info.h>
+#include <vconf.h>
+
+#define MAX_BUF_LEN 1024
+#define APP2SD_TMP_PATH "/opt/usr/apps/tmp"
+
+int app2sd_pre_app_install(const char *pkgid, GList* dir_list,
+ int size)
+{
+ int ret = 0;
+ int free_mmc_mem = 0;
+ char *device_node = NULL;
+ char *devi = NULL;
+ char *result = NULL;
+
+ /*Validate the function parameter recieved */
+ if (pkgid == NULL || dir_list == NULL || size <= 0) {
+ app2ext_print("App2Sd Error : Invalid function arguments\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+ /*Find available free memory in the MMC card */
+ ret = _app2sd_get_available_free_memory(MMC_PATH,
+ &free_mmc_mem);
+ if (ret) {
+ app2ext_print("App2Sd Error : Unable to get available free memory in MMC %d\n", ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+ /*If avaialalbe free memory in MMC is less than required size + 5MB , return error */
+ if ((size + PKG_BUF_SIZE + MEM_BUF_SIZE) > free_mmc_mem) {
+ app2ext_print("Insufficient memory in MMC for application installation %d\n", ret);
+ return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
+ }
+ /*Create a loopback device */
+ ret = _app2sd_create_loopback_device(pkgid, (size+PKG_BUF_SIZE));
+ if (ret) {
+ app2ext_print("App2Sd Error : Package already present\n");
+ char buf_dir[FILENAME_MAX] = { 0, };
+ memset((void *)&buf_dir, '\0', FILENAME_MAX);
+ snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
+ ret = _app2sd_delete_directory(buf_dir);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : Unable to delete the directory %s\n",
+ buf_dir);
+ }
+ }
+ /*Perform Loopback encryption setup */
+ device_node = _app2sd_do_loopback_encryption_setup(pkgid);
+ if (!device_node) {
+ app2ext_print("App2Sd Error : Loopback encryption setup failed\n");
+ _app2sd_delete_loopback_device(pkgid);
+ return APP2EXT_ERROR_DO_LOSETUP;
+ }
+ /*Check whether loopback device is associated with device node or not */
+ devi = _app2sd_find_associated_device_node(pkgid);
+ if (devi == NULL) {
+ app2ext_print("App2Sd Error : finding associated device node failed\n");
+ ret = APP2EXT_ERROR_DO_LOSETUP;
+ goto FINISH_OFF;
+ }
+
+ /*Format the loopback file system */
+ ret = _app2sd_create_file_system(device_node);
+ if (ret) {
+ app2ext_print("App2Sd Error : creating FS failed failed\n");
+ ret = APP2EXT_ERROR_CREATE_FS;
+ goto FINISH_OFF;
+ }
+
+ /*Mount the loopback encrypted pseudo device on application installation path as with Read Write permission */
+ ret =_app2sd_mount_app_content(pkgid, device_node, MOUNT_TYPE_RW,
+ dir_list, APP2SD_PRE_INSTALL);
+ if (ret) {
+ app2ext_print("App2Sd Error : mounting dev path to app install path failed\n");
+ ret = APP2EXT_ERROR_MOUNT_PATH;
+ goto FINISH_OFF;
+ }
+
+ /*Success */
+ ret = APP2EXT_SUCCESS;
+ goto END;
+
+FINISH_OFF:
+
+ if (device_node) {
+ result = _app2sd_detach_loop_device(device_node);
+ if (result) {
+ free(result);
+ result = NULL;
+ }
+ _app2sd_delete_loopback_device(pkgid);
+ }
+END:
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
+ if (devi) {
+ free(devi);
+ devi = NULL;
+ }
+ return ret;
+}
+
+int app2sd_post_app_install(const char *pkgid,
+ app2ext_status install_status)
+{
+ char *device_name = NULL;
+ char buf_dir[FILENAME_MAX] = { 0, };
+ int ret = APP2EXT_SUCCESS;
+ /*Validate the function parameter recieved */
+ if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
+ || install_status > APP2EXT_STATUS_SUCCESS) {
+ app2ext_print("Invalid func parameters\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+ sync(); //2
+ /*Get the associated device node for SD card applicationer */
+ device_name = _app2sd_find_associated_device_node(pkgid);
+ if (NULL == device_name) {
+ return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
+ }
+ ret = _app2sd_unmount_app_content(pkgid);
+ if (ret) {
+ if (device_name) {
+ free(device_name);
+ device_name = NULL;
+ }
+ app2ext_print("Unable to unmount the app content %d\n", ret);
+ return APP2EXT_ERROR_UNMOUNT;
+ }
+ ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+ if (ret) {
+ if (device_name) {
+ free(device_name);
+ device_name = NULL;
+ }
+ app2ext_print
+ ("Unable to Detach the loopback encryption setup for the application");
+ return APP2EXT_ERROR_UNMOUNT;
+ }
+ if (device_name) {
+ free(device_name);
+ device_name = NULL;
+ }
+
+ /*Take appropriate action based on installation
+ status of application package */
+ if (install_status == APP2EXT_STATUS_FAILED) {
+ /*Delete the loopback device from the SD card */
+ ret = _app2sd_delete_loopback_device(pkgid);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : Unable to delete the loopback device from the SD Card\n");
+ return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+ }
+ ret = _app2sd_remove_password_from_db(pkgid);
+
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : Unable to delete the password\n");
+ }
+
+ snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
+
+ ret = _app2sd_delete_directory(buf_dir);
+
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : Unable to delete the directory %s\n",
+ buf_dir);
+ }
+
+ } else {
+ /*If the status is success, then update installed storage to pkgmgr_parser db*/
+ int rt = 0;
+ rt = pkgmgrinfo_pkginfo_set_installed_storage(pkgid, INSTALL_EXTERNAL);
+ if (rt < 0) {
+ app2ext_print("fail to update installed location to db[%s, %s]\n", pkgid, INSTALL_EXTERNAL);
+ }
+ }
+ return ret;
+}
+
+int app2sd_on_demand_setup_init(const char *pkgid)
+{
+ int ret = APP2EXT_SUCCESS;
+ char app_path[FILENAME_MAX] = { 0, };
+ char *device_node = NULL;
+ char *result = NULL;
+ FILE *fp = NULL;
+
+ /*Validate the function parameter recieved */
+ if (pkgid == NULL) {
+ app2ext_print
+ ("App2Sd Error : Invalid function arguments to app launch setup\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+
+ /*check app entry is there in sd card or not. */
+ snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+ pkgid);
+ fp = fopen(app_path, "r+");
+ if (fp == NULL) {
+ app2ext_print
+ ("App2SD Error: App Entry is not present in SD Card\n");
+ return APP2EXT_ERROR_INVALID_PACKAGE;
+ }
+ fclose(fp);
+ result = (char *)_app2sd_find_associated_device(app_path);
+ /*process the string */
+ if ((result!=NULL) && strstr(result, "/dev") != NULL) {
+ app2ext_print("App2SD Error! Already associated\n");
+ free(result);
+ result = NULL;
+ return APP2EXT_ERROR_ALREADY_MOUNTED;
+ }
+
+ /*Do loopback setup */
+ device_node = _app2sd_do_loopback_encryption_setup(pkgid);
+ if (device_node == NULL) {
+ app2ext_print
+ ("App2Sd Error : loopback encryption setup failed\n");
+ return APP2EXT_ERROR_DO_LOSETUP;
+ }
+
+ /*Do mounting */
+ ret =
+ _app2sd_mount_app_content(pkgid, device_node, MOUNT_TYPE_RD,
+ NULL, APP2SD_APP_LAUNCH);
+ if (ret) {
+ app2ext_print("App2Sd Error : Re-mount failed\n");
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
+ return APP2EXT_ERROR_MOUNT_PATH;
+ }
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
+ return ret;
+}
+
+int app2sd_on_demand_setup_exit(const char *pkgid)
+{
+ int ret = APP2EXT_SUCCESS;
+ char app_path[FILENAME_MAX] = { 0, };
+ FILE *fp = NULL;
+
+ /*Validate the function parameter recieved */
+ if (pkgid == NULL) {
+ app2ext_print
+ ("App2Sd Error : Invalid function arguments to app launch setup\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+ /*check app entry is there in sd card or not. */
+ snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+ pkgid);
+ fp = fopen(app_path, "r+");
+ if (fp == NULL) {
+ app2ext_print
+ ("App2SD Error: App Entry is not present in SD Card\n");
+ return APP2EXT_ERROR_INVALID_PACKAGE;
+ }
+ fclose(fp);
+ ret = _app2sd_unmount_app_content(pkgid);
+ if (ret) {
+ app2ext_print
+ ("App2SD Error: Unable to unmount the SD application\n");
+ return APP2EXT_ERROR_UNMOUNT;
+ }
+ ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+ if (ret) {
+ app2ext_print("App2SD Error: Unable to remove loopback setup\n");
+ return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+ }
+ return ret;
+}
+
+int app2sd_pre_app_uninstall(const char *pkgid)
+{
+ int ret = APP2EXT_SUCCESS;
+ char app_path[FILENAME_MAX] = { 0, };
+ char *device_node = NULL;
+ FILE*fp = NULL;
+
+ /*Validate the function parameter recieved */
+ if (pkgid == NULL) {
+ app2ext_print
+ ("App2Sd Error : Invalid function arguments to app launch setup\n");
+ ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
+ goto END;
+ }
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ ret = APP2EXT_ERROR_MMC_STATUS;
+ goto END;
+ }
+ /*check app entry is there in sd card or not. */
+ snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH, pkgid);
+ fp = fopen(app_path, "r+");
+ if (fp == NULL) {
+ app2ext_print
+ ("App2SD Error: App Entry is not present in SD Card\n");
+ ret = APP2EXT_ERROR_INVALID_PACKAGE;
+ goto END;
+ }
+ fclose(fp);
+
+ /*Get the associated device node for SD card applicationer */
+ device_node = _app2sd_find_associated_device_node(pkgid);
+ if (NULL == device_node) {
+ /*Do loopback setup */
+ device_node = _app2sd_do_loopback_encryption_setup(pkgid);
+
+ if (device_node == NULL) {
+ app2ext_print
+ ("App2Sd Error : loopback encryption setup failed\n");
+ ret = APP2EXT_ERROR_DO_LOSETUP;
+ goto END;
+ }
+ /*Do mounting */
+ ret =
+ _app2sd_mount_app_content(pkgid, device_node,
+ MOUNT_TYPE_RW, NULL,
+ APP2SD_PRE_UNINSTALL);
+
+ if (ret) {
+ app2ext_print("App2Sd Error : RW-mount failed\n");
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
+ ret = APP2EXT_ERROR_MOUNT_PATH;
+ goto END;
+ }
+ } else {
+ /*Do re-mounting */
+ ret =
+ _app2sd_mount_app_content(pkgid, device_node,
+ MOUNT_TYPE_RW_REMOUNT, NULL,
+ APP2SD_PRE_UNINSTALL);
+
+ if (ret) {
+ app2ext_print("App2Sd Error : Re-mount failed\n");
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
+ ret = APP2EXT_ERROR_MOUNT_PATH;
+ goto END;
+ }
+ }
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
+
+END:
+ if (ret != APP2EXT_SUCCESS)
+ app2ext_print("App2Sd Error : app2sd has [%d]error, but return success for uninstallation\n", ret);
+ return ret;
+}
+
+/*
+* app2sd_post_app_uninstall_setup
+* Uninstall Application and free all the allocated resources
+* Called after dpkg remove, It deallocates dev node and loopback
+*/
+int app2sd_post_app_uninstall(const char *pkgid)
+{
+ char buf_dir[FILENAME_MAX] = { 0, };
+ int ret = APP2EXT_SUCCESS;
+ int ret1 = APP2EXT_SUCCESS;
+ /*Validate the function parameter recieved */
+ if (pkgid == NULL) {
+ app2ext_print
+ ("App2Sd Error : Invalid function arguments to Post Uninstall\n");
+ ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
+ goto END;
+ }
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ ret = APP2EXT_ERROR_MMC_STATUS;
+ goto END;
+ }
+ /*Unmount the loopback encrypted pseudo device from the application installation path */
+ ret = _app2sd_unmount_app_content(pkgid);
+ if (ret) {
+ app2ext_print("Unable to unmount the app content %d\n", ret);
+ ret = APP2EXT_ERROR_UNMOUNT;
+ goto END;
+ }
+ /*Detach the loopback encryption setup for the application */
+ ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+ if (ret) {
+ app2ext_print
+ ("Unable to Detach the loopback encryption setup for the application");
+ ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
+ goto END;
+ }
+ /*Delete the loopback device from the SD card */
+ ret = _app2sd_delete_loopback_device(pkgid);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : Unable to delete the loopback device from the SD Card\n");
+ ret = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+ goto END;
+ }
+ memset((void *)&buf_dir, '\0', FILENAME_MAX);
+ snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
+ ret1 = _app2sd_delete_directory(buf_dir);
+ if (ret1) {
+ app2ext_print
+ ("App2Sd Error : Unable to delete the directory %s\n",
+ buf_dir);
+ }
+ /*remove encryption password from DB */
+ ret = _app2sd_initialize_db();
+ if (ret) {
+ app2ext_print("\n app2sd db initialize failed");
+ ret = APP2EXT_ERROR_SQLITE_REGISTRY;
+ goto END;
+ }
+ ret = _app2sd_remove_password_from_db(pkgid);
+ if (ret) {
+ app2ext_print("cannot remove password from db \n");
+ ret = APP2EXT_ERROR_SQLITE_REGISTRY;
+ goto END;
+ }
+
+END:
+ if (ret != APP2EXT_SUCCESS)
+ app2ext_print("App2Sd Error : app2sd has [%d]error, but return success for uninstallation\n", ret);
+ return ret;
+}
+
+int app2sd_move_installed_app(const char *pkgid, GList* dir_list,
+ app2ext_move_type move_type)
+{
+ int ret = 0;
+ int pkgmgrinfo_ret = 0;
+
+ /*Validate function arguments*/
+ if (pkgid == NULL || dir_list == NULL
+ || move_type < APP2EXT_MOVE_TO_EXT
+ || move_type > APP2EXT_MOVE_TO_PHONE) {
+ app2ext_print("App2Sd Error : Invalid function arguments\n");
+ ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
+ goto END;
+ }
+
+ /*If move is completed, then update installed storage to pkgmgr_parser db*/
+ pkgmgrinfo_pkginfo_h info_handle = NULL;
+ pkgmgrinfo_installed_storage storage = PMINFO_INTERNAL_STORAGE;
+ pkgmgrinfo_ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &info_handle);
+ if (pkgmgrinfo_ret < 0) {
+ app2ext_print("App2Sd Error : pkgmgrinfo_pkginfo_get_pkginfo[%s] fail.. \n", pkgid);
+ }
+ pkgmgrinfo_ret = pkgmgrinfo_pkginfo_get_installed_storage(info_handle, &storage);
+ if (pkgmgrinfo_ret < 0) {
+ app2ext_print("App2Sd Error : pkgmgrinfo_pkginfo_get_installed_storage[%s] fail.. \n", pkgid);
+ }
+
+ if ((move_type == APP2EXT_MOVE_TO_EXT && storage == PMINFO_EXTERNAL_STORAGE)
+ || (move_type == APP2EXT_MOVE_TO_PHONE && storage == PMINFO_INTERNAL_STORAGE)) {
+ ret = APP2EXT_ERROR_PKG_EXISTS;
+ app2ext_print("App2Sd Error : PKG_EXISTS in [%d]STORAGE\n", storage);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
+ goto END;
+ } else {
+ app2ext_print("App2Sd info : pkgid[%s] move to STORAGE[%d]\n", pkgid, storage);
+ }
+ pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
+
+ ret = _app2sd_move_app(pkgid, move_type, dir_list);
+ if (ret) {
+ app2ext_print("App2Sd Error : Unable to move application\n");
+ goto END;
+ }
+
+ /*If move is completed, then update installed storage to pkgmgr_parser db*/
+ if (move_type == APP2EXT_MOVE_TO_EXT) {
+ pkgmgrinfo_ret = pkgmgrinfo_pkginfo_set_installed_storage(pkgid, INSTALL_EXTERNAL);
+ if (pkgmgrinfo_ret < 0) {
+ app2ext_print("App2Sd Error : fail to update installed location to db[%s, %s]\n", pkgid, INSTALL_EXTERNAL);
+ }
+ } else {
+ pkgmgrinfo_ret = pkgmgrinfo_pkginfo_set_installed_storage(pkgid, INSTALL_INTERNAL);
+ if (pkgmgrinfo_ret < 0) {
+ app2ext_print("App2Sd Error : fail to update installed location to db[%s, %s]\n", pkgid, INSTALL_INTERNAL);
+ }
+ }
+END:
+
+// vconf_set_int(VCONFKEY_PKGMGR_STATUS, ret);
+ _app2sd_make_result_info_file(pkgid, ret);
+
+ return ret;
+}
+
+int app2sd_pre_app_upgrade(const char *pkgid, GList* dir_list,
+ int size)
+{
+ int ret = APP2EXT_SUCCESS;
+ char app_path[FILENAME_MAX] = { 0, };
+ char *device_node = NULL;
+ unsigned long long curr_size = 0;
+ FILE *fp = NULL;
+
+ /*Validate function arguments*/
+ if (pkgid == NULL || dir_list == NULL || size<=0) {
+ app2ext_print
+ ("App2Sd Error : Invalid function arguments \n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+ /*check app entry is there in sd card or not. */
+ snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+ pkgid);
+ app2ext_print("App2Sd Log : Checking path %s\n", app_path);
+ fp = fopen(app_path, "r+");
+ if (fp == NULL) {
+ app2ext_print
+ ("App2SD Error: App Entry is not present in SD Card\n");
+ return APP2EXT_ERROR_INVALID_PACKAGE;
+ }
+ fclose(fp);
+ /*Get installed app size*/
+ curr_size = _app2sd_calculate_file_size(app_path);
+ curr_size = (curr_size/1024)/1024;
+
+ if (curr_size==0) {
+ app2ext_print
+ ("App2SD Error: App Entry is not present in SD Card\n");
+ return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
+ }
+ if (curr_size<size) {
+ ret = _app2sd_update_loopback_device_size(pkgid, size, dir_list);
+ if(APP2EXT_SUCCESS !=ret) {
+ app2ext_print
+ ("App2SD Error: _app2sd_update_loopback_device_size() failed\n");
+ return ret;
+ }
+ }
+
+ /*Get the associated device node for SD card applicationer */
+ device_node = _app2sd_find_associated_device_node(pkgid);
+ if (NULL == device_node) {
+ /*Do loopback setup */
+ device_node = _app2sd_do_loopback_encryption_setup(pkgid);
+ if (device_node == NULL) {
+ app2ext_print
+ ("App2Sd Error : loopback encryption setup failed\n");
+ return APP2EXT_ERROR_DO_LOSETUP;
+ }
+ /*Do mounting */
+ ret =
+ _app2sd_mount_app_content(pkgid, device_node,
+ MOUNT_TYPE_RW, NULL,
+ APP2SD_PRE_UPGRADE);
+ if (ret) {
+ app2ext_print("App2Sd Error : Re-mount failed\n");
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
+ return APP2EXT_ERROR_MOUNT_PATH;
+ }
+ } else {
+ /*Do re-mounting */
+ ret =
+ _app2sd_mount_app_content(pkgid, device_node,
+ MOUNT_TYPE_RW_REMOUNT, NULL,
+ APP2SD_PRE_UPGRADE);
+ if (ret) {
+ app2ext_print("App2Sd Error : Re-mount failed\n");
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
+ return APP2EXT_ERROR_MOUNT_PATH;
+ }
+ }
+
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
+ return ret;
+}
+
+
+int app2sd_post_app_upgrade(const char *pkgid,
+ app2ext_status install_status)
+{
+ char *device_name = NULL;
+ int ret = APP2EXT_SUCCESS;
+ /*Validate the function parameter recieved */
+ if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
+ || install_status > APP2EXT_STATUS_SUCCESS) {
+ app2ext_print("Invalid func parameters\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+
+ /*Get the associated device node for SD card applicationer */
+ device_name = _app2sd_find_associated_device_node(pkgid);
+ if (NULL == device_name) {
+ return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
+ }
+ ret = _app2sd_unmount_app_content(pkgid);
+ if (ret) {
+ if (device_name) {
+ free(device_name);
+ device_name = NULL;
+ }
+ app2ext_print("Unable to unmount the app content %d\n", ret);
+ return APP2EXT_ERROR_UNMOUNT;
+ }
+ ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+ if (ret) {
+ if (device_name) {
+ free(device_name);
+ device_name = NULL;
+ }
+ app2ext_print
+ ("Unable to Detach the loopback encryption setup for the application");
+ return APP2EXT_ERROR_UNMOUNT;
+ }
+ if (device_name) {
+ free(device_name);
+ device_name = NULL;
+ }
+ return ret;
+}
+
+#if 0
+/**
+ * Reserved API for forced cleanup
+ *
+ */
+int app2sd_force_cleanup(const char *pkgid){
+ char *device_name = NULL;
+ char buf_dir[FILENAME_MAX] = { 0, };
+ int ret = APP2EXT_SUCCESS;
+ FILE *fp = NULL;
+
+ /*Validate the function parameter recieved */
+ if (pkgid == NULL) {
+ app2ext_print("invalid func parameters\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+ memset((void *)&buf_dir, '\0', FILENAME_MAX);
+ snprintf(buf_dir, FILENAME_MAX, "%s%s", APP2SD_PATH, pkgid);
+ fp = fopen(buf_dir, "r+");
+ if (fp == NULL) {
+ app2ext_print("\"%s\" not installed on SD Card\n", pkgid);
+ return APP2EXT_ERROR_INVALID_PACKAGE;
+ }
+ fclose(fp);
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+
+ /*Get the associated device node for SD card applicationer */
+ device_name = _app2sd_find_associated_device_node(pkgid);
+ if (NULL != device_name) {
+ free(device_name);
+ device_name = NULL;
+ ret = _app2sd_unmount_app_content(pkgid);
+ if (ret) {
+ app2ext_print("Unable to unmount the app content %d\n", ret);
+ return APP2EXT_ERROR_UNMOUNT;
+ }
+ ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+ if (ret) {
+ app2ext_print
+ ("Unable to Detach the loopback encryption setup for the application");
+ return APP2EXT_ERROR_UNMOUNT;
+ }
+ }
+
+ memset((void *)&buf_dir, '\0', FILENAME_MAX);
+ snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
+ ret = _app2sd_delete_directory(buf_dir);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : Unable to delete the directory %s\n",
+ buf_dir);
+ }
+
+ /*remove passwrd from DB*/
+ ret = _app2sd_initialize_db();
+ if (ret) {
+ app2ext_print("\n app2sd db initialize failed");
+ return APP2EXT_ERROR_SQLITE_REGISTRY;
+ }
+ ret = _app2sd_remove_password_from_db(pkgid);
+ if (ret) {
+ app2ext_print("cannot remove password from db \n");
+ return APP2EXT_ERROR_SQLITE_REGISTRY;
+ }
+ return ret;
+}
+#endif
+
+int app2sd_force_clean(const char *pkgid)
+{
+ char buf_dir[FILENAME_MAX] = { 0, };
+ int ret = APP2EXT_SUCCESS;
+
+ /*Validate the function parameter recieved */
+ if (pkgid == NULL) {
+ app2ext_print("Invalid func parameters\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+ app2ext_print("star force_clean [%s]", pkgid);
+
+ sync(); //2
+ /*Unmount the loopback encrypted pseudo device from the application installation path */
+ ret = _app2sd_unmount_app_content(pkgid);
+ if (ret) {
+ app2ext_print("Unable to unmount the app content %d\n", ret);
+ }
+
+ /*Detach the loopback encryption setup for the application */
+ ret = _app2sd_remove_all_loopback_encryption_setups(pkgid);
+ if (ret) {
+ app2ext_print("Unable to Detach the loopback encryption setup for the application");
+ }
+
+ /*Delete the loopback device from the SD card */
+ ret = _app2sd_delete_loopback_device(pkgid);
+ if (ret) {
+ app2ext_print("Unable to Detach the loopback encryption setup for the application");
+ }
+
+ /*Delete symlink*/
+ memset((void *)&buf_dir, '\0', FILENAME_MAX);
+ snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
+
+ _app2sd_delete_symlink(buf_dir);
+
+ /*remove passwrd from DB*/
+ ret = _app2sd_initialize_db();
+ if (ret) {
+ app2ext_print("\n app2sd db initialize failed");
+ }
+ ret = _app2sd_remove_password_from_db(pkgid);
+ if (ret) {
+ app2ext_print("cannot remove password from db \n");
+ }
+
+ app2ext_print("finish force_clean");
+ return 0;
+}
+
+/* This is the plug-in load function. The plugin has to bind its functions to function pointers of handle
+ @param[in/out] st_interface Specifies the storage interface.
+*/
+void
+app2ext_on_load(app2ext_interface *st_interface)
+{
+ /*Plug-in Binding.*/
+ st_interface->pre_install= app2sd_pre_app_install;
+ st_interface->post_install= app2sd_post_app_install;
+ st_interface->pre_uninstall= app2sd_pre_app_uninstall;
+ st_interface->post_uninstall= app2sd_post_app_uninstall;
+ st_interface->pre_upgrade= app2sd_pre_app_upgrade;
+ st_interface->post_upgrade= app2sd_post_app_upgrade;
+ st_interface->move= app2sd_move_installed_app;
+ st_interface->force_clean= app2sd_force_clean;
+ st_interface->enable= app2sd_on_demand_setup_init;
+ st_interface->disable= app2sd_on_demand_setup_exit;
+}
+
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ * Jyotsna Dhumale <jyotsna.a@samsung.com>
+ * Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <app2sd_internals.h>
+#include <app2sd_interface.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <openssl/sha.h>
+#include <fcntl.h>
+#include <time.h>
+#include <dlog.h>
+#include <privilege-control.h>
+
+/*
+########### Internal APIs ##################
+ */
+static int _app2sd_setup_path(const char *pkgid, const char *dirpath,
+ int apppathtype, const char *groupid)
+{
+ int ret = 0;
+
+ if (groupid == NULL) {
+ ret = perm_app_setup_path(pkgid, dirpath, apppathtype);
+ app2ext_print( "[smack] app_setup_path(), result = [%d]", ret);
+ } else {
+ ret = perm_app_setup_path(pkgid, dirpath, apppathtype, groupid);
+ app2ext_print( "[smack] app_setup_path(), result = [%d]", ret);
+ }
+
+ return ret;
+}
+
+static int _app2sd_apply_app_smack(const char *pkgid, GList* dir_list, const char *groupid)
+{
+ int ret = APP2EXT_SUCCESS;
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ char path[FILENAME_MAX] = { 0, };
+
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name
+ && dir_detail->type == APP2EXT_DIR_RO) {
+ snprintf(path, FILENAME_MAX, "%s%s/%s",APP_INSTALLATION_PATH, pkgid, dir_detail->name);
+ ret = _app2sd_setup_path(pkgid, path, PERM_APP_PATH_ANY_LABEL, groupid);
+ if (ret) {
+ app2ext_print ("App2Sd Error : unable to smack %s\n", path);
+ return APP2EXT_ERROR_MOVE;
+ }
+ }
+ list = g_list_next(list);
+ }
+
+ return APP2EXT_SUCCESS;
+}
+
+static int _app2sd_apply_mmc_smack(const char *pkgid, GList* dir_list, const char *groupid)
+{
+ int ret = APP2EXT_SUCCESS;
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ char path[FILENAME_MAX] = { 0, };
+
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name
+ && dir_detail->type == APP2EXT_DIR_RO) {
+ snprintf(path, FILENAME_MAX, "%s%s/.mmc/%s",APP_INSTALLATION_PATH, pkgid, dir_detail->name);
+
+ ret = _app2sd_setup_path(pkgid, path, PERM_APP_PATH_ANY_LABEL, groupid);
+ if (ret) {
+ app2ext_print ("App2Sd Error : unable to smack %s\n", path);
+ return APP2EXT_ERROR_MOVE;
+ }
+ }
+ list = g_list_next(list);
+ }
+
+ return APP2EXT_SUCCESS;
+}
+
+char *_app2sd_find_associated_device_node(const char *pkgid)
+{
+ char *ret_result = NULL;
+ char delims[] = ":";
+ char *result = NULL;
+ char app_path[FILENAME_MAX] = { '\0' };
+ char dev[FILENAME_MAX] = {0,};
+ char *devnode = NULL;
+ snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+ pkgid);
+ result = (char *)_app2sd_find_associated_device(app_path);
+ if (result == NULL) {
+ app2ext_print
+ ("App2SD info! there is no the associated File with [%s]\n", pkgid);
+ return NULL;
+ }
+ /*process the string*/
+ snprintf(dev, FILENAME_MAX-1, "%s", result);
+ if (strstr(dev, "/dev") == NULL) {
+ app2ext_print
+ ("App2SD Error! Unable to find the associated File\n");
+
+ free(result);
+ return NULL;
+ } else {
+ ret_result = strtok(dev, delims);
+ if (ret_result)
+ devnode = strdup(ret_result);
+ }
+ free(result);
+ return devnode;
+}
+
+char *_app2sd_create_loopdevice_node(void)
+{
+ char *ret_result = NULL;
+ mode_t mode = DIR_PERMS;
+ int count = 0;
+ int ret = APP2EXT_SUCCESS;
+ char *result = NULL;
+ FILE *fp = NULL;
+
+ result = (char *)_app2sd_find_free_device();
+ /*validate the result */
+ if (result == NULL || strstr(result, "/dev") == NULL) {
+ app2ext_print("No device found, creating device node...\n");
+
+ if (result) {
+ free(result);
+ result = NULL;
+ }
+ count = 0;
+ char dev_path[BUF_SIZE] = { 0, };
+ snprintf(dev_path, BUF_SIZE, "/dev/loop%d", count);
+ while ((fp = fopen(dev_path, "r+")) != NULL) {
+ count = count + 1;
+ snprintf(dev_path, BUF_SIZE, "/dev/loop%d", count);
+ app2ext_print("next dev path for checking is %s\n",
+ dev_path);
+ fclose(fp);
+ }
+ app2ext_print("Device node candidate is %s \n", dev_path);
+ dev_t dev_node;
+ dev_node = makedev(DEV_MAJOR, count);
+ ret = mknod(dev_path, S_IFBLK | mode, dev_node);
+ if (ret < 0) {
+ app2ext_print
+ ("Error while creating the device node: errno is %d\n",
+ errno);
+ return NULL;
+ }
+ ret_result = (char *)malloc(strlen(dev_path) + 1);
+ if (ret_result == NULL) {
+ app2ext_print("Unable to allocate memory\n");
+ return NULL;
+ }
+ memset(ret_result, '\0', strlen(dev_path) + 1);
+ memcpy(ret_result, dev_path, strlen(dev_path));
+ } else {
+ ret_result = (char *)malloc(strlen(result) + 1);
+ if (ret_result == NULL) {
+ app2ext_print("Malloc failed!\n");
+ free(result);
+ result = NULL;
+ return NULL;
+ }
+ memset(ret_result, '\0', strlen(result) + 1);
+ if (strlen(result) > 0) {
+ memcpy(ret_result, result, strlen(result) - 1);
+ }
+ free(result);
+ result = NULL;
+
+ }
+ return ret_result;
+}
+
+char *_app2sd_do_loopback_encryption_setup(const char *pkgid)
+{
+ int ret = APP2EXT_SUCCESS;
+ char *passwd = NULL;
+ char app_path[FILENAME_MAX] = { '\0' };
+ char *result = NULL;
+ char *device_node = NULL;
+ if (pkgid == NULL) {
+ app2ext_print("App2Sd Error: Invalid argument\n");
+ return NULL;
+ }
+
+ snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+ pkgid);
+ /* Get password for loopback encryption */
+ ret = _app2sd_initialize_db();
+ if (ret) {
+ app2ext_print("\n app2sd db initialize failed");
+ return NULL;
+ }
+ if ((passwd = _app2sd_get_password_from_db(pkgid)) == NULL) {
+ passwd = (char *)_app2sd_generate_password(pkgid);
+ if (NULL == passwd) {
+ app2ext_print
+ ("App2Sd Error: Unable to generate password\n");
+ return NULL;
+ } else {
+ app2ext_print("Password is %s\n", passwd);
+ if ((ret = _app2sd_set_password_in_db(pkgid,
+ passwd)) < 0) {
+ app2ext_print
+ ("App2Sd Error: Unable to save password\n");
+ free(passwd);
+ passwd = NULL;
+ return NULL;
+ }
+ }
+ }
+
+ /*Get Free device node*/
+ device_node = _app2sd_create_loopdevice_node();
+ if (NULL == device_node) {
+ free(passwd);
+ passwd = NULL;
+ app2ext_print
+ ("App2Sd Error: Unable to find free loopback node\n");
+ return NULL;
+ }
+ result = (char *)_app2sd_encrypt_device(device_node, app_path, passwd);
+ if (result == NULL) {
+ app2ext_print("App2Sd Error: Encryption failed!\n\n");
+ free(passwd);
+ passwd = NULL;
+ return NULL;
+ } else {
+ free(result);
+ result = NULL;
+ free(passwd);
+ passwd = NULL;
+ return device_node;
+ }
+}
+
+char *_app2sd_do_loopback_duplicate_encryption_setup(const char *pkgid, const char * dup_appname)
+{
+ int ret = APP2EXT_SUCCESS;
+ char *passwd = NULL;
+ char app_path[FILENAME_MAX] = { '\0' };
+ char *result = NULL;
+ char *device_node = NULL;
+ if (pkgid == NULL || dup_appname == NULL) {
+ app2ext_print("App2Sd Error: Invalid argument\n");
+ return NULL;
+ }
+
+ snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+ dup_appname);
+ /* Get password for loopback encryption */
+ ret = _app2sd_initialize_db();
+ if (ret) {
+ app2ext_print("\n app2sd db initialize failed");
+ return NULL;
+ }
+ if ((passwd = _app2sd_get_password_from_db(pkgid)) == NULL) {
+ passwd = (char *)_app2sd_generate_password(pkgid);
+ if (NULL == passwd) {
+ app2ext_print
+ ("App2Sd Error: Unable to generate password\n");
+ return NULL;
+ } else {
+ app2ext_print("Password is %s\n", passwd);
+ if ((ret = _app2sd_set_password_in_db(pkgid,
+ passwd)) < 0) {
+ app2ext_print
+ ("App2Sd Error: Unable to save password\n");
+ free(passwd);
+ passwd = NULL;
+ return NULL;
+ }
+ }
+
+ }
+ /*Get Free device node*/
+ device_node = _app2sd_create_loopdevice_node();
+ if (NULL == device_node) {
+ free(passwd);
+ passwd = NULL;
+ app2ext_print
+ ("App2Sd Error: Unable to find free loopback node\n");
+ return NULL;
+ }
+ result = (char *)_app2sd_encrypt_device(device_node, app_path, passwd);
+ if (result == NULL) {
+ app2ext_print("App2Sd Error: Encryption failed!\n\n");
+ free(passwd);
+ passwd = NULL;
+ return NULL;
+ } else {
+ if (strlen(result) == 0) {
+ free(result);
+ result = NULL;
+ free(passwd);
+ passwd = NULL;
+ return device_node;
+ } else {
+ app2ext_print("App2Sd Error: Error is %s\n", result);
+ free(result);
+ result = NULL;
+ free(passwd);
+ passwd = NULL;
+ return NULL;
+ }
+ }
+ return device_node;
+}
+
+int _app2sd_remove_loopback_encryption_setup(const char *pkgid)
+{
+ int ret = APP2EXT_SUCCESS;
+ char *result = NULL;
+ char *dev_node = NULL;
+ if ((dev_node = _app2sd_find_associated_device_node(pkgid)) == NULL) {
+ app2ext_print("Unable to find the association\n");
+ ret = APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
+ }
+ result = (char *)_app2sd_detach_loop_device(dev_node);
+ if (result == NULL) {
+ app2ext_print("App2sd Error: Error in detaching\n");
+ ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
+ } else {
+ free(result);
+ result = NULL;
+ }
+ if (dev_node) {
+ free(dev_node);
+ dev_node = NULL;
+ }
+ return ret;
+}
+
+int _app2sd_remove_all_loopback_encryption_setups(const char *pkgid)
+{
+ int ret = APP2EXT_SUCCESS;
+ char *result = NULL;
+ char *dev_node = NULL;
+ while(1) {
+ if ((dev_node = _app2sd_find_associated_device_node(pkgid)) == NULL) {
+ app2ext_print("finish to find the association\n");
+ ret = APP2EXT_SUCCESS;
+ break;
+ }
+
+ app2ext_print("find node :: %s \n", dev_node);
+
+ result = (char *)_app2sd_detach_loop_device(dev_node);
+ if (result == NULL) {
+ app2ext_print("App2sd Error: Error in detaching\n");
+ ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
+ break;
+ } else {
+ free(result);
+ result = NULL;
+ }
+ if (dev_node) {
+ free(dev_node);
+ dev_node = NULL;
+ }
+ }
+ return ret;
+}
+
+int _app2sd_create_loopback_device(const char *pkgid, int size)
+{
+ int ret = APP2EXT_SUCCESS;
+ char command[FILENAME_MAX] = { 0, };
+ mode_t mode = DIR_PERMS;
+ char external_storage_path[FILENAME_MAX] = { 0, };
+ char buff[BUF_SIZE] = { 0, };
+ char app_path[FILENAME_MAX] = { 0, };
+ FILE *fp = NULL;
+
+ if (NULL == pkgid || size <= 0) {
+ app2ext_print("App2Sd Error: Invalid argument\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+ snprintf(command, FILENAME_MAX, "of=%s%s", APP2SD_PATH,
+ pkgid);
+ snprintf(buff, BUF_SIZE, "count=%d", size);
+ const char *argv1[] =
+ { "dd", "if=/dev/zero", command, "bs=1M", buff, NULL };
+ snprintf(external_storage_path, FILENAME_MAX, "%s",
+ APP2SD_PATH);
+ ret = mkdir(external_storage_path, mode);
+ if (ret) {
+ if (errno != EEXIST) {
+ app2ext_print
+ ("App2sd Error : Create directory failed, error no is %d\n",
+ errno);
+ return APP2EXT_ERROR_CREATE_DIRECTORY;
+ }
+ }
+ snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+ pkgid);
+ if ((fp = fopen(app_path, "r+")) != NULL) {
+ app2ext_print("Application already exists %s\n", app_path);
+ fclose(fp);
+ return APP2EXT_ERROR_PKG_EXISTS;
+ }
+
+ ret = _xsystem(argv1);
+ if (ret) {
+ app2ext_print("App2Sd Error : command \"%s\" failed \n",
+ command);
+ return ret;
+ }
+ return ret;
+}
+
+int _app2sd_delete_loopback_device(const char *pkgid)
+{
+ int ret = APP2EXT_SUCCESS;
+ char loopback_device[FILENAME_MAX] = { 0, };
+
+ snprintf(loopback_device, FILENAME_MAX, "%s%s", APP2SD_PATH,
+ pkgid);
+
+ ret = unlink(loopback_device);
+ if (ret) {
+ if (errno == ENOENT) {
+ app2ext_print("Unable to access file %s\n", loopback_device);
+ } else {
+ app2ext_print("Unable to delete %s\n", loopback_device);
+ return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+ }
+ }
+ return ret;
+}
+
+int _app2sd_create_file_system(const char *device_path)
+{
+ int ret = APP2EXT_SUCCESS;
+ FILE *fp = NULL;
+ if (NULL == device_path) {
+ app2ext_print("App2Sd Error: invalid param [NULL]\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+
+ /*Format the filesystem [create a filesystem]*/
+ const char *argv[] = { "/sbin/mkfs.ext4", device_path, NULL };
+ fp = fopen(device_path, "r+");
+ if (fp == NULL) {
+ app2ext_print
+ ("App2sd Error: Unable to access %s [System errono is %d.....%s]\n",
+ device_path, errno, strerror(errno));
+ return APP2EXT_ERROR_ACCESS_FILE;
+ } else {
+ fclose(fp);
+ }
+ ret = _xsystem(argv);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : creating file system failed [System error is %s\n",
+ strerror(errno));
+ return APP2EXT_ERROR_CREATE_FS;
+ }
+ return ret;
+}
+
+static int _app2sd_create_dir_with_link(const char *pkgid,
+ const char *dir_name)
+{
+ mode_t mode = DIR_PERMS;
+ int ret = APP2EXT_SUCCESS;
+ char app_dir_mmc_path[FILENAME_MAX] = { 0, };
+ char app_dir_path[FILENAME_MAX] = { 0, };
+ snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc/%s",APP_INSTALLATION_PATH,
+ pkgid, dir_name);
+ snprintf(app_dir_path, FILENAME_MAX, "%s%s/%s", APP_INSTALLATION_PATH, pkgid,
+ dir_name);
+
+ ret = mkdir(app_dir_mmc_path, mode);
+ if (ret) {
+ if (errno != EEXIST) {
+ app2ext_print
+ ("App2sd Error : Create directory failed, error no is %d\n",
+ errno);
+ return APP2EXT_ERROR_CREATE_DIRECTORY;
+ }
+ }
+
+ if ((ret = symlink(app_dir_mmc_path, app_dir_path)) < 0) {
+ if (errno == EEXIST) {
+ app2ext_print
+ ("App2sd : File with Symlink name present %s\n",
+ app_dir_path);
+ } else {
+ app2ext_print
+ ("A2Sd Error : Symbolic link creation failed, error no is %d\n",
+ errno);
+ return APP2EXT_ERROR_CREATE_SYMLINK;
+ }
+ }
+
+ ret = _app2sd_setup_path(pkgid, app_dir_path, PERM_APP_PATH_ANY_LABEL, pkgid);
+ if (ret) {
+ app2ext_print ("App2Sd Error : unable to smack %s\n", app_dir_path);
+ return APP2EXT_ERROR_MOVE;
+ }
+
+ ret = _app2sd_setup_path(pkgid, app_dir_mmc_path, PERM_APP_PATH_ANY_LABEL, pkgid);
+ if (ret) {
+ app2ext_print ("App2Sd Error : unable to smack %s\n", app_dir_mmc_path);
+ return APP2EXT_ERROR_MOVE;
+ }
+
+ return ret;
+}
+
+int _app2sd_create_directory_entry(const char *pkgid, GList* dir_list)
+{
+ int ret = APP2EXT_SUCCESS;
+ char app_dir_path[FILENAME_MAX] = { 0, };
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+
+ snprintf(app_dir_path, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH,
+ pkgid);
+
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name
+ && dir_detail->type == APP2EXT_DIR_RO) {
+ ret = _app2sd_create_dir_with_link(pkgid, dir_detail->name);
+ if (ret) {
+ return ret;
+ }
+ }
+ list = g_list_next(list);
+ }
+ return APP2EXT_SUCCESS;
+}
+
+
+/*
+ *
+ * _app2sd_mount_app_content
+ This function is to create the path for mmc and mount the content
+Example usage: _app2sd_mount_app_content("deb.com.samsung.helloworld","/dev/loop0",MOUNT_TYPE_RD)
+*/
+int _app2sd_mount_app_content(const char *pkgid, const char *dev,
+ int mount_type, GList* dir_list, app2sd_cmd cmd)
+{
+ int ret = APP2EXT_SUCCESS;
+ mode_t mode = DIR_PERMS;
+ char app_dir_path[FILENAME_MAX] = { 0, };
+ char app_dir_mmc_path[FILENAME_MAX] = { 0, };
+ if (NULL == pkgid || NULL == dev) {
+ app2ext_print("App2Sd Error : Input param is NULL %s %s \n",
+ pkgid, dev);
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+ snprintf(app_dir_path, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
+ ret = mkdir(app_dir_path, mode);
+ if (ret) {
+ if (errno != EEXIST) {
+ app2ext_print
+ ("App2Sd Error : Create directory failed, error no is %d\n",
+ errno);
+ return APP2EXT_ERROR_CREATE_DIRECTORY;
+ }
+ }
+ snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
+ ret = mkdir(app_dir_mmc_path, mode);
+ if (ret) {
+ if (errno != EEXIST) {
+ app2ext_print
+ ("App2Sd Error : Create directory failed, error no is %d\n",
+ errno);
+ return APP2EXT_ERROR_CREATE_DIRECTORY;
+ }
+ }
+
+ usleep(200 * 1000); /* 200ms sleep*/
+ app2ext_print ("App2Sd info : give a delay for mount\n");
+
+ switch (mount_type) {
+ case MOUNT_TYPE_RD:
+ {
+ if ((ret =
+ mount(dev, app_dir_mmc_path, FS_TYPE,
+ MS_MGC_VAL | MS_RDONLY, NULL)) < 0) {
+ app2ext_print
+ ("App2Sd Error : Read Only Mount failed [System Erro no is %d], dev is %s path is %s\n",
+ errno, dev, app_dir_mmc_path);
+ ret = APP2EXT_ERROR_MOUNT;
+ }
+ break;
+ }
+ case MOUNT_TYPE_RW:
+ {
+ if ((ret =
+ mount(dev, app_dir_mmc_path, FS_TYPE, MS_MGC_VAL,
+ NULL)) < 0) {
+ app2ext_print
+ ("App2Sd Error : Read Write Mount failed [System Erro no is %d]\n",
+ errno);
+ ret = APP2EXT_ERROR_MOUNT;
+ }
+ break;
+ }
+ case MOUNT_TYPE_RW_NOEXEC:
+ {
+ if ((ret =
+ mount(dev, app_dir_mmc_path, FS_TYPE,
+ MS_MGC_VAL | MS_NOEXEC, NULL)) < 0) {
+ app2ext_print
+ ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
+ errno);
+ ret = APP2EXT_ERROR_MOUNT;
+ }
+ break;
+ }
+ case MOUNT_TYPE_RD_REMOUNT:
+ {
+ if ((ret =
+ mount(dev, app_dir_mmc_path, FS_TYPE,
+ MS_MGC_VAL | MS_RDONLY | MS_REMOUNT,
+ NULL)) < 0) {
+ app2ext_print
+ ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
+ errno);
+ ret = APP2EXT_ERROR_MOUNT;
+ }
+ break;
+ }
+ case MOUNT_TYPE_RW_REMOUNT:
+ {
+ if ((ret =
+ mount(dev, app_dir_mmc_path, FS_TYPE,
+ MS_MGC_VAL | MS_REMOUNT, NULL)) < 0) {
+ app2ext_print
+ ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
+ errno);
+ ret = APP2EXT_ERROR_MOUNT;
+ }
+ break;
+ }
+
+ default:
+ {
+ app2ext_print("App2Sd Error: Invalid mount type\n");
+ break;
+ }
+ }
+ if (cmd == APP2SD_PRE_INSTALL || cmd == APP2SD_MOVE_APP_TO_MMC) {
+ ret = _app2sd_create_directory_entry(pkgid, dir_list);
+ }
+ return ret;
+}
+
+int _app2sd_unmount_app_content(const char *pkgid)
+{
+ int ret = APP2EXT_SUCCESS;
+ char app_dir_mmc_path[FILENAME_MAX] = { 0, };
+ snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
+ if ((ret = umount(app_dir_mmc_path)) < 0) {
+ app2ext_print("Unable to umount the dir %s\n", strerror(errno));
+ }
+ return ret;
+}
+
+static int _app2sd_move_to_archive(const char *src_path, const char *arch_path)
+{
+ int ret = APP2EXT_SUCCESS;
+
+ ret = _app2sd_copy_dir(src_path, arch_path);
+ if (ret) {
+ if (ret != APP2EXT_ERROR_ACCESS_FILE) {
+ app2ext_print
+ ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
+ src_path, arch_path, strerror(errno));
+ return APP2EXT_ERROR_MOVE;
+ }
+ }
+ ret = _app2sd_delete_directory((char *)src_path);
+ if (ret) {
+ if (ret != APP2EXT_ERROR_ACCESS_FILE) {
+ app2ext_print("App2Sd Error : unable to delete %s \n", src_path);
+ return APP2EXT_ERROR_DELETE_DIRECTORY;
+ }
+ }
+ return ret;
+}
+
+int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
+{
+ int ret = APP2EXT_SUCCESS;
+ char app_path[FILENAME_MAX] = { 0, };
+ char path[FILENAME_MAX] = { 0, };
+ char app_mmc_path[FILENAME_MAX] = { 0, };
+ char app_archive_path[FILENAME_MAX] = { 0, };
+ char mmc_path[FILENAME_MAX] = { 0, };
+ unsigned long long total_size = 0;
+ int reqd_size = 0;
+ char *device_node = NULL;
+ char *devi = NULL;
+ mode_t mode = DIR_PERMS;
+ int free_mmc_mem = 0;
+ FILE *fp = NULL;
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+
+ snprintf(mmc_path, FILENAME_MAX,
+ "%s%s", APP2SD_PATH, pkgid);
+
+ /*check whether application is in external memory or not */
+ fp = fopen(mmc_path, "r+");
+ if (fp != NULL) {
+ app2ext_print
+ ("Already %s entry is present in the SD Card, delete entry and go on without return\n",
+ pkgid);
+ fclose(fp);
+// return APP2EXT_ERROR_ALREADY_FILE_PRESENT;
+ }
+
+ snprintf(app_mmc_path, FILENAME_MAX,
+ "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
+ snprintf(app_archive_path, FILENAME_MAX,
+ "%s%s/.archive", APP_INSTALLATION_PATH, pkgid);
+
+ ret = mkdir(app_archive_path, mode);
+ if (ret) {
+ if (errno != EEXIST) {
+ app2ext_print
+ ("App2sd Error: Unable to create directory for archiving, error no is %d\n",
+ errno);
+// return APP2EXT_ERROR_CREATE_DIRECTORY;
+ }
+ }
+
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name
+ && dir_detail->type == APP2EXT_DIR_RO) {
+ memset((void *)&app_path, '\0',
+ FILENAME_MAX);
+ snprintf(app_path, FILENAME_MAX,
+ "%s%s/%s",APP_INSTALLATION_PATH,
+ pkgid,
+ dir_detail->name);
+ total_size +=
+ _app2sd_calculate_dir_size
+ (app_path);
+ }
+ list = g_list_next(list);
+ }
+
+ reqd_size = ((total_size / 1024) / 1024) + 2;
+
+ /*Find avialable free memory in the MMC card */
+ ret =
+ _app2sd_get_available_free_memory
+ (MMC_PATH, &free_mmc_mem);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : Unable to get available free memory in MMC %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+ /*If avaialalbe free memory in MMC is less than required size + 5MB , return error */
+ if (reqd_size > free_mmc_mem) {
+ app2ext_print
+ ("App2Sd Error : Insufficient memory in MMC for application installation %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
+ }
+ /*Create a loopback device */
+ ret =
+ _app2sd_create_loopback_device(pkgid, (reqd_size+PKG_BUF_SIZE));
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : loopback node creation failed\n");
+// return APP2EXT_ERROR_CREATE_DEVICE;
+ }
+ /*Perform Loopback encryption setup */
+ device_node =
+ _app2sd_do_loopback_encryption_setup(pkgid);
+ if (!device_node) {
+ app2ext_print
+ ("App2Sd Error : losetup failed, device node is %s\n",
+ device_node);
+ return APP2EXT_ERROR_DO_LOSETUP;
+ }
+ /*Check whether loopback device is associated with device node or not */
+ devi = _app2sd_find_associated_device_node(pkgid);
+ if (devi == NULL) {
+ app2ext_print
+ ("App2Sd Error : _app2sd_find_associated_device_node losetup failed\n");
+ return APP2EXT_ERROR_DO_LOSETUP;
+ } else {
+ free(devi);
+ devi = NULL;
+ }
+ /*Format the loopback file system */
+ ret = _app2sd_create_file_system(device_node);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : create ext4 filesystem failed\n");
+ return APP2EXT_ERROR_CREATE_FS;
+ }
+ /********Archiving code begin***********/
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name
+ && dir_detail->type == APP2EXT_DIR_RO) {
+ snprintf(path, FILENAME_MAX,
+ "%s%s/%s",APP_INSTALLATION_PATH,
+ pkgid,
+ dir_detail->name);
+ ret =
+ _app2sd_move_to_archive
+ (path,
+ app_archive_path);
+ if (ret) {
+ if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+ app2ext_print
+ ("App2Sd Error : unable to access %s\n",
+ path);
+ } else {
+ app2ext_print
+ ("App2Sd Error : unable to copy from %s to %s \n",
+ path,
+ app_archive_path);
+// return APP2EXT_ERROR_MOVE;
+ }
+ }
+ }
+ list = g_list_next(list);
+ }
+ /********Archiving code ends***********/
+
+ /*mount the loopback encrypted pseudo device on application installation path as with Read Write permission */
+ ret =
+ _app2sd_mount_app_content(pkgid, device_node,
+ MOUNT_TYPE_RW, dir_list,
+ APP2SD_MOVE_APP_TO_MMC);
+ if (ret) {
+ return ret;
+ }
+ /********restore Archive begin***********/
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name
+ && dir_detail->type == APP2EXT_DIR_RO) {
+ memset((void *)&path, '\0',
+ FILENAME_MAX);
+ snprintf(path, FILENAME_MAX,
+ "%s%s/.archive/%s",APP_INSTALLATION_PATH,
+ pkgid,
+ dir_detail->name);
+ ret =
+ _app2sd_copy_dir
+ (path,
+ app_mmc_path);
+ if (ret) {
+ if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+ app2ext_print
+ ("App2Sd Error : unable to access %s\n",
+ path);
+ } else {
+ app2ext_print
+ ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
+ path,
+ app_mmc_path,
+ strerror
+ (errno));
+// return APP2EXT_ERROR_MOVE;
+ }
+ }
+ ret =
+ _app2sd_delete_directory
+ (path);
+ if (ret) {
+ if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+ app2ext_print
+ ("App2Sd Error : unable to access %s\n",
+ path);
+ } else {
+ app2ext_print
+ ("App2Sd Error : unable to delete %s \n",
+ path);
+ return
+ APP2EXT_ERROR_DELETE_DIRECTORY;
+ }
+ }
+ }
+ list = g_list_next(list);
+ }
+
+ ret = _app2sd_delete_directory(app_archive_path);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : unable to delete %s \n",
+ app_archive_path);
+// return APP2EXT_ERROR_DELETE_DIRECTORY;
+ }
+
+ ret = _app2sd_apply_mmc_smack(pkgid, dir_list, pkgid);
+ if (ret) {
+ app2ext_print("App2Sd Error : unable to apply app smack\n");
+ return APP2EXT_ERROR_MOVE;
+ }
+
+ /*Restore archive ends */
+ /*Re-mount the loopback encrypted pseudo device on application installation path as with Read Only permission */
+ ret = _app2sd_unmount_app_content(pkgid);
+ if (ret) {
+ return APP2EXT_ERROR_REMOUNT;
+ }
+ ret =
+ _app2sd_remove_loopback_encryption_setup(pkgid);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : unable to detach loopback setup for %s\n",
+ pkgid);
+ return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
+ }
+ return APP2EXT_SUCCESS;
+}
+
+int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
+{
+ int ret = APP2EXT_SUCCESS;
+ mode_t mode = DIR_PERMS;
+ char path[FILENAME_MAX] = { 0, };
+ char app_mmc_path[FILENAME_MAX] = { 0, };
+ char app_path[FILENAME_MAX] = { 0, };
+ char mmc_path[FILENAME_MAX] = { 0, };
+ char app_archive_path[FILENAME_MAX] = { 0, };
+ char *device_node = NULL;
+ FILE *fp = NULL;
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+
+ snprintf(app_mmc_path, FILENAME_MAX,
+ "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
+ snprintf(app_path, FILENAME_MAX, "%s%s/", APP_INSTALLATION_PATH,
+ pkgid);
+ snprintf(app_archive_path, FILENAME_MAX,
+ "%s%s/.archive", APP_INSTALLATION_PATH, pkgid);
+ snprintf(mmc_path, FILENAME_MAX,
+ "%s%s", APP2SD_PATH, pkgid);
+
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+
+ /*check whether application is in external memory or not */
+ fp = fopen(mmc_path, "r+");
+ if (fp == NULL) {
+ app2ext_print
+ ("Application %s is not installed on SD Card\n",
+ pkgid);
+ return APP2EXT_ERROR_FILE_ABSENT;
+ } else {
+ fclose(fp);
+ fp = NULL;
+ }
+
+ /*Get the associated device node for SD card applicationer */
+ device_node =
+ _app2sd_find_associated_device_node(pkgid);
+ if (NULL == device_node) {
+ /*Do loopback setup */
+ device_node =
+ _app2sd_do_loopback_encryption_setup
+ (pkgid);
+ if (device_node == NULL) {
+ app2ext_print
+ ("App2Sd Error : loopback encryption setup failed\n");
+ return APP2EXT_ERROR_DO_LOSETUP;
+ }
+ /*Do mounting */
+ ret =
+ _app2sd_mount_app_content(pkgid,
+ device_node,
+ MOUNT_TYPE_RW,
+ dir_list,
+ APP2SD_MOVE_APP_TO_PHONE);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : Re-mount failed\n");
+ return APP2EXT_ERROR_MOUNT_PATH;
+ }
+ } else {
+ /*Do re-mounting */
+ ret =
+ _app2sd_mount_app_content(pkgid,
+ device_node,
+ MOUNT_TYPE_RW_REMOUNT,
+ dir_list,
+ APP2SD_MOVE_APP_TO_PHONE);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : Re-mount failed\n");
+ return APP2EXT_ERROR_MOUNT_PATH;
+ }
+ }
+ ret = mkdir(app_archive_path, mode);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : unable to create directory%s\n",
+ app_archive_path);
+// return APP2EXT_ERROR_CREATE_DIRECTORY;
+ }
+
+
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name
+ && dir_detail->type == APP2EXT_DIR_RO) {
+ /*Archiving code */
+ memset((void *)&path, '\0',
+ FILENAME_MAX);
+ snprintf(path, FILENAME_MAX,
+ "%s%s/.mmc/%s", APP_INSTALLATION_PATH,
+ pkgid,
+ dir_detail->name);
+ ret =
+ _app2sd_copy_dir
+ (path,
+ app_archive_path);
+ if (ret) {
+ if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+ app2ext_print
+ ("App2Sd Error : unable to access %s\n",
+ path);
+ } else {
+ app2ext_print
+ ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
+ path,
+ app_archive_path,
+ strerror
+ (errno));
+// return APP2EXT_ERROR_MOVE;
+ }
+ }
+
+ /*Delete the symbolic link files [bin, lib, res]*/
+ memset((void *)&path, '\0',
+ FILENAME_MAX);
+ snprintf(path, FILENAME_MAX,
+ "%s%s/%s", APP_INSTALLATION_PATH,
+ pkgid,
+ dir_detail->name);
+ ret = unlink(path);
+ if (ret) {
+ if (errno == ENOENT) {
+ app2ext_print
+ ("App2Sd Error : Directory %s does not exist\n",
+ path);
+ } else {
+ app2ext_print
+ ("App2Sd Error : unable to remove the symbolic link file %s, it is already unlinked!!!\n",
+ path);
+// return APP2EXT_ERROR_DELETE_LINK_FILE;
+ }
+ }
+
+ /*Copy content to destination */
+ memset((void *)&path, '\0',
+ FILENAME_MAX);
+ snprintf(path, FILENAME_MAX,
+ "%s%s/.archive/%s", APP_INSTALLATION_PATH,
+ pkgid,
+ dir_detail->name);
+ ret =
+ _app2sd_copy_dir
+ (path, app_path);
+ if (ret) {
+ if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+ app2ext_print
+ ("App2Sd Error : unable to access %s\n",
+ path);
+ } else {
+ app2ext_print
+ ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
+ path,
+ app_path,
+ strerror
+ (errno));
+// return APP2EXT_ERROR_MOVE;
+ }
+ }
+ }
+ list = g_list_next(list);
+ }
+
+ ret = _app2sd_unmount_app_content(pkgid);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : unable to unmount SD directory for app %s\n",
+ pkgid);
+ return APP2EXT_ERROR_UNMOUNT;
+ }
+ ret =
+ _app2sd_remove_loopback_encryption_setup(pkgid);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : unable to detach loopback setup for %s\n",
+ pkgid);
+ return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
+ }
+ ret = _app2sd_delete_loopback_device(pkgid);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : unable to delete the loopback device for %s\n",
+ pkgid);
+ return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+ }
+ ret = _app2sd_delete_directory(app_mmc_path);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : unable to delete %s \n",
+ app_mmc_path);
+// return APP2EXT_ERROR_DELETE_DIRECTORY;
+ }
+ ret = _app2sd_delete_directory(app_archive_path);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : unable to delete %s \n",
+ app_archive_path);
+// return APP2EXT_ERROR_DELETE_DIRECTORY;
+ }
+
+ ret = _app2sd_apply_app_smack(pkgid, dir_list, pkgid);
+ if (ret) {
+ app2ext_print("App2Sd Error : unable to apply app smack\n");
+ return APP2EXT_ERROR_MOVE;
+ }
+
+ return APP2EXT_SUCCESS;
+}
+
+int _app2sd_move_app(const char *pkgid, app2ext_move_type move_cmd, GList* dir_list)
+{
+ int ret = APP2EXT_SUCCESS;
+
+ /*Check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status();
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : MMC not preset OR Not ready %d\n",
+ ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+
+ switch (move_cmd) {
+ case APP2EXT_MOVE_TO_EXT:
+ {
+ ret = _app2sd_move_app_to_external(pkgid, dir_list);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : move app to external memory failed %d\n",
+ ret);
+ return ret;
+ }
+ break;
+ }
+ case APP2EXT_MOVE_TO_PHONE:
+ {
+ ret = _app2sd_move_app_to_internal(pkgid, dir_list);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : move app to internal memory failed %d\n",
+ ret);
+ return ret;
+ }
+ break;
+ }
+ default:
+ {
+ app2ext_print("App2Sd Error : invalid argument\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+ }
+
+ return ret;
+
+}
+
+int _app2sd_copy_ro_content(const char *src, const char *dest, GList* dir_list)
+{
+ char path[FILENAME_MAX] = { 0, };
+ int ret = APP2EXT_SUCCESS;
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name
+ && dir_detail->type == APP2EXT_DIR_RO) {
+ memset((void *)&path, '\0',
+ FILENAME_MAX);
+ snprintf(path, FILENAME_MAX,
+ "%s/%s", src,
+ dir_detail->name);
+ ret =
+ _app2sd_copy_dir
+ (path,
+ dest);
+ if (ret) {
+ if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+ app2ext_print
+ ("App2Sd Error : unable to access %s\n",
+ path);
+ } else {
+ app2ext_print
+ ("App2Sd Error : unable to copy from %s to %s .....errno is %d\n",
+ path,
+ dest,
+ errno);
+ return
+ APP2EXT_ERROR_MOVE;
+ }
+ }
+ }
+ list = g_list_next(list);
+ }
+
+ return APP2EXT_SUCCESS;
+}
+
+int _app2sd_duplicate_device(const char *pkgid, GList* dir_list, char *dev_node, int size)
+{
+ int ret = 0;
+ char temp_pkgid[FILENAME_MAX] = { 0, };
+ char *devi = NULL;
+ int err_res = 0;
+ char *result = NULL;
+
+ /*Create a new loopback device */
+ snprintf(temp_pkgid, FILENAME_MAX,
+ "%s.new", pkgid);
+ ret = _app2sd_create_loopback_device(temp_pkgid, (size+PKG_BUF_SIZE));
+ if (ret) {
+ app2ext_print("App2Sd Error : Package already present\n");
+ return ret;
+ }
+ app2ext_print("App2Sd : _app2sd_create_loopback_device SUCCESS\n");
+ /*Perform Loopback encryption setup */
+ dev_node = _app2sd_do_loopback_duplicate_encryption_setup(pkgid, temp_pkgid);
+ if (!dev_node) {
+ app2ext_print("App2Sd Error : losetup failed, device node is %s\n", dev_node);
+ _app2sd_delete_loopback_device(pkgid);
+ app2ext_print("App2Sd Error : create ext filesystem failed\n");
+ return APP2EXT_ERROR_DO_LOSETUP;
+ }
+ app2ext_print("App2Sd : _app2sd_do_loopback_duplicate_encryption_setup SUCCESS\n");
+ /*Check whether loopback device is associated with device node or not */
+ devi = _app2sd_find_associated_device_node(temp_pkgid);
+ if (devi == NULL) {
+ app2ext_print("App2Sd Error : finding associated device node failed\n");
+ err_res = APP2EXT_ERROR_DO_LOSETUP;
+ goto FINISH_OFF;
+ }
+ app2ext_print("App2Sd : _app2sd_find_associated_device_node SUCCESS\n");
+ /*Format the loopback file system */
+ ret = _app2sd_create_file_system(dev_node);
+ if (ret) {
+ app2ext_print("App2Sd Error : creating FS failed failed\n");
+ err_res = APP2EXT_ERROR_CREATE_FS;
+ goto FINISH_OFF;
+ }
+ app2ext_print("App2Sd : _app2sd_create_file_system SUCCESS\n");
+ /*Do mounting for new dev*/
+ ret =
+ _app2sd_mount_app_content(temp_pkgid, dev_node, MOUNT_TYPE_RW,
+ dir_list, APP2SD_PRE_UPGRADE);
+ if (ret) {
+ app2ext_print("App2Sd Error : Re-mount failed\n");
+ err_res = APP2EXT_ERROR_MOUNT_PATH;
+ goto FINISH_OFF;
+ }
+ if (devi) {
+ free(devi);
+ devi = NULL;
+ }
+ return APP2EXT_SUCCESS;
+
+FINISH_OFF:
+ if (dev_node) {
+ result = _app2sd_detach_loop_device(dev_node);
+ if (result) {
+ free(result);
+ result = NULL;
+ }
+ _app2sd_delete_loopback_device(pkgid);
+ free(dev_node);
+ dev_node = NULL;
+ }
+
+ if (devi) {
+ free(devi);
+ devi = NULL;
+ }
+ return err_res;
+}
+
+int _app2sd_update_loopback_device_size(const char *pkgid,
+ int size, GList* dir_list)
+{
+ int ret = 0;
+ char *device_node = NULL;
+ char *old_device_node = NULL;
+ int err_res = 0;
+ char app_mmc_path[FILENAME_MAX] = { 0, };
+ char app_archive_path[FILENAME_MAX] = { 0, };
+ char temp_pkgid[FILENAME_MAX] = { 0, };
+ char app_path[FILENAME_MAX] = { 0, };
+
+ snprintf(temp_pkgid, FILENAME_MAX,
+ "%s.new", pkgid);
+
+ ret = _app2sd_duplicate_device(pkgid, dir_list, device_node, size);
+ if (ret) {
+ app2ext_print("App2Sd Error : Creating duplicate device failed\n");
+ return ret;
+ }
+
+ app2ext_print("App2Sd : _app2sd_mount_app_content SUCCESS\n");
+ /*check app entry is there in sd card or not. */
+ snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+ pkgid);
+
+ /*Get the associated device node for SD card applicatione */
+ old_device_node = _app2sd_find_associated_device_node(pkgid);
+ if (NULL == old_device_node) {
+ /*Do loopback setup */
+ old_device_node = _app2sd_do_loopback_encryption_setup(pkgid);
+ if (old_device_node == NULL) {
+ app2ext_print
+ ("App2Sd Error : loopback encryption setup failed\n");
+ err_res = APP2EXT_ERROR_DO_LOSETUP;
+ goto FINISH_OFF;
+ }
+ /*Do mounting */
+ ret =
+ _app2sd_mount_app_content(pkgid, old_device_node,
+ MOUNT_TYPE_RW, dir_list,
+ APP2SD_PRE_UPGRADE);
+ if (ret) {
+ app2ext_print("App2Sd Error : Re-mount failed\n");
+ err_res = APP2EXT_ERROR_MOUNT_PATH;
+// goto FINISH_OFF;
+ }
+ } else {
+ /*Do re-mounting */
+ ret =
+ _app2sd_mount_app_content(pkgid, old_device_node,
+ MOUNT_TYPE_RW_REMOUNT, dir_list,
+ APP2SD_PRE_UPGRADE);
+ if (ret) {
+ app2ext_print("App2Sd Error : Re-mount failed\n");
+ err_res = APP2EXT_ERROR_MOUNT_PATH;
+// goto FINISH_OFF;
+ }
+ }
+
+ snprintf(app_mmc_path, FILENAME_MAX,
+ "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
+ snprintf(app_archive_path, FILENAME_MAX,
+ "%s%s/.mmc", APP_INSTALLATION_PATH, temp_pkgid);
+
+ ret = _app2sd_copy_ro_content(app_mmc_path, app_archive_path, dir_list);
+ if (ret) {
+ app2ext_print("App2Sd Error : copy ro content failed\n");
+ err_res = ret;
+// goto FINISH_OFF;
+ }
+
+ ret = _app2sd_unmount_app_content(pkgid);
+ if (ret) {
+ app2ext_print
+ ("App2SD Error: Unable to unmount the SD application\n");
+ err_res = APP2EXT_ERROR_UNMOUNT;
+// goto FINISH_OFF;
+ }
+ ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+ if (ret) {
+ app2ext_print("App2SD Error: Unable to remove loopback setup\n");
+ err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+// goto FINISH_OFF;
+ }
+ ret = _app2sd_unmount_app_content(temp_pkgid);
+ if (ret) {
+ app2ext_print
+ ("App2SD Error: Unable to unmount the SD application\n");
+ err_res = APP2EXT_ERROR_UNMOUNT;
+ goto FINISH_OFF;
+ }
+ ret = _app2sd_remove_loopback_encryption_setup(temp_pkgid);
+ if (ret) {
+ app2ext_print("App2SD Error: Unable to remove loopback setup\n");
+ err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+ goto FINISH_OFF;
+ }
+ snprintf(app_archive_path, FILENAME_MAX,
+ "%s%s", APP2SD_PATH, temp_pkgid);
+ ret = _app2sd_delete_directory(app_path);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : unable to delete %s \n",
+ app_path);
+ err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
+ goto FINISH_OFF;
+ }
+ ret = _app2sd_rename_dir(app_archive_path, app_path);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : unable to rename %s \n",
+ app_archive_path);
+ err_res = APP2EXT_ERROR_MOVE;
+ goto FINISH_OFF;
+ }
+ snprintf(app_path, FILENAME_MAX,
+ "%s%s", APP_INSTALLATION_PATH, temp_pkgid);
+ ret = _app2sd_delete_directory(app_path);
+ if (ret) {
+ app2ext_print
+ ("App2Sd Error : unable to delete %s \n",
+ app_path);
+ err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
+ goto FINISH_OFF;
+ }
+ return APP2EXT_SUCCESS;
+
+FINISH_OFF:
+ if (old_device_node) {
+ free(old_device_node);
+ old_device_node = NULL;
+ }
+
+ ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+ if (ret) {
+ app2ext_print("App2SD Error: Unable to remove loopback setup\n");
+ err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+ }
+ return err_res;
+}
+
+void _app2sd_make_result_info_file(char *pkgid, int size)
+{
+ int ret = 0;
+ FILE* file = NULL;
+ int fd = 0;
+ char buf[FILENAME_MAX] = {0};
+ const char* app_info_label = "*";
+ char info_file[FILENAME_MAX] = {'\0', };
+
+ if(pkgid == NULL)
+ return;
+
+ snprintf(info_file, FILENAME_MAX, "/tmp/%s", pkgid);
+ app2ext_print("App2SD info : File path = %s\n", info_file);
+
+ file = fopen(info_file, "w");
+ if (file == NULL) {
+ app2ext_print("App2SD Error: Couldn't open the file %s \n", info_file);
+ return;
+ }
+
+ snprintf(buf, 128, "%d\n", size);
+ fwrite(buf, 1, strlen(buf), file);
+
+ fflush(file);
+ fd = fileno(file);
+ fsync(fd);
+ fclose(file);
+
+ if(lsetxattr(info_file, "security.SMACK64", app_info_label, strlen(app_info_label), 0)) {
+ app2ext_print("App2SD Error: error(%d) in setting smack label",errno);
+ }
+ ret = chmod(info_file, 0777);
+ if (ret == -1) {
+ return;
+ }
+
+ ret = chown(info_file, 5000, 5000);
+ if (ret == -1) {
+ return;
+ }
+}
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ * Jyotsna Dhumale <jyotsna.a@samsung.com>
+ * Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <app2sd_internals.h>
+#include <app2sd_interface.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <dlog.h>
+#include <time.h>
+#include <db-util.h>
+#define MAX_QUERY_LEN 4096
+#define PASSWORD_LENGTH 64
+/*
+########### Internal APIs ##################
+ */
+
+/*sqlite db code*/
+#define APP2SD_DB_FILE "/opt/dbspace/.app2sd.db"
+sqlite3 *app2sd_db;
+#define QUERY_CREATE_TABLE_APP2SD "create table app2sd \
+ (pkgid text primary key,\
+ password text\
+ )"
+
+/*
+ *@_app2sd_initialize_db
+ *This function is to initialize sqlite db.
+ * return: On success, it will return zero else if fail then return val<0.
+ */
+int _app2sd_initialize_db()
+{
+ char *error_message = NULL;
+ int ret;
+ FILE * fp = NULL;
+ fp = fopen(APP2SD_DB_FILE, "r");
+ if (fp != NULL) {
+ fclose(fp);
+ ret =
+ db_util_open(APP2SD_DB_FILE, &app2sd_db,
+ DB_UTIL_REGISTER_HOOK_METHOD);
+
+ if (ret != SQLITE_OK) {
+ app2ext_print("====>>>> connect menu_db [%s] failed!\n",
+ APP2SD_DB_FILE);
+ return -1;
+ }
+ return 0;
+ }
+
+ ret =
+ db_util_open(APP2SD_DB_FILE, &app2sd_db,
+ DB_UTIL_REGISTER_HOOK_METHOD);
+
+ if (ret != SQLITE_OK) {
+ app2ext_print("====>>>> connect menu_db [%s] failed!\n",
+ APP2SD_DB_FILE);
+ return -1;
+ }
+
+ if (SQLITE_OK !=
+ sqlite3_exec(app2sd_db, QUERY_CREATE_TABLE_APP2SD,
+ NULL, NULL, &error_message)) {
+ app2ext_print("Don't execute query = %s, "
+ "error message = %s\n",
+ QUERY_CREATE_TABLE_APP2SD, error_message);
+ return -1;
+ }
+
+ app2ext_print("\n db_initialize_done ");
+ return 0;
+}
+
+/*
+ *@_app2sd_set_password_in_db
+ *This function is to store password into db.
+ * param[in]: pkgid: package id
+ * param[in]: password: password string
+ * return: On success, it will return 0.
+ * Else appropriate error will be returned.
+ */
+int _app2sd_set_password_in_db(const char *pkgid,
+ const char *passwd)
+{
+ char *error_message = NULL;
+
+ char *query = sqlite3_mprintf("insert into app2sd(pkgid,password) values (%Q, %Q)", pkgid, passwd);
+
+ if (SQLITE_OK != sqlite3_exec(app2sd_db, query, NULL, NULL,
+ &error_message)) {
+ app2ext_print("Don't execute query = %s, error message = %s\n",
+ query, error_message);
+
+ sqlite3_free(query);
+ return APP2EXT_ERROR_SQLITE_REGISTRY;
+ }
+ sqlite3_free(query);
+ app2ext_print("\n sqlite insertion done ");
+ return APP2EXT_SUCCESS;
+}
+
+/*
+ *@_app2sd_remove_password_from_db
+ *This function is to remove passwod from db.
+ * param[in]: pkgid: package id
+ * return: On success, it will return 0.
+ * Else appropriate error will be returned.
+ */
+int _app2sd_remove_password_from_db(const char *pkgid)
+{
+ char *error_message = NULL;
+
+ char *query = sqlite3_mprintf("delete from app2sd where pkgid LIKE %Q", pkgid);
+ app2ext_print("\n deletion querys is %s ", query);
+
+ if (SQLITE_OK != sqlite3_exec(app2sd_db, query, NULL,
+ NULL, &error_message)) {
+ app2ext_print("Don't execute query = %s, error message = %s\n",
+ query, error_message);
+ sqlite3_free(query);
+ return APP2EXT_ERROR_SQLITE_REGISTRY;
+ }
+
+ sqlite3_free(query);
+ app2ext_print("\n app2sd password deletion done ");
+ return APP2EXT_SUCCESS;
+
+}
+
+/*
+ *@_app2sd_get_password_from_db
+ *This function is to retrive password from DB
+ * param[in]: pkgid: package id
+ * return: On success, it will return the password, else NULL.
+ */
+char *_app2sd_get_password_from_db(const char *pkgid)
+{
+ char query[MAX_QUERY_LEN] = { 0 };
+ sqlite3_stmt *stmt = NULL;
+ const char *tail = NULL;
+ int rc = 0;
+ char *passwd = NULL;
+
+ sqlite3_snprintf(MAX_QUERY_LEN, query,
+ "select * from app2sd where pkgid LIKE '%s'", pkgid);
+ app2ext_print("\n access querys is %s ", query);
+
+ if (SQLITE_OK != sqlite3_prepare(app2sd_db, query,
+ strlen(query), &stmt, &tail)) {
+ app2ext_print("sqlite3_prepare error\n");
+ return NULL;
+ }
+
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_ROW || rc == SQLITE_DONE) {
+ app2ext_print("No records found");
+ goto FINISH_OFF;
+ }
+ passwd = malloc(PASSWORD_LENGTH + 1);
+ if (passwd == NULL) {
+ app2ext_print("memory allocation failed\n");
+ goto FINISH_OFF;
+ }
+
+ app2ext_print("\n entry available in sqlite");
+ strncpy(passwd, (const char*)sqlite3_column_text(stmt, 1),
+ PASSWORD_LENGTH);
+ if (passwd == NULL) {
+ app2ext_print("\n password is NULL ");
+ goto FINISH_OFF;
+ }
+ app2ext_print("\n passwd is %s ", passwd);
+ if (SQLITE_OK != sqlite3_finalize(stmt)) {
+ app2ext_print("error : sqlite3_finalize\n");
+ goto FINISH_OFF;
+ }
+ return passwd;
+
+FINISH_OFF:
+ rc = sqlite3_finalize(stmt);
+ if (rc != SQLITE_OK) {
+ app2ext_print(" sqlite3_finalize failed - %d", rc);
+ }
+ if (passwd)
+ free(passwd);
+ return NULL;
+}
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ * Jyotsna Dhumale <jyotsna.a@samsung.com>
+ * Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <app2sd_internals.h>
+#include <app2sd_interface.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <dlog.h>
+#include <sys/statvfs.h>
+#include <errno.h>
+
+#define PASSWD_LEN 8
+#define ASCII_PASSWD_CHAR 93
+
+/*
+########### Internal APIs ##################
+ */
+
+/*Note: Don't use any printf statement inside this function*/
+/*This function is similar to Linux's "system()" for executing a process.*/
+int _xsystem(const char *argv[])
+{
+ int status = 0;
+ pid_t pid;
+ pid = fork();
+ switch (pid) {
+ case -1:
+ perror("fork failed");
+ return -1;
+ case 0:
+ /* child */
+ if (execvp(argv[0], (char *const *)argv) < 0) {
+ fprintf(stderr, "execvp failed %d....%s\n", errno, strerror(errno)); /*Don't use d_msg_app2sd */
+ }
+ _exit(-1);
+ default:
+ /* parent */
+ break;
+ }
+ if (waitpid(pid, &status, 0) == -1) {
+ perror("waitpid failed");
+ return -1;
+ }
+ if (WIFSIGNALED(status)) {
+ perror("signal");
+ return -1;
+ }
+ if (!WIFEXITED(status)) {
+ /* shouldn't happen */
+ perror("should not happen");
+ return -1;
+ }
+ return WEXITSTATUS(status);
+}
+
+
+/*
+* @_app2sd_check_mmc_status
+* This function checks and returns MMC status
+*/
+int _app2sd_check_mmc_status(void)
+{
+ FILE *fp1 = NULL;
+ char line[512];
+ fp1 = fopen("/etc/mtab", "r");
+ if (fp1 == NULL) {
+ fprintf(stderr, "failed to open file\n");
+ app2ext_print("failed to open file /etc/mtab\n");
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+ while (fgets(line, 512, fp1) != NULL) {
+ if (strstr(line, MMC_PATH) != NULL) {
+ fclose(fp1);
+ return APP2EXT_SUCCESS;
+ }
+ }
+ fclose(fp1);
+ return APP2EXT_ERROR_MMC_STATUS;
+}
+
+/*
+ * @_app2sd_get_available_free_memory
+ * This function returns the available free memory in the SD Card.
+ * param [in]: sd_path: This is sd card access path.
+ * param [out]: free_mem: Result will be available in this.
+ * User has to pass valid memory address.
+ * return: On success, it will return 0.
+ * Else, appropriate error no will be returned.
+ */
+int _app2sd_get_available_free_memory(const char *sd_path, int *free_mem)
+{
+ struct statvfs buf;
+ int ret = 0;
+ if (sd_path == NULL || free_mem == NULL) {
+ app2ext_print("App2Sd Error : Invalid input parameter\n");
+ return -1;
+ }
+ memset((void *)&buf, '\0', sizeof(struct statvfs));
+ ret = statvfs(sd_path, &buf);
+ if (ret) {
+ app2ext_print
+ ("App2SD Error: Unable to get SD Card memory information\n");
+ return APP2EXT_ERROR_MMC_INFORMATION;
+ }
+ *free_mem = ((buf.f_bfree * buf.f_bsize) / 1024) / 1024;
+ return 0;
+}
+
+int _app2sd_delete_directory(char *dirname)
+{
+ DIR *dp = NULL;
+ struct dirent *ep = NULL;
+ char abs_filename[FILENAME_MAX] = { 0, };
+ int ret = 0;
+ dp = opendir(dirname);
+ if (dp != NULL) {
+ while ((ep = readdir(dp)) != NULL) {
+ struct stat stFileInfo;
+
+ snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
+ ep->d_name);
+
+ if (lstat(abs_filename, &stFileInfo) < 0) {
+ perror(abs_filename);
+ (void)closedir(dp);
+ return -1;
+ }
+
+ if (S_ISDIR(stFileInfo.st_mode)) {
+ if (strcmp(ep->d_name, ".")
+ && strcmp(ep->d_name, "..")) {
+ ret = _app2sd_delete_directory(abs_filename);
+ if (ret <0) {
+ (void)closedir(dp);
+ return -1;
+ }
+ }
+ } else {
+ ret = remove(abs_filename);
+ if (ret <0) {
+ (void)closedir(dp);
+ return -1;
+ }
+ }
+ }
+ (void)closedir(dp);
+ ret = remove(dirname);
+ if (ret <0)
+ return -1;
+ } else {
+ app2ext_print("Couldn't open the directory[%s]\n", dirname);
+ }
+ return 0;
+}
+
+void _app2sd_delete_symlink(const char *dirname)
+{
+ int ret = 0;
+ DIR *dp = NULL;
+ struct dirent *ep = NULL;
+ char abs_filename[FILENAME_MAX] = { 0, };
+
+ app2ext_print("star clean_symlink [%s]", dirname);
+
+ dp = opendir(dirname);
+ if (dp != NULL) {
+ while ((ep = readdir(dp)) != NULL) {
+ struct stat stFileInfo;
+ char mmc_path[PATH_MAX] = {0};
+
+ if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, ".."))
+ continue;
+
+ /*get realpath find symlink to ".mmc" and unlink it*/
+ snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname, ep->d_name);
+ realpath(abs_filename, mmc_path);
+
+ if (strstr(mmc_path,".mmc")) {
+ app2ext_print("force unlink [%s]", abs_filename);
+ if (unlink(abs_filename)) {
+ if (errno == ENOENT) {
+ app2ext_print("Unable to access file %s\n", abs_filename);
+ } else {
+ app2ext_print("Unable to delete %s\n", abs_filename);
+ }
+ }
+ }
+
+ }
+ (void)closedir(dp);
+
+ /*delete ".mmc" folder*/
+ snprintf(abs_filename, FILENAME_MAX, "%s/.mmc", dirname);
+ ret = remove(abs_filename);
+ if (ret == -1) {
+ return;
+ }
+ } else {
+ app2ext_print("Couldn't open the directory[%s]\n", dirname);
+ }
+
+ app2ext_print("finish clean_symlink");
+}
+
+int _app2sd_copy_dir(const char *src, const char *dest)
+{
+ int ret = APP2EXT_SUCCESS;
+ const char *argv_bin[] = { "/bin/cp", "-raf", src, dest, NULL };
+ ret = _xsystem(argv_bin);
+ if (ret) {
+ app2ext_print("copy fail\n");
+ return APP2EXT_ERROR_MOVE;
+ }
+ return ret;
+}
+
+int _app2sd_rename_dir(const char *old_name, const char *new_name)
+{
+ int ret = APP2EXT_SUCCESS;
+ const char *argv_bin[] = { "/bin/mv", old_name, new_name, NULL };
+ ret = _xsystem(argv_bin);
+ if (ret) {
+ app2ext_print("mv/rename fail\n");
+ return APP2EXT_ERROR_MOVE;
+ }
+ return ret;
+}
+
+unsigned long long _app2sd_calculate_dir_size(char *dirname)
+{
+ static unsigned long long total = 0;
+ DIR *dp = NULL;
+ struct dirent *ep = NULL;
+ char abs_filename[FILENAME_MAX] = { 0, };;
+ dp = opendir(dirname);
+ if (dp != NULL) {
+ while ((ep = readdir(dp)) != NULL) {
+ struct stat stFileInfo;
+
+ snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
+ ep->d_name);
+
+ if (stat(abs_filename, &stFileInfo) < 0)
+ perror(abs_filename);
+ else {
+ total += stFileInfo.st_size;
+
+ if (S_ISDIR(stFileInfo.st_mode)) {
+ if (strcmp(ep->d_name, ".")
+ && strcmp(ep->d_name, "..")) {
+ _app2sd_calculate_dir_size
+ (abs_filename);
+ }
+ } else {
+ /*Do Nothing */
+ }
+ }
+ }
+ (void)closedir(dp);
+ } else {
+ app2ext_print("\n error in opening directory ");
+ }
+ return total;
+}
+
+unsigned long long _app2sd_calculate_file_size(const char *filename)
+{
+ struct stat stFileInfo;
+ app2ext_print("\n Calculating file size for %s\n", filename);
+
+ if (stat(filename, &stFileInfo) < 0) {
+ perror(filename);
+ return 0;
+ } else
+ return stFileInfo.st_size;
+}
+
+/*Note: Don't use any printf statement inside this function*/
+char *_app2sd_encrypt_device(const char *device, const char *pkgid,
+ char *passwd)
+{
+ const char *argv[] =
+ { "/sbin/losetup", "-e", "aes", device, pkgid, "-k", passwd, NULL };
+ pid_t pid = 0;
+ int my_pipe[2] = { 0, };
+ char buf[FILENAME_MAX] = { 0, };
+ char *ret_result = NULL;
+ int result = 0;
+ if (pipe(my_pipe) < 0) {
+ fprintf(stderr, "Unable to create pipe\n");
+ return NULL;
+ }
+ pid = fork();
+ switch (pid) {
+ case -1:
+ perror("fork failed");
+ return NULL;
+ case 0:
+ /* child */
+ close(1);
+ close(2);
+ result = dup(my_pipe[1]);
+ if (result < 0) {
+ fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+ close(result);
+ _exit(-1);
+ }
+ result = dup(my_pipe[1]);
+ if (result < 0) {
+ fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+ close(result);
+ _exit(-1);
+ }
+ if (execvp(argv[0], (char *const *)argv) < 0) {
+ fprintf(stderr, "execvp failed %d....%s\n", errno, strerror(errno)); /*Don't use d_msg_app2sd */
+ }
+ _exit(-1);
+ default:
+ /* parent */
+ close(my_pipe[1]);
+ result = read(my_pipe[0], buf, FILENAME_MAX);
+ if (result < 0)
+ fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
+ break;
+ }
+
+ ret_result = (char *)malloc(strlen(buf) + 1);
+ if (ret_result == NULL) {
+ app2ext_print("Malloc failed!\n");
+ return NULL;
+ }
+ memset(ret_result, '\0', strlen(buf) + 1);
+ memcpy(ret_result, buf, strlen(buf));
+ return ret_result;
+}
+
+/*Note: Don't use any printf statement inside this function*/
+char *_app2sd_detach_loop_device(const char *device)
+{
+ const char *argv[] = { "/sbin/losetup", "-d", device, NULL };
+ pid_t pid;
+ int my_pipe[2] = { 0, };
+ char buf[FILENAME_MAX] = { 0, };
+ char *ret_result = NULL;
+ int result = 0;
+ if (pipe(my_pipe) < 0) {
+ fprintf(stderr, "Unable to create pipe\n");
+ return NULL;
+ }
+ pid = fork();
+ switch (pid) {
+ case -1:
+ perror("fork failed");
+ return NULL;
+ case 0:
+ /* child */
+ close(1);
+ close(2);
+ result = dup(my_pipe[1]);
+ if (result < 0) {
+ fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+ close(result);
+ _exit(-1);
+ }
+ result = dup(my_pipe[1]);
+ if (result < 0) {
+ fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+ close(result);
+ _exit(-1);
+ }
+ if (execvp(argv[0], (char *const *)argv) < 0) {
+ fprintf(stderr, "execvp failed\n"); /*Don't use d_msg_app2sd */
+ }
+ _exit(-1);
+ default:
+ /* parent */
+ close(my_pipe[1]);
+ result = read(my_pipe[0], buf, FILENAME_MAX);
+ if (result < 0)
+ fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
+ break;
+ }
+
+ ret_result = (char *)malloc(strlen(buf) + 1);
+ if (ret_result == NULL) {
+ app2ext_print("Malloc failed!\n");
+ return NULL;
+ }
+ memset(ret_result, '\0', strlen(buf) + 1);
+ memcpy(ret_result, buf, strlen(buf));
+
+ return ret_result;
+}
+
+/*Note: Don't use any printf statement inside this function*/
+char *_app2sd_find_associated_device(const char *mmc_app_path)
+{
+ const char *argv[] = { "/sbin/losetup", "-j", mmc_app_path, NULL };
+ pid_t pid;
+ int my_pipe[2] = { 0, };
+ char buf[FILENAME_MAX] = { 0, };
+ char *ret_result = NULL;
+ int result = 0;
+ if (pipe(my_pipe) < 0) {
+ fprintf(stderr, "Unable to create pipe\n");
+ return NULL;
+ }
+ pid = fork();
+ switch (pid) {
+ case -1:
+ perror("fork failed");
+ return NULL;
+ case 0:
+ /* child */
+ close(1);
+ close(2);
+ result = dup(my_pipe[1]);
+ if (result < 0) {
+ fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+ close(result);
+ _exit(-1);
+ }
+ result = dup(my_pipe[1]);
+ if (result < 0) {
+ fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+ close(result);
+ _exit(-1);
+ }
+ if (execvp(argv[0], (char *const *)argv) < 0) {
+ fprintf(stderr, "execvp failed\n"); /*Don't use d_msg_app2sd */
+ }
+ _exit(-1);
+ default:
+ /* parent */
+ close(my_pipe[1]);
+ result = read(my_pipe[0], buf, FILENAME_MAX);
+ if (result < 0)
+ fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
+ break;
+ }
+
+ ret_result = (char *)malloc(strlen(buf) + 1);
+ if (ret_result == NULL) {
+ app2ext_print("Malloc failed!\n");
+ return NULL;
+ }
+ memset(ret_result, '\0', strlen(buf) + 1);
+ memcpy(ret_result, buf, strlen(buf));
+
+ return ret_result;
+}
+
+/*Note: Don't use any printf statement inside this function*/
+char *_app2sd_find_free_device(void)
+{
+ const char *argv[] = { "/sbin/losetup", "-f", NULL };
+ pid_t pid;
+ int my_pipe[2] = { 0, };
+ char buf[FILENAME_MAX+1] = { 0, };
+ char *ret_result = NULL;
+ int result = 0;
+ if (pipe(my_pipe) < 0) {
+ fprintf(stderr, "Unable to create pipe\n");
+ return NULL;
+ }
+ pid = fork();
+ switch (pid) {
+ case -1:
+ perror("fork failed");
+ return NULL;
+ case 0:
+ /* child */
+ close(1);
+ close(2);
+ result = dup(my_pipe[1]);
+ if (result < 0) {
+ fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+ close(result);
+ _exit(-1);
+ }
+ result = dup(my_pipe[1]);
+ if (result < 0) {
+ fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+ close(result);
+ _exit(-1);
+ }
+ if (execvp(argv[0], (char *const *)argv) < 0) {
+ fprintf(stderr, "execvp failed\n"); /*Don't use d_msg_app2sd */
+ }
+ _exit(-1);
+ default:
+ /* parent */
+ close(my_pipe[1]);
+ result = read(my_pipe[0], buf, FILENAME_MAX);
+ if (result < 0)
+ fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
+ break;
+ }
+
+ ret_result = (char *)malloc(strlen(buf) + 1);
+ if (ret_result == NULL) {
+ app2ext_print("Malloc failed!\n");
+ return NULL;
+ }
+ memset(ret_result, '\0', strlen(buf) + 1);
+ memcpy(ret_result, buf, strlen(buf));
+
+ return ret_result;
+}
+
+/*@_app2sd_generate_password
+* This is a simple password generator
+* return: On success, it will return the password, else NULL.
+*/
+char *_app2sd_generate_password(const char *pkgid)
+{
+ char passwd[PASSWD_LEN+1] = { 0, };
+ char *ret_result = NULL;
+ char set[ASCII_PASSWD_CHAR+1] = "!\"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
+ unsigned char char_1;
+ unsigned char char_2;
+ int i = 0;
+ int appname_len = strlen(pkgid);
+ int j = appname_len;
+
+ /* Length of the password */
+ ret_result = (char*)malloc(PASSWD_LEN+1);
+ if (NULL == ret_result) {
+ app2ext_print("Unable to Allocate memory\n");
+ return NULL;
+ }
+ memset((void *)ret_result, '\0', PASSWD_LEN+1);
+
+ while(i < PASSWD_LEN) {
+ char_1 = (rand()+pkgid[j--])%ASCII_PASSWD_CHAR;
+ char_2 = rand()%ASCII_PASSWD_CHAR;
+ passwd[i] = set[char_1];
+ passwd[i+1] = set[(pkgid[j--])*2];
+ if (i<PASSWD_LEN-3)
+ passwd[i+2] = set[char_2];
+ i++;
+ }
+
+ app2ext_print("Password is %s\n", passwd);
+ memcpy(ret_result, passwd, PASSWD_LEN+1);
+ return ret_result;
+}
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <app2ext_interface.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <dirent.h>
+
+#define APP2EXT_SD_PLUGIN_PATH LIBPREFIX "/libapp2sd.so"
+
+app2ext_handle *app2ext_init(int storage_type)
+{
+ /*Validate the function parameter recieved */
+ if (storage_type < APP2EXT_INTERNAL_MEM ||
+ storage_type > APP2EXT_CLOUD) {
+ app2ext_print("App2Ext Error : Invalid function arguments\n");
+ return NULL;
+ }
+ if (storage_type != APP2EXT_SD_CARD ) {
+ app2ext_print("App2Ext Error : Storage type currently not supported\n");
+ return NULL;
+ }
+
+ /* allocate memory for app2ext handle*/
+ app2ext_handle *handle = (app2ext_handle *)calloc(1, sizeof(app2ext_handle));
+ if (handle == NULL) {
+ app2ext_print("App2Ext Error : Memory allocation failure\n");
+ return NULL;
+ }
+ void *dl_handle = NULL;
+ int (*dl_on_load)(app2ext_interface *)=NULL;
+
+ /* Load SD plugin*/
+ handle->type = APP2EXT_SD_CARD;
+ dl_handle = dlopen(APP2EXT_SD_PLUGIN_PATH, RTLD_LAZY|RTLD_GLOBAL);
+ if (NULL == dl_handle)
+ {
+ app2ext_print("App2Ext Error : dlopen(%s) failed.\n", APP2EXT_SD_PLUGIN_PATH);
+ free(handle);
+ return NULL;
+ }
+ handle->plugin_handle = dl_handle;
+ dl_on_load = dlsym(dl_handle, "app2ext_on_load");
+ if (NULL == dl_on_load)
+ {
+ app2ext_print("App2Ext Error : Cannot find app2ext_on_load symbol in %s.", APP2EXT_SD_PLUGIN_PATH);
+ dlclose(dl_handle);
+ free(handle);
+ return NULL;
+ }
+
+ /*Initialize the SD plugin*/
+ if(!dl_on_load(&(handle->interface)))
+ {
+ app2ext_print("App2Ext Error : [%s] app2ext_on_load() failed.", APP2EXT_SD_PLUGIN_PATH);
+ dlclose(dl_handle);
+ free(handle);
+ return NULL;
+ }
+
+ app2ext_print("App2Ext: %s plugin loaded\n", APP2EXT_SD_PLUGIN_PATH);
+
+ return handle;
+}
+
+int app2ext_deinit(app2ext_handle *handle)
+{
+ /*Validate the function parameter recieved */
+ if (handle == NULL || handle->plugin_handle == NULL){
+ app2ext_print("App2Ext Error : Invalid function arguments\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+
+ /* Close the plugin handle*/
+ dlclose(handle->plugin_handle);
+
+ /* Free allocated memory during installtion*/
+ free(handle);
+ return APP2EXT_SUCCESS;
+}
+
+int app2ext_get_app_location(const char *appname)
+{
+ /*Validate the function parameter received */
+ if (appname == NULL) {
+ app2ext_print("invalid func parameters\n");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+ FILE *fp = NULL;
+ char app_mmc_path[FILENAME_MAX] = { 0, };
+ char app_dir_path[FILENAME_MAX] = { 0, };
+ char app_mmc_internal_path[FILENAME_MAX] = { 0, };
+ snprintf(app_dir_path, FILENAME_MAX,
+ "%s%s", APP_INSTALLATION_PATH, appname);
+ snprintf(app_mmc_path, FILENAME_MAX,
+ "%s%s", APP2SD_PATH, appname);
+ snprintf(app_mmc_internal_path, FILENAME_MAX,
+ "%s%s/.mmc", APP_INSTALLATION_PATH, appname);
+
+
+ /*check whether application is in external memory or not */
+ fp = fopen(app_mmc_path, "r");
+ if (fp != NULL) {
+ fclose(fp);
+ fp = NULL;
+ return APP2EXT_SD_CARD;
+ }
+
+ /*check whether application is in internal or not */
+ fp = fopen(app_dir_path, "r");
+ if (fp == NULL) {
+ return APP2EXT_NOT_INSTALLED;
+ } else {
+ fclose(fp);
+ /*check whether the application is installed in SD card
+ but SD card is not present*/
+ fp = fopen(app_mmc_internal_path, "r");
+ if (fp == NULL) {
+ return APP2EXT_INTERNAL_MEM;
+ } else {
+ fclose(fp);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+ }
+}
+
+int app2ext_enable_external_pkg(const char *pkgid)
+{
+ /*Validate the function parameter received */
+ if (pkgid == NULL) {
+ app2ext_print("invalid func parameters\n");
+ return -1;
+ }
+ FILE *fp = NULL;
+ app2ext_handle *app2_handle = NULL;
+ char app_mmc_path[FILENAME_MAX] = { 0, };
+ snprintf(app_mmc_path, FILENAME_MAX, "%s%s", APP2SD_PATH, pkgid);
+
+ /*check whether application is in external memory or not */
+ fp = fopen(app_mmc_path, "r");
+ if (fp != NULL) {
+ fclose(fp);
+ fp = NULL;
+
+ app2_handle = app2ext_init(APP2EXT_SD_CARD);
+ if (app2_handle == NULL) {
+ app2ext_print("app2_handle : app2ext init failed\n");
+ return -2;
+ }
+
+ app2_handle->interface.enable(pkgid);
+ app2ext_deinit(app2_handle);
+ app2ext_print("App2Ext enable_external_pkg [%s]\n", pkgid);
+ }
+ return 0;
+}
+
+int app2ext_disable_external_pkg(const char *pkgid)
+{
+ /*Validate the function parameter received */
+ if (pkgid == NULL) {
+ app2ext_print("invalid func parameters\n");
+ return -1;
+ }
+ FILE *fp = NULL;
+ app2ext_handle *app2_handle = NULL;
+ char app_mmc_path[FILENAME_MAX] = { 0, };
+ snprintf(app_mmc_path, FILENAME_MAX, "%s%s", APP2SD_PATH, pkgid);
+
+ /*check whether application is in external memory or not */
+ fp = fopen(app_mmc_path, "r");
+ if (fp != NULL) {
+ fclose(fp);
+ fp = NULL;
+
+ app2_handle = app2ext_init(APP2EXT_SD_CARD);
+ if (app2_handle == NULL) {
+ app2ext_print("app2_handle : app2ext init failed\n");
+ return -2;
+ }
+
+ app2_handle->interface.disable(pkgid);
+ app2ext_deinit(app2_handle);
+ app2ext_print("App2Ext disable_external_pkg [%s]\n", pkgid);
+ }
+ return 0;
+}
+
+int app2ext_enable_external_dir(void)
+{
+ int ret = 0;
+ DIR *dir = NULL;
+ char buf[FILENAME_MAX] = { 0, };
+ struct dirent entry, *result;
+
+ dir = opendir(APP2SD_PATH);
+ if (!dir) {
+ if (strerror_r(errno, buf, sizeof(buf)) == 0)
+ app2ext_print("App2Ext Error :Failed to access the because %s", buf);
+ return -1;
+ }
+
+ for (ret = readdir_r(dir, &entry, &result); ret == 0 && result != NULL; ret = readdir_r(dir, &entry, &result)) {
+ ret = app2ext_enable_external_pkg(entry.d_name);
+ if (ret != 0)
+ app2ext_print("App2Ext Error : fail enable pkg[%s]\n", entry.d_name);
+ }
+
+ closedir(dir);
+ return 0;
+}
+
+int app2ext_disable_external_dir(void)
+{
+ int ret = 0;
+ DIR *dir = NULL;
+ char buf[FILENAME_MAX] = { 0, };
+ struct dirent entry, *result;
+
+ dir = opendir(APP2SD_PATH);
+ if (!dir) {
+ if (strerror_r(errno, buf, sizeof(buf)) == 0)
+ app2ext_print("App2Ext Error :Failed to access the because %s", buf);
+ return -1;
+ }
+
+ for (ret = readdir_r(dir, &entry, &result); ret == 0 && result != NULL; ret = readdir_r(dir, &entry, &result)) {
+ ret = app2ext_disable_external_pkg(entry.d_name);
+ if (ret != 0)
+ app2ext_print("App2Ext Error : fail disable pkg[%s]\n", entry.d_name);
+ }
+
+ closedir(dir);
+ return 0;
+}
+
+int app2ext_force_clean_pkg(const char *pkgid)
+{
+ /*Validate the function parameter received */
+ if (pkgid == NULL) {
+ app2ext_print("invalid func parameters\n");
+ return 0;
+ }
+
+ FILE *fp = NULL;
+ app2ext_handle *app2_handle = NULL;
+ char app_mmc_path[FILENAME_MAX] = { 0, };
+ snprintf(app_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
+
+ fp = fopen(app_mmc_path, "r");
+ if (fp == NULL) {
+ return 0;
+ } else {
+ fclose(fp);
+ }
+
+ app2_handle = app2ext_init(APP2EXT_SD_CARD);
+ if (app2_handle == NULL) {
+ app2ext_print("app2_handle : app2ext init failed\n");
+ return 0;
+ }
+
+ app2_handle->interface.force_clean(pkgid);
+ app2ext_deinit(app2_handle);
+ app2ext_print("App2Ext force_clean_pkg [%s]\n", pkgid);
+ return 0;
+}
+
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(TCapp2ext C)
+
+SET(SOURCE_DIR ${CMAKE_SOURCE_DIR})
+
+SET(SRCS
+ ${SOURCE_DIR}/TC_app2ext.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED app2sd aul)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g -Wall -Wextra -fPIE")
+SET(CMAKE_C_FLAGS_RELEASE "-O3 -fPIE")
+
+ADD_EXECUTABLE(TCapp2ext ${SRCS})
+TARGET_LINK_LIBRARIES(TCapp2ext ${pkgs_LDFLAGS} "-pie")
+
+INSTALL(TARGETS TCapp2ext DESTINATION /usr/bin COMPONENT Runtime)
+
--- /dev/null
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <app2ext_interface.h>
+
+#define SUCCESS 0
+#define FAIL 1
+#define CMD_LEN 256
+
+app2ext_handle *handle = NULL;
+
+#define PKGNAME_INSTALL "com.samsung.calculator-0.1.6-5.armv7l.rpm"
+#define PKGNAME_UPGRADE "com.samsung.calculator-0.1.7-5.armv7l.rpm"
+#define PKGNAME_INSTALL_RPM "com.samsung.calculator"
+
+char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
+
+char error_list[45][100] = {
+ "SUCCESS",
+ "APP2EXT_ERROR_UNKNOW",
+ "APP2EXT_ERROR_INVALID_ARGUMENTS",
+ "APP2EXT_ERROR_MOVE",
+ "APP2EXT_ERROR_PRE_UNINSTALL",
+ "APP2EXT_ERROR_MMC_STATUS",
+ "APP2EXT_ERROR_DB_INITIALIZE",
+ "APP2EXT_ERROR_SQLITE_REGISTRY",
+ "APP2EXT_ERROR_PASSWD_GENERATION",
+ "APP2EXT_ERROR_MMC_INFORMATION",
+ "APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY",
+ "APP2EXT_ERROR_DELETE_DIRECTORY",
+ "APP2EXT_ERROR_CREATE_SYMLINK",
+ "APP2EXT_ERROR_CREATE_DIRECTORY",
+ "APP2EXT_ERROR_DELETE_LINK_FILE",
+ "APP2EXT_ERROR_PKG_EXISTS",
+ "APP2EXT_ERROR_ACCESS_FILE",
+ "APP2EXT_ERROR_OPEN_DIR",
+ "APP2EXT_ERROR_ALREADY_FILE_PRESENT",
+ "APP2EXT_ERROR_FILE_ABSENT",
+ "APP2EXT_ERROR_STRCMP_FAILED",
+ "APP2EXT_ERROR_INVALID_PACKAGE",
+ "APP2EXT_ERROR_CREATE_DIR_ENTRY",
+ "APP2EXT_ERROR_PASSWORD_GENERATION",
+ "APP2EXT_ERROR_COPY_DIRECTORY",
+ "APP2EXT_ERROR_INVALID_CASE",
+ "APP2EXT_ERROR_SYMLINK_ALREADY_EXISTS",
+ "APP2EXT_ERROR_APPEND_HASH_TO_FILE",
+ "APP2EXT_ERROR_CREATE_DEVICE",
+ "APP2EXT_ERROR_DO_LOSETUP",
+ "APP2EXT_ERROR_CREATE_FS",
+ "APP2EXT_ERROR_MOUNT_PATH",
+ "APP2EXT_ERROR_CLEANUP",
+ "APP2EXT_ERROR_MOUNT",
+ "APP2EXT_ERROR_REMOUNT",
+ "APP2EXT_ERROR_PIPE_CREATION",
+ "APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE",
+ "APP2EXT_ERROR_VCONF_REGISTRY",
+ "APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE",
+ "APP2EXT_ERROR_UNMOUNT",
+ "APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE",
+ "APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE",
+ "APP2EXT_ERROR_ALREADY_MOUNTED",
+ "APP2EXT_ERROR_PLUGIN_INIT_FAILED",
+ "APP2EXT_ERROR_PLUGIN_DEINIT_FAILED"
+};
+
+static int __get_integer_input_data(void);
+
+static char *__get_string_input_data(void);
+
+static int __get_integer_input_data(void)
+{
+ char input_str[32] = { 0, };
+ int data = 0;
+
+ if (fgets(input_str, 32, stdin) == NULL) {
+ printf("Input buffer overflow....\n");
+ return -1;
+ }
+
+ if (sscanf(input_str, "%4d", &data) != 1) {
+ printf("Input only integer option....\n");
+ return -1;
+ }
+
+ return data;
+}
+
+static void Usage(void)
+{
+ printf("\n*********************************************\n");
+ printf("\n Test Suite Usage \n");
+ printf("\n Test_id test_case\n");
+ printf("\n 1 TC_app_install (Pre-install,Install, Post-install, OnDemand init, App Launch, OnDemand Exit)\n");
+ printf("\n 2 TC_app_uninstall (Pre-uninstall, Uninstall, Post-uninstall)\n");
+ printf("\n 3 TC_app_upgrade (Pre-upgrade, Upgrade, Post-Upgrade)\n");
+ printf("\n 4 TC_app_move\n");
+ printf("\n 5 TC_app_get_location\n");
+ printf("\n 6 Exit\n");
+}
+
+GList * populate_dir_details()
+{
+ GList *dir_list = NULL;
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ int i;
+
+
+ for (i=0; i<3; i++) {
+ dir_detail = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
+ if (dir_detail == NULL) {
+ printf("\nMemory allocation failed\n");
+ goto FINISH_OFF;
+ }
+ dir_detail->name = (char*) calloc(1, sizeof(char)*(strlen(pkg_ro_content_rpm[i])+2));
+ if (dir_detail->name == NULL) {
+ printf("\nMemory allocation failed\n");
+ free(dir_detail);
+ goto FINISH_OFF;
+ }
+ snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i])+1), "%s", pkg_ro_content_rpm[i]);
+ dir_detail->type = APP2EXT_DIR_RO;
+ dir_list = g_list_append(dir_list, dir_detail);
+ }
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ list = g_list_next(list);
+ }
+ }
+ return dir_list;
+FINISH_OFF:
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+ return NULL;
+}
+
+void clear_dir_list(GList* dir_list)
+{
+ GList *list = NULL;
+ app2ext_dir_details* dir_detail = NULL;
+ if (dir_list) {
+ list = g_list_first(dir_list);
+ while (list) {
+ dir_detail = (app2ext_dir_details *)list->data;
+ if (dir_detail && dir_detail->name) {
+ free(dir_detail->name);
+ }
+ list = g_list_next(list);
+ }
+ g_list_free(dir_list);
+ }
+}
+
+int TC_app_install()
+{
+ printf("TC_app_install %s \n", PKGNAME_INSTALL_RPM);
+ GList *dir_list = NULL;
+
+ int ret = -1;
+ char cmd_install[CMD_LEN+1];
+ snprintf(cmd_install, CMD_LEN,"rpm -i %s", PKGNAME_INSTALL);
+
+ dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ printf("\nError in populating the directory list\n");
+ return -1;
+ }
+ ret = handle->interface.pre_install(PKGNAME_INSTALL_RPM, dir_list, 20);
+ if (ret) {
+ printf("\n TC : pre app install API fail. Reason %s", error_list[ret]);
+ clear_dir_list(dir_list);
+ return -1;
+ }
+
+ printf("\n cmd_install is %s ", cmd_install);
+ ret = system(cmd_install);
+ if (ret) {
+
+ printf("\n TC : rpm install command fail %d ", ret);
+ ret = handle->interface.post_install(PKGNAME_INSTALL_RPM, 1);
+ if (ret) {
+ printf("\n TC : post app install API fail Reason %s", error_list[ret]);
+ }
+ clear_dir_list(dir_list);
+ return -1;
+ }
+
+ ret = handle->interface.post_install(PKGNAME_INSTALL_RPM, 2);
+ if (ret) {
+ printf("\n TC : post app install API fail Reason %s", error_list[ret]);
+ clear_dir_list(dir_list);
+ return -1;
+ }
+
+ ret = handle->interface.enable(PKGNAME_INSTALL_RPM);
+ if (ret) {
+ printf("\n TC : app enable API fail Reason %s", error_list[ret]);
+ clear_dir_list(dir_list);
+ return -1;
+ }
+ printf("\nLaunching application after install");
+ ret = aul_open_app(PKGNAME_INSTALL_RPM);
+
+ if (ret < 0)
+ printf("\n launch fail");
+ else
+ printf("\n application launched");
+
+ sleep(5);
+
+ ret = system("killall -9 calculator");
+ if (ret < 0)
+ printf("\n app exit fail");
+ else
+ printf("\n application exited");
+
+ sleep(5);
+
+ ret = handle->interface.disable(PKGNAME_INSTALL_RPM);
+ if (ret < 0 || ret > 44) {
+ printf("Unknown error\n");
+ } else {
+ printf("Returned Result: %s\n", error_list[ret]);
+ }
+ clear_dir_list(dir_list);
+ return ret;
+}
+
+int TC_app_uninstall()
+{
+ printf("TC_app_uninstall %s \n", PKGNAME_INSTALL_RPM);
+ int ret = -1;
+ char cmd_uninstall[CMD_LEN+1];
+ snprintf(cmd_uninstall, CMD_LEN, "rpm -e %s", PKGNAME_INSTALL_RPM);
+
+ ret = handle->interface.pre_uninstall(PKGNAME_INSTALL_RPM);
+ if (ret) {
+ printf("\n TC : pre app uninstall API fail. Reason %s", error_list[ret]);
+ return -1;
+ }
+
+ printf("\n cmd_uninstall is %s ", cmd_uninstall);
+ ret = system(cmd_uninstall);
+ if (ret) {
+ printf("\n TC : rpm uninstall command fail Reason %s", error_list[ret]);
+ return -1;
+ }
+
+ ret = handle->interface.post_uninstall(PKGNAME_INSTALL_RPM);
+ if (ret) {
+ printf("\n TC : post app uninstall API fail Reason %s", error_list[ret]);
+ return -1;
+ }
+
+ return ret;
+}
+
+int TC_app_upgrade()
+{
+ printf("TC_app_uninstall %s \n", PKGNAME_INSTALL_RPM);
+ int ret = -1;
+ char cmd_uninstall[CMD_LEN+1];
+ snprintf(cmd_uninstall, CMD_LEN, "rpm -U %s", PKGNAME_UPGRADE);
+ GList *dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ printf("\nError in populating the directory list\n");
+ return -1;
+ }
+
+ ret = handle->interface.pre_upgrade(PKGNAME_INSTALL_RPM, dir_list, 40);
+ if (ret) {
+ printf("\n TC : pre app upgrade API fail. Reason %s", error_list[ret]);
+ clear_dir_list(dir_list);
+ return -1;
+ }
+
+ printf("\n cmd_uninstall is %s ", cmd_uninstall);
+ ret = system(cmd_uninstall);
+ if (ret) {
+ printf("\n TC : rpm upgrade command fail Reason %s", error_list[ret]);
+ ret = handle->interface.post_upgrade(PKGNAME_INSTALL_RPM, 1);
+ if (ret) {
+ printf("\n TC : post app upgrade API fail Reason %s", error_list[ret]);
+ }
+ clear_dir_list(dir_list);
+ return -1;
+ }
+
+ ret = handle->interface.post_upgrade(PKGNAME_INSTALL_RPM, 2);
+ if (ret) {
+ printf("\n TC : post app upgrade API fail Reason %s", error_list[ret]);
+ clear_dir_list(dir_list);
+ return -1;
+ }
+ clear_dir_list(dir_list);
+ return ret;
+}
+
+int TC_app_move()
+{
+ printf("TC_app_move %s \n", PKGNAME_INSTALL_RPM);
+ int ret = -1;
+ int ret_check = -1;
+ GList *dir_list = populate_dir_details();
+ if (dir_list == NULL) {
+ printf("\nError in populating the directory list\n");
+ return -1;
+ }
+
+ ret = app2ext_get_app_location(PKGNAME_INSTALL_RPM);
+ if (ret == APP2EXT_SD_CARD) {
+ printf("\n app %s is in sd card ", PKGNAME_INSTALL_RPM);
+ printf("\n app %s will be moved to internal memory ",
+ PKGNAME_INSTALL_RPM);
+ ret = handle->interface.move(PKGNAME_INSTALL_RPM, dir_list, APP2EXT_MOVE_TO_PHONE);
+ if (ret) {
+ printf("\n TC: move API failed Reason %s", error_list[ret]);
+ clear_dir_list(dir_list);
+ return -1;
+ }
+ ret = app2ext_get_app_location(PKGNAME_INSTALL_RPM);
+ if (ret_check == APP2EXT_INTERNAL_MEM)
+ printf("\n app %s is moved to internal memory ",
+ PKGNAME_INSTALL_RPM);
+ } else if (ret == APP2EXT_INTERNAL_MEM) {
+ printf("\n app %s is in internal memory ", PKGNAME_INSTALL_RPM);
+ printf("\n app %s will be moved to sd card", PKGNAME_INSTALL_RPM);
+
+ ret = handle->interface.move(PKGNAME_INSTALL_RPM, dir_list, APP2EXT_MOVE_TO_EXT);
+ if (ret) {
+ printf("\n TC: move API failed Reason %s", error_list[ret]);
+ clear_dir_list(dir_list);
+ return -1;
+ }
+ ret = app2ext_get_app_location(PKGNAME_INSTALL_RPM);
+ if (ret_check == APP2EXT_SD_CARD)
+ printf("\n app %s is moved to sd card ",
+ PKGNAME_INSTALL_RPM);
+ } else {
+ ret = APP2EXT_ERROR_INVALID_PACKAGE;
+ printf("\n errorReason %s", error_list[ret]);
+ clear_dir_list(dir_list);
+ return ret;
+ }
+ clear_dir_list(dir_list);
+ return ret;
+}
+
+void TC_app_get_location()
+{
+ printf("TC_app_get_location %s \n", PKGNAME_INSTALL_RPM);
+ int ret = -1;
+
+ ret = app2ext_get_app_location(PKGNAME_INSTALL_RPM);
+ if (ret == APP2EXT_SD_CARD) {
+ printf("\n app %s is in sd card ", PKGNAME_INSTALL_RPM);
+ } else if (ret == APP2EXT_INTERNAL_MEM) {
+ printf("\n app %s is in internal memory ", PKGNAME_INSTALL_RPM);
+ } else {
+ printf("\napp %s is not installed", PKGNAME_INSTALL_RPM);
+ }
+}
+
+void TC_enable_external_dir()
+{
+ printf("TC_enable_external_dir\n");
+ int ret = -1;
+
+ ret = app2ext_enable_external_dir();
+ if (ret == 0) {
+ printf("\n app2ext_enable_external_dir() success");
+ } else {
+ printf("\n app2ext_enable_external_dir() failed");
+ }
+}
+
+void TC_disable_external_dir()
+{
+ printf("TC_disable_external_dir\n");
+ int ret = -1;
+
+ ret = app2ext_disable_external_dir();
+ if (ret == 0) {
+ printf("\n app2ext_disable_external_dir() success");
+ } else {
+ printf("\n app2ext_disable_external_dir() failed");
+ }
+}
+
+int main(int argc, char **argv)
+{
+ printf("\nEnter plug-in type: 1. App2SD 2. App2mUSB 3.App2CLOUD\n");
+ int plugin = __get_integer_input_data();
+ int ret = 0;
+ if (plugin !=1) {
+ printf("Plug-in type currently not supported");
+ return -1;
+ }
+ handle = app2ext_init(APP2EXT_SD_CARD);
+ if (handle == NULL) {
+ ret = APP2EXT_ERROR_PLUGIN_INIT_FAILED;
+ printf("app2ext_init. Reason:%s\n", error_list[ret]);
+ return -1;
+ }
+ do {
+ Usage();
+ printf("Enter Option for testing\n");
+ int option = __get_integer_input_data();
+ switch (option) {
+ case 1:
+ {
+ TC_app_install();
+ break;
+ }
+ case 2:
+ {
+ TC_app_uninstall();
+ break;
+ }
+ case 3:
+ {
+ TC_app_upgrade();
+ break;
+ }
+ case 4:
+ {
+ TC_app_move();
+ break;
+ }
+ case 5:
+ {
+ TC_app_get_location();
+ break;
+ }
+ case 6:
+ {
+ TC_enable_external_dir();
+ break;
+ }
+ case 7:
+ {
+ TC_disable_external_dir();
+ break;
+ }
+ case 8: {
+ app2ext_deinit(handle);
+ return 0;
+ }
+ default:
+ {
+ printf("\nInvalid test id\n");
+ break;
+ }
+ }
+ } while(1);
+ app2ext_deinit(handle);
+ return 0;
+}
--- /dev/null
+Name: TCapp2ext
+Summary: Test suite for APP2EXT
+Version: 0.5
+Release: 1
+Group: TO_BE/FILLED_IN
+License: Apache2.0
+Source0: %{name}-%{version}.tar.gz
+
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+BuildRequires: pkgconfig(app2sd)
+BuildRequires: pkgconfig(aul)
+BuildRequires: cmake
+
+%description
+Test suite for App2Ext
+
+%prep
+%setup -q
+
+%build
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+%{_bindir}/TCapp2ext
+
+
+