tizen 2.3.1 release tizen_2.3.1 submit/tizen_2.3.1/20150915.080138 tizen_2.3.1_release
authorjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 13:13:44 +0000 (22:13 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 13:13:44 +0000 (22:13 +0900)
55 files changed:
AUTHORS [new file with mode: 0755]
CMakeLists.txt [new file with mode: 0755]
LICENSE [new file with mode: 0644]
TC/build.sh [new file with mode: 0755]
TC/com.samsung.calculator-0.1.36-1.armv7l.rpm [new file with mode: 0755]
TC/execute.sh [new file with mode: 0755]
TC/tet_code [new file with mode: 0755]
TC/tet_scen [new file with mode: 0755]
TC/tetbuild.cfg [new file with mode: 0755]
TC/tetclean.cfg [new file with mode: 0755]
TC/tetexec.cfg [new file with mode: 0755]
TC/unit/Makefile [new file with mode: 0755]
TC/unit/tc_gen.sh [new file with mode: 0755]
TC/unit/tslist [new file with mode: 0755]
TC/unit/utc_ApplicationFW_app2ext_deinit_func.c [new file with mode: 0755]
TC/unit/utc_ApplicationFW_app2ext_get_app_location_func.c [new file with mode: 0755]
TC/unit/utc_ApplicationFW_app2ext_init_func.c [new file with mode: 0755]
TC/unit/utc_ApplicationFW_app2ext_move_func.c [new file with mode: 0755]
TC/unit/utc_ApplicationFW_app2ext_post_install_func.c [new file with mode: 0755]
TC/unit/utc_ApplicationFW_app2ext_post_uninstall_func.c [new file with mode: 0755]
TC/unit/utc_ApplicationFW_app2ext_post_upgrade_func.c [new file with mode: 0755]
TC/unit/utc_ApplicationFW_app2ext_pre_install_func.c [new file with mode: 0755]
TC/unit/utc_ApplicationFW_app2ext_pre_uninstall_func.c [new file with mode: 0755]
TC/unit/utc_ApplicationFW_app2ext_pre_upgrade_func.c [new file with mode: 0755]
TC/unit/utc_MODULE_API_func.c.in [new file with mode: 0755]
app2sd.manifest [new file with mode: 0755]
app2sd.manifest.in [new file with mode: 0755]
app2sd.pc.in [new file with mode: 0755]
debian/app2sd-dev.install.in [new file with mode: 0644]
debian/app2sd.install.in [new file with mode: 0644]
debian/changelog [new file with mode: 0755]
debian/compat [new file with mode: 0755]
debian/control [new file with mode: 0755]
debian/copyright [new file with mode: 0755]
debian/dirs [new file with mode: 0755]
debian/rules [new file with mode: 0755]
doc/images/SLP_app2ext_PG_image01.png [new file with mode: 0755]
doc/images/app2ext_diag.png [new file with mode: 0755]
doc/images/app2ext_install_diag.png [new file with mode: 0755]
doc/images/app2ext_uninstall_diag.png [new file with mode: 0755]
inc/SLP_app2ext_PG.h [new file with mode: 0755]
inc/app2ext_interface.h [new file with mode: 0755]
packaging/app2sd.spec [new file with mode: 0755]
plugin/app2sd/CMakeLists.txt [new file with mode: 0755]
plugin/app2sd/inc/SLP_app2sd_PG.h [new file with mode: 0755]
plugin/app2sd/inc/app2sd_interface.h [new file with mode: 0755]
plugin/app2sd/inc/app2sd_internals.h [new file with mode: 0755]
plugin/app2sd/src/app2sd_interface.c [new file with mode: 0755]
plugin/app2sd/src/app2sd_internals.c [new file with mode: 0755]
plugin/app2sd/src/app2sd_internals_registry.c [new file with mode: 0755]
plugin/app2sd/src/app2sd_internals_utils.c [new file with mode: 0755]
src/app2ext_interface.c [new file with mode: 0755]
test/CMakeLists.txt [new file with mode: 0755]
test/TC_app2ext.c [new file with mode: 0755]
test/TCapp2ext.spec [new file with mode: 0755]

diff --git a/AUTHORS b/AUTHORS
new file mode 100755 (executable)
index 0000000..ead8dbd
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Garima Shrivastava<garima.s@samsung.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..6882b47
--- /dev/null
@@ -0,0 +1,57 @@
+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)
+
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..9c13a9b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,204 @@
+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
diff --git a/TC/build.sh b/TC/build.sh
new file mode 100755 (executable)
index 0000000..e838751
--- /dev/null
@@ -0,0 +1,20 @@
+#!/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
diff --git a/TC/com.samsung.calculator-0.1.36-1.armv7l.rpm b/TC/com.samsung.calculator-0.1.36-1.armv7l.rpm
new file mode 100755 (executable)
index 0000000..d14c9c9
Binary files /dev/null and b/TC/com.samsung.calculator-0.1.36-1.armv7l.rpm differ
diff --git a/TC/execute.sh b/TC/execute.sh
new file mode 100755 (executable)
index 0000000..e2c742e
--- /dev/null
@@ -0,0 +1,19 @@
+#!/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
diff --git a/TC/tet_code b/TC/tet_code
new file mode 100755 (executable)
index 0000000..a2cf6c1
--- /dev/null
@@ -0,0 +1,12 @@
+# 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"
diff --git a/TC/tet_scen b/TC/tet_scen
new file mode 100755 (executable)
index 0000000..43cbc9b
--- /dev/null
@@ -0,0 +1,7 @@
+all
+       ^TEST
+##### Scenarios for TEST #####
+
+# Test scenario
+TEST
+       :include:/unit/tslist
diff --git a/TC/tetbuild.cfg b/TC/tetbuild.cfg
new file mode 100755 (executable)
index 0000000..6192c78
--- /dev/null
@@ -0,0 +1,3 @@
+TET_OUTPUT_CAPTURE=False
+TET_BUILD_TOOL=make
+TET_PASS_TC_NAME=True
diff --git a/TC/tetclean.cfg b/TC/tetclean.cfg
new file mode 100755 (executable)
index 0000000..c66eda4
--- /dev/null
@@ -0,0 +1,2 @@
+TET_OUTPUT_CAPTURE=False
+TET_CLEAN_TOOL=make clean
diff --git a/TC/tetexec.cfg b/TC/tetexec.cfg
new file mode 100755 (executable)
index 0000000..0d9d39a
--- /dev/null
@@ -0,0 +1 @@
+TET_OUTPUT_CAPTURE=False
diff --git a/TC/unit/Makefile b/TC/unit/Makefile
new file mode 100755 (executable)
index 0000000..7adf2b5
--- /dev/null
@@ -0,0 +1,31 @@
+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)
diff --git a/TC/unit/tc_gen.sh b/TC/unit/tc_gen.sh
new file mode 100755 (executable)
index 0000000..54f482d
--- /dev/null
@@ -0,0 +1,28 @@
+#!/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"
diff --git a/TC/unit/tslist b/TC/unit/tslist
new file mode 100755 (executable)
index 0000000..029cf23
--- /dev/null
@@ -0,0 +1,10 @@
+/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
diff --git a/TC/unit/utc_ApplicationFW_app2ext_deinit_func.c b/TC/unit/utc_ApplicationFW_app2ext_deinit_func.c
new file mode 100755 (executable)
index 0000000..0542fd2
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * 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);
+}
diff --git a/TC/unit/utc_ApplicationFW_app2ext_get_app_location_func.c b/TC/unit/utc_ApplicationFW_app2ext_get_app_location_func.c
new file mode 100755 (executable)
index 0000000..598f664
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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);
+}
diff --git a/TC/unit/utc_ApplicationFW_app2ext_init_func.c b/TC/unit/utc_ApplicationFW_app2ext_init_func.c
new file mode 100755 (executable)
index 0000000..372b61c
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ *  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);
+}
+
diff --git a/TC/unit/utc_ApplicationFW_app2ext_move_func.c b/TC/unit/utc_ApplicationFW_app2ext_move_func.c
new file mode 100755 (executable)
index 0000000..ae0f334
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * 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);
+}
diff --git a/TC/unit/utc_ApplicationFW_app2ext_post_install_func.c b/TC/unit/utc_ApplicationFW_app2ext_post_install_func.c
new file mode 100755 (executable)
index 0000000..95352c9
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * 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);
+}
diff --git a/TC/unit/utc_ApplicationFW_app2ext_post_uninstall_func.c b/TC/unit/utc_ApplicationFW_app2ext_post_uninstall_func.c
new file mode 100755 (executable)
index 0000000..239cb7f
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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);
+}
diff --git a/TC/unit/utc_ApplicationFW_app2ext_post_upgrade_func.c b/TC/unit/utc_ApplicationFW_app2ext_post_upgrade_func.c
new file mode 100755 (executable)
index 0000000..14469ba
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * 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);
+}
diff --git a/TC/unit/utc_ApplicationFW_app2ext_pre_install_func.c b/TC/unit/utc_ApplicationFW_app2ext_pre_install_func.c
new file mode 100755 (executable)
index 0000000..81e163e
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * 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);
+}
diff --git a/TC/unit/utc_ApplicationFW_app2ext_pre_uninstall_func.c b/TC/unit/utc_ApplicationFW_app2ext_pre_uninstall_func.c
new file mode 100755 (executable)
index 0000000..4f81e46
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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);
+}
diff --git a/TC/unit/utc_ApplicationFW_app2ext_pre_upgrade_func.c b/TC/unit/utc_ApplicationFW_app2ext_pre_upgrade_func.c
new file mode 100755 (executable)
index 0000000..9ac2826
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * 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);
+}
diff --git a/TC/unit/utc_MODULE_API_func.c.in b/TC/unit/utc_MODULE_API_func.c.in
new file mode 100755 (executable)
index 0000000..5edf1b7
--- /dev/null
@@ -0,0 +1,67 @@
+#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);
+}
diff --git a/app2sd.manifest b/app2sd.manifest
new file mode 100755 (executable)
index 0000000..ec5cd53
--- /dev/null
@@ -0,0 +1,15 @@
+<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>
diff --git a/app2sd.manifest.in b/app2sd.manifest.in
new file mode 100755 (executable)
index 0000000..85d9892
--- /dev/null
@@ -0,0 +1,15 @@
+<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>
diff --git a/app2sd.pc.in b/app2sd.pc.in
new file mode 100755 (executable)
index 0000000..d2e6ce8
--- /dev/null
@@ -0,0 +1,12 @@
+# 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
diff --git a/debian/app2sd-dev.install.in b/debian/app2sd-dev.install.in
new file mode 100644 (file)
index 0000000..258b9f0
--- /dev/null
@@ -0,0 +1,2 @@
+@PREFIX@/include/app2sd_interface.h
+@PREFIX@/lib/pkgconfig/*.pc
diff --git a/debian/app2sd.install.in b/debian/app2sd.install.in
new file mode 100644 (file)
index 0000000..bf766f0
--- /dev/null
@@ -0,0 +1 @@
+@PREFIX@/lib/*.so*
diff --git a/debian/changelog b/debian/changelog
new file mode 100755 (executable)
index 0000000..0d77b89
--- /dev/null
@@ -0,0 +1,8 @@
+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
+
diff --git a/debian/compat b/debian/compat
new file mode 100755 (executable)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100755 (executable)
index 0000000..7bf93c6
--- /dev/null
@@ -0,0 +1,27 @@
+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
+
diff --git a/debian/copyright b/debian/copyright
new file mode 100755 (executable)
index 0000000..37b94ac
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ *
+ */
diff --git a/debian/dirs b/debian/dirs
new file mode 100755 (executable)
index 0000000..ca882bb
--- /dev/null
@@ -0,0 +1,2 @@
+usr/bin
+usr/sbin
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..f902937
--- /dev/null
@@ -0,0 +1,126 @@
+#!/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
diff --git a/doc/images/SLP_app2ext_PG_image01.png b/doc/images/SLP_app2ext_PG_image01.png
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/doc/images/app2ext_diag.png b/doc/images/app2ext_diag.png
new file mode 100755 (executable)
index 0000000..137eaf3
Binary files /dev/null and b/doc/images/app2ext_diag.png differ
diff --git a/doc/images/app2ext_install_diag.png b/doc/images/app2ext_install_diag.png
new file mode 100755 (executable)
index 0000000..6fd73ee
Binary files /dev/null and b/doc/images/app2ext_install_diag.png differ
diff --git a/doc/images/app2ext_uninstall_diag.png b/doc/images/app2ext_uninstall_diag.png
new file mode 100755 (executable)
index 0000000..2e61c71
Binary files /dev/null and b/doc/images/app2ext_uninstall_diag.png differ
diff --git a/inc/SLP_app2ext_PG.h b/inc/SLP_app2ext_PG.h
new file mode 100755 (executable)
index 0000000..48c0b8a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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>
+
+ * @}
+ */
diff --git a/inc/app2ext_interface.h b/inc/app2ext_interface.h
new file mode 100755 (executable)
index 0000000..4569dd6
--- /dev/null
@@ -0,0 +1,499 @@
+/*
+ * 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
diff --git a/packaging/app2sd.spec b/packaging/app2sd.spec
new file mode 100755 (executable)
index 0000000..1d4db72
--- /dev/null
@@ -0,0 +1,71 @@
+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
+
+
+
diff --git a/plugin/app2sd/CMakeLists.txt b/plugin/app2sd/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..920c369
--- /dev/null
@@ -0,0 +1,45 @@
+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)
+
+
diff --git a/plugin/app2sd/inc/SLP_app2sd_PG.h b/plugin/app2sd/inc/SLP_app2sd_PG.h
new file mode 100755 (executable)
index 0000000..4933bc1
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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>
+
+ * @}
+ */
diff --git a/plugin/app2sd/inc/app2sd_interface.h b/plugin/app2sd/inc/app2sd_interface.h
new file mode 100755 (executable)
index 0000000..a59cb9a
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * 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
diff --git a/plugin/app2sd/inc/app2sd_internals.h b/plugin/app2sd/inc/app2sd_internals.h
new file mode 100755 (executable)
index 0000000..c422d8b
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * 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
diff --git a/plugin/app2sd/src/app2sd_interface.c b/plugin/app2sd/src/app2sd_interface.c
new file mode 100755 (executable)
index 0000000..5961cb9
--- /dev/null
@@ -0,0 +1,860 @@
+/*
+ * 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;
+}
+
diff --git a/plugin/app2sd/src/app2sd_internals.c b/plugin/app2sd/src/app2sd_internals.c
new file mode 100755 (executable)
index 0000000..72efc28
--- /dev/null
@@ -0,0 +1,1541 @@
+/*
+ * 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;
+       }
+}
diff --git a/plugin/app2sd/src/app2sd_internals_registry.c b/plugin/app2sd/src/app2sd_internals_registry.c
new file mode 100755 (executable)
index 0000000..4e6ca4d
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * 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;
+}
diff --git a/plugin/app2sd/src/app2sd_internals_utils.c b/plugin/app2sd/src/app2sd_internals_utils.c
new file mode 100755 (executable)
index 0000000..744f07b
--- /dev/null
@@ -0,0 +1,574 @@
+/*
+ * 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;
+}
diff --git a/src/app2ext_interface.c b/src/app2ext_interface.c
new file mode 100755 (executable)
index 0000000..8f89832
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * 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;
+}
+
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..69e4aec
--- /dev/null
@@ -0,0 +1,27 @@
+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)
+
diff --git a/test/TC_app2ext.c b/test/TC_app2ext.c
new file mode 100755 (executable)
index 0000000..031c018
--- /dev/null
@@ -0,0 +1,497 @@
+/*
+ * 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;
+}
diff --git a/test/TCapp2ext.spec b/test/TCapp2ext.spec
new file mode 100755 (executable)
index 0000000..0b92aab
--- /dev/null
@@ -0,0 +1,39 @@
+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
+
+
+