merge with master
authorJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:12:42 +0000 (01:12 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:12:42 +0000 (01:12 +0900)
28 files changed:
CMakeLists.txt
debian/changelog [deleted file]
debian/compat [deleted file]
debian/control [deleted file]
debian/dirs [deleted file]
debian/libslp-shortcut-0.install.in [deleted file]
debian/libslp-shortcut-dev.install.in [deleted file]
debian/rules [deleted file]
lib/CMakeLists.txt [new file with mode: 0644]
lib/LICENSE [moved from LICENSE with 100% similarity]
lib/include/shortcut.h [moved from include/shortcut.h with 61% similarity]
lib/include/shortcut_PG.h [moved from include/SLP_shortcut_PG.h with 81% similarity]
lib/shortcut.pc.in [moved from shortcut.pc.in with 91% similarity]
lib/src/main.c [new file with mode: 0644]
libshortcut.manifest
packaging/libshortcut.spec
pkgmgr_shortcut/CMakeLists.txt [new file with mode: 0644]
pkgmgr_shortcut/include/dlist.h [new file with mode: 0644]
pkgmgr_shortcut/src/dlist.c [new file with mode: 0644]
pkgmgr_shortcut/src/service_register.c [new file with mode: 0644]
sample.xml [new file with mode: 0644]
src/main.c [deleted file]
src/secom_socket.c [deleted file]
test/Makefile
test/application.c
test/homescreen.c
test/shortcut.c [moved from include/secom_socket.h with 50% similarity]
test_db_builder.sh [new file with mode: 0755]

index c2e1079..ea60a32 100644 (file)
@@ -1,52 +1,6 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(shortcut C)
-
-SET(PREFIX ${CMAKE_INSTALL_PREFIX})
-SET(EXEC_PREFIX "\${prefix}")
-SET(LIBDIR "\${exec_prefix}/lib")
-SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}")
-SET(VERSION_MAJOR 0)
-SET(VERSION "${VERSION_MAJOR}.0.1")
 
 set(CMAKE_SKIP_BUILD_RPATH true)
 
-SET(SRCS src/main.c src/secom_socket.c)
-
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
-
-INCLUDE(FindPkgConfig)
-pkg_check_modules(glib_pkg REQUIRED gobject-2.0)
-pkg_check_modules(pkgs REQUIRED
-       glib-2.0
-       dlog
-)
-
-FOREACH(flag ${pkgs_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}")
-
-#ADD_DEFINITIONS("-Werror")
-#ADD_DEFINITIONS("-Wall")
-#ADD_DEFINITIONS("-Wextra")
-#ADD_DEFINITIONS("-ansi")
-#ADD_DEFINITIONS("-pedantic")
-
-ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
-ADD_DEFINITIONS("-DLOG_TAG=\"${PROJECT_NAME}\"")
-
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
-
-CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
-SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PROJECT_NAME}.pc")
-
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib)
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/shortcut.h DESTINATION include/${PROJECT_NAME})
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/SLP_shortcut_PG.h DESTINATION include/${PROJECT_NAME})
+ADD_SUBDIRECTORY("pkgmgr_shortcut")
+ADD_SUBDIRECTORY("lib")
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644 (file)
index 0bfc7b0..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-libslp-shortcut (0.0.5) unstable; urgency=low
-
-  * Git:165.213.180.234:/slp/pkgs/s/shortcut
-  * Tag: libslp-shortcut_0.0.5
-
- -- Sung-jae Park <nicesj.park@samsung.com>  Mon, 02 Jan 2012 13:15:52 +0900
diff --git a/debian/compat b/debian/compat
deleted file mode 100644 (file)
index 7ed6ff8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-5
diff --git a/debian/control b/debian/control
deleted file mode 100644 (file)
index f8a7fda..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-Source: libslp-shortcut
-Section: libs
-Priority: optional
-Maintainer: Sung-jae Park <nicesj.park@samsung.com>, Young-joo Park <yjoo93.park@samsung.com>
-Build-Depends: debhelper (>= 5), libglib2.0-dev, dlog-dev
-Standards-Version: 3.7.2
-
-Package: libslp-shortcut-0
-Section: libs
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, libglib2.0-0, libdlog-0
-Description: Shortcut service supporting library (shared object)
-
-Package: libslp-shortcut-dev
-Section: libs
-Architecture: any
-Depends: libslp-shortcut-0 (= ${Source-Version})
-Description: Shortcut (Add to home) service supporting library (development)
-XB-Generate-Docs: yes 
-
-Package: libslp-shortcut-dbg
-Section: debug
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, libslp-shortcut-0 (= ${Source-Version})
-Description: Shortcut service supporting library (unstripped)
-
-
-
-
diff --git a/debian/dirs b/debian/dirs
deleted file mode 100644 (file)
index ca882bb..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin
-usr/sbin
diff --git a/debian/libslp-shortcut-0.install.in b/debian/libslp-shortcut-0.install.in
deleted file mode 100644 (file)
index a7c24c5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-@PREFIX@/lib/*.so.*
diff --git a/debian/libslp-shortcut-dev.install.in b/debian/libslp-shortcut-dev.install.in
deleted file mode 100644 (file)
index 4430783..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-@PREFIX@/include/shortcut/shortcut.h
-@PREFIX@/include/shortcut/SLP_shortcut_PG.h
-@PREFIX@/lib/pkgconfig/*.pc
diff --git a/debian/rules b/debian/rules
deleted file mode 100755 (executable)
index 6618431..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/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
-
-CFLAGS ?= -Wall -g
-LDFLAGS ?=
-PREFIX ?= /usr
-DATADIR ?= /opt
-
-BUILDDIR ?= $(CURDIR)/cmake-tmp
-
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
-       CFLAGS += -O0
-else
-       CFLAGS += -O2
-endif
-
-LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed
-
-configure: configure-stamp
-configure-stamp:
-       dh_testdir
-       # Add here commands to configure the package.
-       mkdir -p $(BUILDDIR) && cd $(BUILDDIR) && CFLAGS="$(CFLAGS)" 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 $(BUILDDIR) && $(MAKE)
-       #docbook-to-man debian/wavplayer.sgml > wavplayer.1
-
-       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 build-stamp configure-stamp
-
-       # Add here commands to clean up after the build process.
-       -rm -rf $(BUILDDIR)
-       #rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake Makefile install_manifest.txt
-
-       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/wavplayer.
-       cd $(BUILDDIR) && $(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 --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=libslp-shortcut-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 configure
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0e27e2d
--- /dev/null
@@ -0,0 +1,49 @@
+PROJECT(shortcut C)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/lib/include)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${exec_prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}")
+SET(VERSION_MAJOR 0)
+SET(VERSION "${VERSION_MAJOR}.0.1")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(svc_pkgs REQUIRED
+       dlog
+       sqlite3
+       libxml-2.0
+       glib-2.0
+       db-util
+       com-core
+       vconf
+)
+
+FOREACH(flag ${svc_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -g -Wall -Werror")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+ADD_DEFINITIONS("-DLOG_TAG=\"SHORTCUT\"")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED 
+       src/main.c
+)
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${svc_pkgs_LDFLAGS})
+
+CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
+SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PROJECT_NAME}.pc")
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/lib/include/shortcut.h DESTINATION include/${PROJECT_NAME})
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/lib/include/shortcut_PG.h DESTINATION include/${PROJECT_NAME})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/lib/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/lib/LICENSE DESTINATION /usr/share/license RENAME "lib${PROJECT_NAME}")
+
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
similarity index 100%
rename from LICENSE
rename to lib/LICENSE
similarity index 61%
rename from include/shortcut.h
rename to lib/include/shortcut.h
index b488faf..5edd598 100644 (file)
@@ -1,18 +1,19 @@
 /*
- * Copyright 2012  Samsung Electronics Co., Ltd
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Licensed under the Flora License, Version 1.0 (the "License");
+ * 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.tizenopensource.org/license
+ * 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 __SHORTCUT_H__
 #define __SHORTCUT_H__
@@ -39,7 +40,7 @@ extern "C" {
  * @brief This function prototype is used to define a callback function for the add_to_home reqeust.
  *        The homescreen should define a callback as this type and implementing the service code
  *        for adding a new application shortcut.
- * @param[in] pkgname Shortcut is added for this package.
+ * @param[in] appid Shortcut is added for this package.
  * @param[in] name Name for created shortcut icon.
  * @param[in] type 3 kinds of types are defined.
  * @param[in] content_info Specific information for creating a new shortcut.
@@ -53,7 +54,7 @@ extern "C" {
  * @post None
  * @remarks None
  */
-typedef int (*request_cb_t)(const char *pkgname, const char *name, int type, const char *content_info, const char *icon, int pid, void *data);
+typedef int (*request_cb_t)(const char *appid, const char *name, int type, const char *content_info, const char *icon, int pid, double period, void *data);
 
 /**
  * @brief This function prototype is used to define for receiving the result of add_to_home.
@@ -61,7 +62,7 @@ typedef int (*request_cb_t)(const char *pkgname, const char *name, int type, con
  * @param[in] pid Process ID of who handles this add_to_home request.
  * @param[in] data Callback data.
  * @return int Returns 0, if there is no error or returns errno.
- * @see shortcut_add_to_home()
+ * @see add_to_home_shortcut()
  * @pre None
  * @post None
  * @remarks None
@@ -72,16 +73,36 @@ typedef int (*result_cb_t)(int ret, int pid, void *data);
  * @brief Basically, three types of shortcut is defined.
  *        Every homescreen developer should support these types of shortcut.
  *        Or returns proper errno to figure out why the application failed to add a shortcut.
- *        SHORTCUT_PACKAGE is used for adding a package itself as a shortcut
- *        SHORTCUT_DATA is used for adding a shortcut for "content" data.
- *        SHORTCUT_FILE is used for adding a shortcut for "file".
+ *        LAUNCH_BY_PACKAGE is used for adding a package itself as a shortcut
+ *        LAUNCH_BY_URI is used for adding a shortcut for "uri" data.
  */
-enum {
-       SHORTCUT_PACKAGE = 0x0, /**< Launch the package using given pakcage name. */
-       SHORTCUT_DATA = 0x01, /**< Launch the related package with given data(content_info). */
-       SHORTCUT_FILE = 0x02, /** < Launch the related package with given filename(content_info). */
+enum shortcut_type {
+       /*!< Deprecated type */
+       SHORTCUT_PACKAGE        = 0x00000000, /**< Launch the package using given pakcage name. */
+       SHORTCUT_DATA           = 0x00000001, /**< Launch the related package with given data(content_info). */
+       SHORTCUT_FILE           = 0x00000002, /**< Launch the related package with given filename(content_info). */
+
+       /*!< Use these */
+       LAUNCH_BY_PACKAGE       = 0x00000000, /*!< Launch the package using given pakcage name. */
+       LAUNCH_BY_URI           = 0x00000001, /*!< Launch the related package with given data(URI). */
+
+       LIVEBOX_TYPE_DEFAULT      = 0x10000000,
+       LIVEBOX_TYPE_EASY_DEFAULT = 0x30000000,
+       LIVEBOX_TYPE_1x1          = 0x10010000,
+       LIVEBOX_TYPE_2x1          = 0x10020000,
+       LIVEBOX_TYPE_2x2          = 0x10040000,
+       LIVEBOX_TYPE_4x1          = 0x10080000,
+       LIVEBOX_TYPE_4x2          = 0x10100000,
+       LIVEBOX_TYPE_4x3          = 0x10200000,
+       LIVEBOX_TYPE_4x4          = 0x10400000,
+       LIVEBOX_TYPE_EASY_1x1     = 0x30010000,
+       LIVEBOX_TYPE_EASY_3x1     = 0x30020000,
+       LIVEBOX_TYPE_EASY_3x3     = 0x30040000,
+       LIVEBOX_TYPE_UNKNOWN      = 0x1FFF0000,
 };
 
+#define ADD_TO_HOME_IS_LIVEBOX(type)   (!!((type) & 0x10000000))
+
 /**
  * @fn int shortcut_set_request_cb(request_cb_t request_cb, void *data)
  *
@@ -116,9 +137,9 @@ enum {
  * @code
  * #include <shortcut.h>
  *
- * static int request_cb(const char *pkgname, const char *name, int type, const char *content_info, const char *icon, int pid, void *data)
+ * static int request_cb(const char *appid, const char *name, int type, const char *content_info, const char *icon, int pid, void *data)
  * {
- *     printf("Package name: %s\n", pkgname);
+ *     printf("Package name: %s\n", appid);
  *     printf("Name: %s\n", name);
  *     printf("Type: %d\n", type);
  *     printf("Content: %s\n", content_info);
@@ -144,7 +165,7 @@ enum {
 extern int shortcut_set_request_cb(request_cb_t request_cb, void *data);
 
 /**
- * @fn int shortcut_add_to_home(const char *pkgname, const char *name, int type, const char *content_info, const char *icon, result_cb_t result_cb, void *data)
+ * @fn int add_to_home_shortcut(const char *appid, const char *name, int type, const char *content_info, const char *icon, result_cb_t result_cb, void *data)
  *
  * @brief The application, which supporting the add_to_home feature, should invoke this.
  *
@@ -156,7 +177,7 @@ extern int shortcut_set_request_cb(request_cb_t request_cb, void *data);
  * - Application should check the return status from the callback function
  * - Application should set the callback function to get the result of this request.
  *
- * @param[in] pkgname Package name of owner of this shortcut.
+ * @param[in] appid Package name of owner of this shortcut.
  * @param[in] name Name for created shortcut icon.
  * @param[in] type 3 kinds of types are defined.
  * @param[in] content_info Specific information for delivering to the creating shortcut.
@@ -196,7 +217,7 @@ extern int shortcut_set_request_cb(request_cb_t request_cb, void *data);
  *
  * static int app_create(void *data)
  * {
- *     shortcut_add_to_home("com.samsung.gallery", "With friends",
+ *     add_to_home_shortcut("org.tizen.gallery", "With friends",
  *                                     SHORTCUT_DATA, "gallery:0000-0000",
  *                                     "/opt/media/Pictures/Friends.jpg", result_cb, NULL);
  *     return 0;
@@ -209,9 +230,37 @@ extern int shortcut_set_request_cb(request_cb_t request_cb, void *data);
  *
  * @endcode
  */
-extern int shortcut_add_to_home(const char *pkgname, const char *name, int type, const char *content_info, const char *icon, result_cb_t result_cb, void *data);
+extern int shortcut_get_list(const char *appid, int (*cb)(const char *appid, const char *icon, const char *name, const char *extra_key, const char *extra_data, void *data), void *data);
+
+extern int add_to_home_shortcut(const char *appid, const char *name, int type, const char *content_info, const char *icon, result_cb_t result_cb, void *data);
+
+extern int add_to_home_livebox(const char *appid, const char *name, int type, const char *content, const char *icon, double period, result_cb_t result_cb, void *data);
+
+
+/*!
+ * \brief Number of preview images for homescreen
+ */
+extern int homescreen_get_image_count(const char *appid);
+/*!
+ * \return string allocated in the heap - Path of image
+ */
+extern char *homescreen_get_image(const char *appid, int idx);
+
+/*!
+ * \brief Description of the homescreen (based on i18n)
+ */
+extern int homescreen_get_description(const char *appid, void (*cb)(const char *appid, const char *icon, const char *name, const char *desc, void *data), void *data);
+
+/*!
+ * \note
+ * These two functions are deprecated now.
+ *
+ * Please replace the "shortcut_add_to_home" with "add_to_home_shortcut"
+ * Please replace the "shortcut_add_to_home_with_period" with "add_to_home_livebox"
+ */
+extern int shortcut_add_to_home(const char *appid, const char *name, int type, const char *content, const char *icon, result_cb_t result_cb, void *data) __attribute__ ((deprecated));
 
-extern int add_to_home_shortcut(const char *pkgname, const char *name, int type, const char *content_info, const char *icon, result_cb_t result_cb, void *data);
+extern int shortcut_add_to_home_with_period(const char *appid, const char *name, int type, const char *content, const char *icon, double period, result_cb_t result_cb, void *data) __attribute__ ((deprecated));
 
 #ifdef __cplusplus
 }
similarity index 81%
rename from include/SLP_shortcut_PG.h
rename to lib/include/shortcut_PG.h
index eec5363..c3bd6c2 100644 (file)
@@ -1,18 +1,19 @@
 /*
- * Copyright 2012  Samsung Electronics Co., Ltd
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Licensed under the Flora License, Version 1.0 (the "License");
+ * 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.tizenopensource.org/license
+ * 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
@@ -20,7 +21,7 @@
  *  @{
 
  <h1 class="pg">Introduction</h1>
- Shortcut is a communication interfaces for homescreen and applications. To enable the add_to_home feature. Shortcut(libslp-shortcut) uses socket for IPC.
+ Shortcut is a communication interfaces for homescreen and applications. To enable the add_to_home feature. Shortcut(libshortcut) uses socket for IPC.
 
  @image html SLP_Shortcut_PG_image01.png
 
similarity index 91%
rename from shortcut.pc.in
rename to lib/shortcut.pc.in
index 9798259..8daf96d 100644 (file)
@@ -6,6 +6,5 @@ includedir=@INCLUDEDIR@
 Name: shortcut
 Description: shortcut server platform library
 Version: @VERSION@
-Requires: glib-2.0
 Libs: -L${libdir} -lshortcut
 Cflags: -I${includedir}
diff --git a/lib/src/main.c b/lib/src/main.c
new file mode 100644 (file)
index 0000000..d485a53
--- /dev/null
@@ -0,0 +1,776 @@
+/*
+ * Copyright (c) 2000 - 2011 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.
+ *
+*/
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <libgen.h>
+
+#include <dlog.h>
+#include <glib.h>
+#include <db-util.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include <packet.h>
+#include <com-core.h>
+#include <com-core_packet.h>
+
+#include "shortcut.h"
+
+#if !defined(FLOG)
+#define DbgPrint(format, arg...)       LOGD("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#define ErrPrint(format, arg...)       LOGE("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#else
+extern FILE *__file_log_fp;
+#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
+
+#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
+#endif
+
+#define EAPI __attribute__((visibility("default")))
+
+int errno;
+
+
+
+static struct info {
+       const char *dbfile;
+       sqlite3 *handle;
+       int server_fd;
+       int client_fd;
+       const char *socket_file;
+       struct {
+               int (*request_cb)(const char *appid, const char *name, int type, const char *content, const char *icon, pid_t pid, double period, void *data);
+               void *data;
+       } server_cb;
+       int initialized;
+       int db_opened;
+} s_info = {
+       .server_fd = -1,
+       .client_fd = -1,
+       .socket_file = "/tmp/.shortcut",
+       .dbfile = "/opt/dbspace/.shortcut_service.db",
+       .handle = NULL,
+       .initialized = 0,
+       .db_opened = 0,
+};
+
+
+
+static struct packet *add_shortcut_handler(pid_t pid, int handle, const struct packet *packet)
+{
+       const char *appid;
+       const char *name;
+       int type;
+       const char *content;
+       const char *icon;
+       int ret;
+
+       if (!packet)
+               return NULL;
+
+       if (packet_get(packet, "ssiss", &appid, &name, &type, &content, &icon) != 5) {
+               ErrPrint("Invalid packet\n");
+               return NULL;
+       }
+
+       DbgPrint("appid[%s], name[%s], type[0x%x], content[%s], icon[%s]\n", appid, name, type, content, icon);
+
+       if (s_info.server_cb.request_cb)
+               ret = s_info.server_cb.request_cb(appid, name, type, content, icon, pid, -1.0f, s_info.server_cb.data);
+       else
+               ret = 0;
+
+       return packet_create_reply(packet, "i", ret);
+}
+
+
+
+static struct packet *add_livebox_handler(pid_t pid, int handle, const struct packet *packet)
+{
+       const char *appid;
+       const char *name;
+       int type;
+       const char *content;
+       const char *icon;
+       double period;
+       int ret;
+
+       if (!packet)
+               return NULL;
+
+       if (packet_get(packet, "ssissd", &appid, &name, &type, &content, &icon, &period) != 6) {
+               ErrPrint("Invalid packet\n");
+               return NULL;
+       }
+
+       DbgPrint("appid[%s], name[%s], type[0x%x], content[%s], icon[%s], period[%lf]\n", appid, name, type, content, icon, period);
+
+       if (s_info.server_cb.request_cb)
+               ret = s_info.server_cb.request_cb(appid, name, type, content, icon, pid, period, s_info.server_cb.data);
+       else
+               ret = 0;
+
+       return packet_create_reply(packet, "i", ret);
+}
+
+
+
+EAPI int shortcut_set_request_cb(request_cb_t request_cb, void *data)
+{
+       s_info.server_cb.request_cb = request_cb;
+       s_info.server_cb.data = data;
+
+       if (s_info.server_fd < 0) {
+               static struct method service_table[] = {
+                       {
+                               .cmd = "add_shortcut",
+                               .handler = add_shortcut_handler,
+                       },
+                       {
+                               .cmd = "add_livebox",
+                               .handler = add_livebox_handler,
+                       },
+                       {
+                               .cmd = NULL,
+                               .handler = NULL,
+                       },
+               };
+
+               unlink(s_info.socket_file);     /* Delete previous socket file for creating a new server socket */
+               s_info.server_fd = com_core_packet_server_init(s_info.socket_file, service_table);
+       }
+
+       DbgPrint("Server FD: %d\n", s_info.server_fd);
+
+       return s_info.server_fd > 0 ? 0 : s_info.server_fd;
+}
+
+
+
+struct result_cb_item {
+       result_cb_t result_cb;
+       void *data;
+};
+
+
+
+static int shortcut_send_cb(pid_t pid, int handle, const struct packet *packet, void *data)
+{
+       struct result_cb_item *item = data;
+       int ret;
+
+       if (!packet) {
+               ErrPrint("Packet is not valid\n");
+               ret = -EFAULT;
+       } else if (packet_get(packet, "i", &ret) != 1) {
+               ErrPrint("Packet is not valid\n");
+               ret = -EINVAL;
+       }
+
+       if (item->result_cb)
+               ret = item->result_cb(ret, pid, item->data);
+       else
+               ret = 0;
+       free(item);
+       return ret;
+}
+
+
+
+static int livebox_send_cb(pid_t pid, int handle, const struct packet *packet, void *data)
+{
+       struct result_cb_item *item = data;
+       int ret;
+
+       if (!packet) {
+               ErrPrint("Packet is not valid\n");
+               ret = -EFAULT;
+       } else if (packet_get(packet, "i", &ret) != 1) {
+               ErrPrint("Packet is not valid\n");
+               ret = -EINVAL;
+       }
+
+       if (item->result_cb)
+               ret = item->result_cb(ret, pid, item->data);
+       else
+               ret = 0;
+       free(item);
+       return ret;
+}
+
+
+
+static int disconnected_cb(int handle, void *data)
+{
+       if (s_info.client_fd != handle) {
+               /*!< This is not my favor */
+               return 0;
+       }
+
+       s_info.client_fd = -EINVAL;
+       return 0;
+}
+
+
+
+EAPI int add_to_home_shortcut(const char *appid, const char *name, int type, const char *content, const char *icon, result_cb_t result_cb, void *data)
+{
+       struct packet *packet;
+       struct result_cb_item *item;
+       int ret;
+
+       if (!s_info.initialized) {
+               s_info.initialized = 1;
+               com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
+       }
+
+       if (s_info.client_fd < 0) {
+               static struct method service_table[] = {
+                       {
+                               .cmd = NULL,
+                               .handler = NULL,
+                       },
+               };
+
+               s_info.client_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
+               if (s_info.client_fd < 0) {
+                       ErrPrint("Failed to make connection\n");
+                       return s_info.client_fd;
+               }
+       }
+
+       item = malloc(sizeof(*item));
+       if (!item) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return -ENOMEM;
+       }
+
+       item->result_cb = result_cb;
+       item->data = data;
+
+       if (!appid)
+               appid = "";
+
+       if (!name)
+               name = "";
+
+       if (!content)
+               content = "";
+
+       if (!icon)
+               icon = "";
+
+       packet = packet_create("add_shortcut", "ssiss", appid, name, type, content, icon);
+       if (!packet) {
+               ErrPrint("Failed to build a packet\n");
+               free(item);
+               return -EFAULT;
+       }
+
+       ret = com_core_packet_async_send(s_info.client_fd, packet, 0.0f, shortcut_send_cb, item);
+       if (ret < 0) {
+               packet_destroy(packet);
+               free(item);
+               com_core_packet_client_fini(s_info.client_fd);
+               s_info.client_fd = -1;
+       }
+
+       return ret;
+}
+
+
+
+EAPI int add_to_home_livebox(const char *appid, const char *name, int type, const char *content, const char *icon, double period, result_cb_t result_cb, void *data)
+{
+       struct packet *packet;
+       struct result_cb_item *item;
+       int ret;
+
+       if (!s_info.initialized) {
+               s_info.initialized = 1;
+               com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
+       }
+
+       if (s_info.client_fd < 0) {
+               static struct method service_table[] = {
+                       {
+                               .cmd = NULL,
+                               .handler = NULL,
+                       },
+               };
+
+               s_info.client_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
+               if (s_info.client_fd < 0)
+                       return s_info.client_fd;
+       }
+
+       item = malloc(sizeof(*item));
+       if (!item) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return -ENOMEM;
+       }
+
+       item->result_cb = result_cb;
+       item->data = data;
+
+       packet = packet_create("add_livebox", "ssissd", appid, name, type, content, icon, period);
+       if (!packet) {
+               ErrPrint("Failed to build a packet\n");
+               free(item);
+               return -EFAULT;
+       }
+
+       ret = com_core_packet_async_send(s_info.client_fd, packet, 0.0f, livebox_send_cb, item);
+       if (ret < 0) {
+               packet_destroy(packet);
+               free(item);
+               com_core_packet_client_fini(s_info.client_fd);
+               s_info.client_fd = -1;
+       }
+
+       return ret;
+}
+
+
+EAPI int shortcut_add_to_home_with_period(const char *appid, const char *name, int type, const char *content, const char *icon, double period, result_cb_t result_cb, void *data)
+{
+       return add_to_home_livebox(appid, name, type, content, icon, period, result_cb, data);
+}
+
+EAPI int shortcut_add_to_home(const char *appid, const char *name, int type, const char *content, const char *icon, result_cb_t result_cb, void *data)
+{
+       return add_to_home_shortcut(appid, name, type, content, icon, result_cb, data);
+}
+
+static inline int open_db(void)
+{
+       int ret;
+
+       ret = db_util_open(s_info.dbfile, &s_info.handle, DB_UTIL_REGISTER_HOOK_METHOD);
+       if (ret != SQLITE_OK) {
+               DbgPrint("Failed to open a %s\n", s_info.dbfile);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+
+
+/*!
+ * \note this function will returns allocated(heap) string
+ */
+static inline char *get_i18n_name(const char *lang, int id)
+{
+       sqlite3_stmt *stmt;
+       static const char *query = "SELECT name FROM shortcut_name WHERE id = ? AND lang = ? COLLATE NOCASE";
+       const unsigned char *name;
+       char *ret;
+       int status;
+
+       status = sqlite3_prepare_v2(s_info.handle, query, -1, &stmt, NULL);
+       if (status != SQLITE_OK) {
+               ErrPrint("Failed to prepare stmt: %s\n", sqlite3_errmsg(s_info.handle));
+               return NULL;
+       }
+
+       status = sqlite3_bind_int(stmt, 1, id);
+       if (status != SQLITE_OK) {
+               ErrPrint("Failed to bind id: %s\n", sqlite3_errmsg(s_info.handle));
+               ret = NULL;
+               goto out;
+       }
+
+       status = sqlite3_bind_text(stmt, 2, lang, -1, SQLITE_TRANSIENT);
+       if (status != SQLITE_OK) {
+               ErrPrint("Failed to bind lang: %s\n", sqlite3_errmsg(s_info.handle));
+               ret = NULL;
+               goto out;
+       }
+
+       DbgPrint("id: %d, lang: %s\n", id, lang);
+       if (SQLITE_ROW != sqlite3_step(stmt)) {
+               ErrPrint("Failed to do step: %s\n", sqlite3_errmsg(s_info.handle));
+               ret = NULL;
+               goto out;
+       }
+
+       name = sqlite3_column_text(stmt, 0);
+       ret = name ? strdup((const char *)name) : NULL;
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+       sqlite3_finalize(stmt);
+       return ret;
+}
+
+
+
+static inline int homescreen_get_i18n(const char *appid, const char *lang, char **name, char **desc)
+{
+       sqlite3_stmt *stmt;
+       static const char *query = "SELECT name, desc FROM desc WHERE appid = ? AND lang = ?";
+       const unsigned char *_name;
+       const unsigned char *_desc;
+       int status;
+
+       status = sqlite3_prepare_v2(s_info.handle, query, -1, &stmt, NULL);
+       if (status != SQLITE_OK) {
+               ErrPrint("Failed to prepare stmt: %s\n", sqlite3_errmsg(s_info.handle));
+               return -EIO;
+       }
+
+       status = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
+       if (status != SQLITE_OK) {
+               ErrPrint("Failed to bind appid: %s\n", sqlite3_errmsg(s_info.handle));
+               status = -EIO;
+               goto out;
+       }
+
+       status = sqlite3_bind_text(stmt, 2, lang, -1, SQLITE_TRANSIENT);
+       if (status != SQLITE_OK) {
+               ErrPrint("Failed to bind lang: %s\n", sqlite3_errmsg(s_info.handle));
+               status = -EIO;
+               goto out;
+       }
+
+       if (SQLITE_ROW != sqlite3_step(stmt)) {
+               ErrPrint("Failed to do step: %s\n", sqlite3_errmsg(s_info.handle));
+               status = -EIO;
+               goto out;
+       }
+
+       if (name) {
+               _name = sqlite3_column_text(stmt, 0);
+               *name = _name ? strdup((const char *)_name) : NULL;
+       }
+
+       if (desc) {
+               _desc = sqlite3_column_text(stmt, 1);
+               *desc = _desc ? strdup((const char *)_desc) : NULL;
+       }
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+       sqlite3_finalize(stmt);
+       return status;
+}
+
+
+
+/*!
+ * cb: SYNC callback
+ */
+EAPI int homescreen_get_description(const char *appid, void (*cb)(const char *appid, const char *icon, const char *name, const char *desc, void *data), void *data)
+{
+       sqlite3_stmt *stmt;
+       static const char *query = "SELECT icon, name, desc FROM homescreen WHERE appid = ?";
+       char *i18n_name;
+       char *i18n_desc;
+       const unsigned char *desc;
+       const unsigned char *name;
+       const unsigned char *icon;
+       int ret;
+
+       ret = sqlite3_prepare_v2(s_info.handle, query, -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Prepare failed: %s\n", sqlite3_errmsg(s_info.handle));
+               ret = -EIO;
+               goto out;
+       }
+
+       ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Prepare failed: %s\n", sqlite3_errmsg(s_info.handle));
+               ret = -EIO;
+               goto out;
+       }
+
+       if (SQLITE_ROW != sqlite3_step(stmt)) {
+               ErrPrint("Step failed: %s\n", sqlite3_errmsg(s_info.handle));
+               ret = -EIO;
+               goto out;
+       }
+
+       icon = sqlite3_column_text(stmt, 0);
+       name = sqlite3_column_text(stmt, 1);
+       desc = sqlite3_column_text(stmt, 2);
+
+       /*!
+        * \todo
+        * Get the i18n name and desc
+        */
+       if (homescreen_get_i18n(appid, "en-us", &i18n_name, &i18n_desc) < 0) {
+               i18n_name = NULL;
+               i18n_desc = NULL;
+       }
+
+       cb(appid, (const char *)icon, i18n_name ? i18n_name : (const char *)name, i18n_desc ? i18n_desc : (const char *)desc, data);
+
+       free(i18n_name);
+       free(i18n_desc);
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+       sqlite3_finalize(stmt);
+       return ret;
+}
+
+
+
+EAPI char *homescreen_get_image(const char *appid, int idx)
+{
+       static const char *query = "SELECT path FROM image WHERE appid = ? AND id = ?";
+       sqlite3_stmt *stmt;
+       int ret;
+       const unsigned char *path;
+       char *ret_path = NULL;
+
+       ret = sqlite3_prepare_v2(s_info.handle, query, -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Prepare failed: %s\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
+       if (ret != SQLITE_OK) {
+               ErrPrint("bind failed: %s\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       ret = sqlite3_bind_int(stmt, 2, idx);
+       if (ret != SQLITE_OK) {
+               ErrPrint("bind failed: %s\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       if (SQLITE_ROW != sqlite3_step(stmt)) {
+               ErrPrint("Step failed: %s\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       path = sqlite3_column_text(stmt, 0);
+       if (!path) {
+               ErrPrint("Get result: %s\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       ret_path = strdup((const char *)path);
+       if (!ret_path)
+               ErrPrint("Heap: %s\n", strerror(errno));
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+       sqlite3_finalize(stmt);
+       return ret_path;
+}
+
+
+
+EAPI int homescreen_get_image_count(const char *appid)
+{
+       static const char *query = "SELECT COUNT(id) FROM image WHERE appid = ?";
+       sqlite3_stmt *stmt;
+       int ret;
+
+       ret = sqlite3_prepare_v2(s_info.handle, query, -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("bind failed: %s\n", sqlite3_errmsg(s_info.handle));
+               ret = -EIO;
+               goto out;
+       }
+
+       ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
+       if (ret != SQLITE_OK) {
+               ErrPrint("bind failed: %s\n", sqlite3_errmsg(s_info.handle));
+               ret = -EIO;
+               goto out;
+       }
+
+       if (SQLITE_ROW != sqlite3_step(stmt)) {
+               ErrPrint("step failed: %s\n", sqlite3_errmsg(s_info.handle));
+               ret = -EIO;
+               goto out;
+       }
+
+       ret = sqlite3_column_int(stmt, 0);
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+       sqlite3_finalize(stmt);
+       return ret;
+}
+
+
+
+static inline char *cur_locale(void)
+{
+       char *language;
+       language = vconf_get_str(VCONFKEY_LANGSET);
+       if (language) {
+               char *ptr;
+
+               ptr = language;
+               while (*ptr) {
+                       if (*ptr == '.') {
+                               *ptr = '\0';
+                               break;
+                       }
+
+                       if (*ptr == '_')
+                               *ptr = '-';
+
+                       ptr++;
+               }
+       } else {
+               language = strdup("en-us");
+               if (!language)
+                       ErrPrint("Heap: %s\n", strerror(errno));
+       }
+
+       return language;
+}
+
+
+
+/*!
+ * \note READ ONLY DB
+ */
+EAPI int shortcut_get_list(const char *appid, int (*cb)(const char *appid, const char *icon, const char *name, const char *extra_key, const char *extra_data, void *data), void *data)
+{
+       sqlite3_stmt *stmt;
+       const char *query;
+       const unsigned char *name;
+       char *i18n_name;
+       const unsigned char *extra_data;
+       const unsigned char *extra_key;
+       const unsigned char *icon;
+       int id;
+       int ret;
+       int cnt;
+       char *language;
+
+       if (!s_info.db_opened)
+               s_info.db_opened = (open_db() == 0);
+
+       if (!s_info.db_opened) {
+               ErrPrint("Failed to open a DB\n");
+               return -EIO;
+       }
+
+       language = cur_locale();
+       if (!language) {
+               ErrPrint("Locale is not valid\n");
+               return -EINVAL;
+       }
+
+       if (appid) {
+               query = "SELECT id, appid, name, extra_key, extra_data, icon FROM shortcut_service WHERE appid = ?";
+               ret = sqlite3_prepare_v2(s_info.handle, query, -1, &stmt, NULL);
+               if (ret != SQLITE_OK) {
+                       ErrPrint("prepare: %s\n", sqlite3_errmsg(s_info.handle));
+                       free(language);
+                       return -EIO;
+               }
+
+               ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
+               if (ret != SQLITE_OK) {
+                       ErrPrint("bind text: %s\n", sqlite3_errmsg(s_info.handle));
+                       sqlite3_finalize(stmt);
+                       free(language);
+                       return -EIO;
+               }
+       } else {
+               query = "SELECT id, appid, name, extra_key, extra_data, icon FROM shortcut_service";
+               ret = sqlite3_prepare_v2(s_info.handle, query, -1, &stmt, NULL);
+               if (ret != SQLITE_OK) {
+                       ErrPrint("prepare: %s\n", sqlite3_errmsg(s_info.handle));
+                       free(language);
+                       return -EIO;
+               }
+       }
+
+       cnt = 0;
+       while (SQLITE_ROW == sqlite3_step(stmt)) {
+               id = sqlite3_column_int(stmt, 0);
+
+               appid = (const char *)sqlite3_column_text(stmt, 1);
+               if (!appid) {
+                       LOGE("Failed to get package name\n");
+                       continue;
+               }
+
+               name = sqlite3_column_text(stmt, 2);
+               if (!name) {
+                       LOGE("Failed to get name\n");
+                       continue;
+               }
+
+               extra_key = sqlite3_column_text(stmt, 3);
+               if (!extra_key) {
+                       LOGE("Failed to get service\n");
+                       continue;
+               }
+
+               extra_data = sqlite3_column_text(stmt, 4);
+               if (!extra_data) {
+                       LOGE("Failed to get service\n");
+                       continue;
+               }
+
+               icon = sqlite3_column_text(stmt, 5);
+               if (!icon) {
+                       LOGE("Failed to get icon\n");
+                       continue;
+               }
+
+               /*!
+                * \todo
+                * Implement the "GET LOCALE" code
+                */
+               i18n_name = get_i18n_name(language, id);
+
+               cnt++;
+               if (cb(appid, (char *)icon, (i18n_name != NULL ? i18n_name : (char *)name), (char *)extra_key, (char *)extra_data, data) < 0) {
+                       free(i18n_name);
+                       break;
+               }
+
+               free(i18n_name);
+       }
+
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+       sqlite3_finalize(stmt);
+       free(language);
+       return cnt;
+}
+
+
+
+/* End of a file */
index a76fdba..f1055e7 100644 (file)
@@ -1,5 +1,22 @@
 <manifest>
+       <!-- Shortcut service -->
+       <define>
+               <domain name="shortcut-service" policy="restricted" />
+               <provide>
+                       <label name="shortcut-service::db" />
+               </provide>
+       </define>
        <request>
                <domain name="_" />
        </request>
+
+       <assign>
+               <!-- Executable file -->
+               <filesystem path="/usr/lib/libshortcut.so.0.0.1" label="_" />
+               <filesystem path="/usr/etc/package-manager/parserlib/libshortcut-list.so" label="_" />
+
+               <!-- Database file -->
+               <filesystem path="/opt/dbspace/.shortcut_service.db" label="shortcut-service::db" />
+               <filesystem path="/opt/dbspace/.shortcut_service.db-journal" label="shortcut-service::db" />
+       </assign>
 </manifest>
index c04cf87..b53a521 100644 (file)
@@ -1,17 +1,22 @@
-Name:      libshortcut
-Summary:    Shortcut add feature supporting library
-Version:    0.0.5
-Release:    0
-Group:      main/devel
-License:    Apache License
-Source0:    %{name}-%{version}.tar.gz
+Name: libshortcut
+Summary: Shortcut add feature supporting library
+Version: 0.3.20
+Release: 0
+Group: main/devel
+License: Apache License
+Source0: %{name}-%{version}.tar.gz
 
 Requires(post): /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
 
-BuildRequires: cmake, gettext-tools
+BuildRequires: cmake, gettext-tools, coreutils
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(db-util)
+BuildRequires: pkgconfig(sqlite3)
+BuildRequires: pkgconfig(com-core)
+BuildRequires: pkgconfig(libxml-2.0)
+BuildRequires: pkgconfig(vconf)
 
 %description
 [Shortcut] AddToHome feature supporting library for menu/home screen developers.
@@ -35,6 +40,9 @@ make %{?jobs:-j%jobs}
 %install
 rm -rf %{buildroot}
 %make_install
+mkdir -p %{buildroot}/opt/dbspace
+touch %{buildroot}/opt/dbspace/.shortcut_service.db
+touch %{buildroot}/opt/dbspace/.shortcut_service.db-journal
 
 %post
 
@@ -44,9 +52,15 @@ rm -rf %{buildroot}
 %manifest libshortcut.manifest
 %defattr(-,root,root,-)
 %{_libdir}/*.so*
+%{_prefix}/etc/package-manager/parserlib/*
+%{_datarootdir}/license/*
+%attr(640,root,app) /opt/dbspace/.shortcut_service.db
+%attr(640,root,app) /opt/dbspace/.shortcut_service.db-journal
 
 %files devel
 %defattr(-,root,root,-)
-%{_includedir}/shortcut/SLP_shortcut_PG.h
+%{_includedir}/shortcut/shortcut_PG.h
 %{_includedir}/shortcut/shortcut.h
 %{_libdir}/pkgconfig/shortcut.pc
+
+# End of a file
diff --git a/pkgmgr_shortcut/CMakeLists.txt b/pkgmgr_shortcut/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0a4abc7
--- /dev/null
@@ -0,0 +1,31 @@
+PROJECT(shortcut-list C)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/pkgmgr_shortcut/include)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(bin_pkgs REQUIRED
+       dlog
+       sqlite3
+       libxml-2.0
+       db-util
+)
+
+FOREACH(flag ${bin_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -g -Wall -Werror")
+
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+ADD_DEFINITIONS("-DLOG_TAG=\"PKGMGR_SHORTCUT\"")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED
+       src/service_register.c
+       src/dlist.c
+)
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${bin_pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION "etc/package-manager/parserlib")
+
+# End of a file
diff --git a/pkgmgr_shortcut/include/dlist.h b/pkgmgr_shortcut/include/dlist.h
new file mode 100644 (file)
index 0000000..f840f92
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2000 - 2011 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.
+ *
+*/
+
+#define dlist_remove_data(list, data) do { \
+       struct dlist *l; \
+       l = dlist_find_data(list, data); \
+       list = dlist_remove(list, l); \
+} while (0)
+
+#define dlist_foreach(list, l, data) \
+       for ((l) = (list); (l) && ((data) = dlist_data(l)); (l) = dlist_next(l))
+
+#define dlist_foreach_safe(list, l, n, data) \
+       for ((l) = (list), (n) = dlist_next(l); \
+               (l) && ((data) = dlist_data(l)); \
+               (l) = (n), (n) = dlist_next(l))
+
+struct dlist;
+
+extern struct dlist *dlist_append(struct dlist *list, void *data);
+extern struct dlist *dlist_prepend(struct dlist *list, void *data);
+extern struct dlist *dlist_remove(struct dlist *list, struct dlist *l);
+extern struct dlist *dlist_find_data(struct dlist *list, void *data);
+extern void *dlist_data(struct dlist *l);
+extern struct dlist *dlist_next(struct dlist *l);
+extern struct dlist *dlist_prev(struct dlist *l);
+extern int dlist_count(struct dlist *l);
+extern struct dlist *dlist_nth(struct dlist *l, int nth);
+
+/* End of a file */
diff --git a/pkgmgr_shortcut/src/dlist.c b/pkgmgr_shortcut/src/dlist.c
new file mode 100644 (file)
index 0000000..a212608
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2000 - 2011 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.
+ *
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "dlist.h"
+
+/*!
+ * \brief
+ * This dlist is called Modified Doubly Linked List.
+ *
+ * Noramlly, The dobule linked list contains address of previous and next element.
+ * This dlist also contains them, but the tail element only contains prev address.
+ *
+ * The head element's prev pointer indicates the last element.
+ * But the last element's next pointer indicates NIL.
+ *
+ * So we can find the last element while crawling this DList
+ * But we have to remember the address of the head element.
+ */
+
+struct dlist {
+       struct dlist *next;
+       struct dlist *prev;
+       void *data;
+};
+
+struct dlist *dlist_append(struct dlist *list, void *data)
+{
+       struct dlist *item;
+
+       item = malloc(sizeof(*item));
+       if (!item)
+               return NULL;
+
+       item->next = NULL;
+       item->data = data;
+
+       if (!list) {
+               item->prev = item;
+
+               list = item;
+       } else {
+               item->prev = list->prev;
+               item->prev->next = item;
+               list->prev = item;
+       }
+
+       assert(!list->prev->next && "item NEXT");
+
+       return list;
+}
+
+struct dlist *dlist_prepend(struct dlist *list, void *data)
+{
+       struct dlist *item;
+
+       item = malloc(sizeof(*item));
+       if (!item)
+               return NULL;
+
+       item->data = data;
+
+       if (!list) {
+               item->prev = item;
+               item->next = NULL;
+       } else {
+               if (list->prev->next)
+                       list->prev->next = item;
+
+               item->prev = list->prev;
+               item->next = list;
+
+               list->prev = item;
+
+       }
+
+       return item;
+}
+
+struct dlist *dlist_remove(struct dlist *list, struct dlist *l)
+{
+       if (!list || !l)
+               return NULL;
+
+       if (l == list)
+               list = l->next;
+       else
+               l->prev->next = l->next;
+
+       if (l->next)
+               l->next->prev = l->prev;
+       /*!
+        * \note
+        * If the removed entry 'l' has no next element, it is the last element.
+        * In this case, check the existence of the list first,
+        * and if the list is not empty, update the 'prev' of the list (which is a head element of the list) 
+        *
+        * If we didn't care about this, the head element(list) can indicates the invalid element.
+        */
+       else if (list)
+               list->prev = l->prev;
+
+       free(l);
+       return list;
+}
+
+struct dlist *dlist_find_data(struct dlist *list, void *data)
+{
+       struct dlist *l;
+       void *_data;
+
+       dlist_foreach(list, l, _data) {
+               if (data == _data)
+                       return l;
+       }
+
+       return NULL;
+}
+
+void *dlist_data(struct dlist *l)
+{
+       return l ? l->data : NULL;
+}
+
+struct dlist *dlist_next(struct dlist *l)
+{
+       return l ? l->next : NULL;
+}
+
+struct dlist *dlist_prev(struct dlist *l)
+{
+       return l ? l->prev : NULL;
+}
+
+int dlist_count(struct dlist *l)
+{
+       register int i;
+       struct dlist *n;
+       void *data;
+
+       i = 0;
+       dlist_foreach(l, n, data) {
+               i++;
+       }
+
+       return i;
+}
+
+struct dlist *dlist_nth(struct dlist *l, int nth)
+{
+       register int i;
+       struct dlist *n;
+
+       i = 0;
+       for (n = l; n; n = n->next) {
+               if (i == nth)
+                       return n;
+               i++;
+       }
+
+       return NULL;
+}
+
+/* End of a file */
diff --git a/pkgmgr_shortcut/src/service_register.c b/pkgmgr_shortcut/src/service_register.c
new file mode 100644 (file)
index 0000000..50b5ae2
--- /dev/null
@@ -0,0 +1,756 @@
+/*
+ * Copyright (c) 2000 - 2011 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.
+ *
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <string.h>
+
+#include <sqlite3.h>
+#include <db-util.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <dlog.h>
+
+#include "dlist.h"
+
+#if !defined(FLOG)
+#define DbgPrint(format, arg...)       LOGD("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#define ErrPrint(format, arg...)       LOGE("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#endif
+/* End of a file */
+
+/*!
+ * DB Table schema
+ *
+ * +----+-------+------+---------+-----------+------------+
+ * | id | appid | Icon |  Name   | extra_key | extra_data |
+ * +----+-------+------+---------+-----------+------------+
+ * | id |   -   |   -  |    -    |     -     |     -      |
+ * +----+-------+------+---------+-----------+------------+
+ *
+ * +----+------+------+
+ * | fk | lang | name |
+ * +----+------+------+
+ * | id |   -  |   -  |
+ * +----+------+------+
+ */
+
+#if !defined(LIBXML_TREE_ENABLED)
+       #error "LIBXML is not supporting the tree"
+#endif
+
+int errno;
+
+static struct {
+       const char *dbfile;
+       sqlite3 *handle;
+} s_info = {
+       .dbfile = "/opt/dbspace/.shortcut_service.db",
+       .handle = NULL,
+};
+
+static inline int begin_transaction(void)
+{
+       sqlite3_stmt *stmt;
+       int ret;
+
+       ret = sqlite3_prepare_v2(s_info.handle, "BEGIN TRANSACTION", -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               return EXIT_FAILURE;
+       }
+
+       if (sqlite3_step(stmt) != SQLITE_DONE) {
+               DbgPrint("Failed to do update (%s)\n",
+                                       sqlite3_errmsg(s_info.handle));
+               sqlite3_finalize(stmt);
+               return EXIT_FAILURE;
+       }
+
+       sqlite3_finalize(stmt);
+       return EXIT_SUCCESS;
+}
+
+static inline int rollback_transaction(void)
+{
+       int ret;
+       sqlite3_stmt *stmt;
+
+       ret = sqlite3_prepare_v2(s_info.handle, "ROLLBACK TRANSACTION", -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               return EXIT_FAILURE;
+       }
+
+       if (sqlite3_step(stmt) != SQLITE_DONE) {
+               DbgPrint("Failed to do update (%s)\n",
+                               sqlite3_errmsg(s_info.handle));
+               sqlite3_finalize(stmt);
+               return EXIT_FAILURE;
+       }
+
+       sqlite3_finalize(stmt);
+       return EXIT_SUCCESS;
+}
+
+static inline int commit_transaction(void)
+{
+       sqlite3_stmt *stmt;
+       int ret;
+
+       ret = sqlite3_prepare_v2(s_info.handle, "COMMIT TRANSACTION", -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+               return EXIT_FAILURE;
+       }
+
+       if (sqlite3_step(stmt) != SQLITE_DONE) {
+               DbgPrint("Failed to do update (%s)\n",
+                                       sqlite3_errmsg(s_info.handle));
+               sqlite3_finalize(stmt);
+               return EXIT_FAILURE;
+       }
+
+       sqlite3_finalize(stmt);
+       return EXIT_SUCCESS;
+}
+static inline void db_create_table(void)
+{
+       char *err;
+       static const char *ddl =
+               "CREATE TABLE shortcut_service ("
+               "id INTEGER PRIMARY KEY AUTOINCREMENT, "
+               "appid TEXT, "
+               "icon TEXT, "
+               "name TEXT, "
+               "extra_key TEXT, "
+               "extra_data TEXT)";
+
+       if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
+               ErrPrint("Failed to execute the DDL (%s)\n", err);
+               return;
+       }
+
+       if (sqlite3_changes(s_info.handle) == 0)
+               ErrPrint("No changes to DB\n");
+
+       ddl = "CREATE TABLE shortcut_name (id INTEGER, lang TEXT, name TEXT)";
+       if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
+               ErrPrint("Failed to execute the DDL (%s)\n", err);
+               return;
+       }
+
+       if (sqlite3_changes(s_info.handle) == 0)
+               ErrPrint("No changes to DB\n");
+}
+
+static inline int db_remove_record(const char *appid, const char *key, const char *data)
+{
+       static const char *dml = "DELETE FROM shortcut_service WHERE appid = ? AND extra_key = ? AND extra_data = ?";
+       sqlite3_stmt *stmt;
+       int ret;
+
+       if (!appid || !key || !data) {
+               ErrPrint("Invalid argument\n");
+               return -EINVAL;
+       }
+
+       ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
+               return -EIO;
+       }
+
+       ret = -EIO;
+       if (sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a appid(%s)\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       if (sqlite3_bind_text(stmt, 2, key, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a key(%s)\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       if (sqlite3_bind_text(stmt, 3, data, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a data(%s)\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       ret = 0;
+       if (sqlite3_step(stmt) != SQLITE_DONE) {
+               ret = -EIO;
+               ErrPrint("Failed to execute the DML for %s - %s(%s)\n", appid, key, data);
+       }
+
+       if (sqlite3_changes(s_info.handle) == 0)
+               DbgPrint("No changes\n");
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+       sqlite3_finalize(stmt);
+       return ret;
+}
+
+static inline int db_remove_name(int id)
+{
+       static const char *dml = "DELETE FROM shortcut_name WHERE id = ?";
+       sqlite3_stmt *stmt;
+       int ret;
+
+       if (id < 0) {
+               ErrPrint("Inavlid id\n");
+               return -EINVAL;
+       }
+
+       ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
+               return -EIO;
+       }
+
+       if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
+               ErrPrint("Failed to bind id(%d)\n", id);
+               ret = -EIO;
+               goto out;
+       }
+
+       ret = 0;
+       if (sqlite3_step(stmt) != SQLITE_DONE) {
+               ret = -EIO;
+               ErrPrint("Failed to execute the DML for %d\n", id);
+               goto out;
+       }
+
+       if (sqlite3_changes(s_info.handle) == 0)
+               DbgPrint("No changes\n");
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+       sqlite3_finalize(stmt);
+       return ret;
+}
+
+static inline int db_insert_record(const char *appid, const char *icon, const char *name, const char *key, const char *data)
+{
+       static const char *dml = "INSERT INTO shortcut_service (appid, icon, name, extra_key, extra_data) VALUES (?, ?, ?, ?, ?)";
+       sqlite3_stmt *stmt;
+       int ret;
+
+       if (!appid) {
+               ErrPrint("Failed to get appid\n");
+               return -EINVAL;
+       }
+
+       if (!name) {
+               ErrPrint("Failed to get name\n");
+               return -EINVAL;
+       }
+
+       if (!key) {
+               ErrPrint("Failed to get key\n");
+               return -EINVAL;
+       }
+
+       if (!data) {
+               ErrPrint("Faield to get key\n");
+               return -EINVAL;
+       }
+
+       icon = icon ? icon : "";
+
+       ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
+               return -EIO;
+       }
+
+       ret = -EIO;
+       if (sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a appid(%s)\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       if (sqlite3_bind_text(stmt, 2, icon, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a icon(%s)\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       if (sqlite3_bind_text(stmt, 3, name, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a name(%s)\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       if (sqlite3_bind_text(stmt, 4, key, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a service(%s)\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       if (sqlite3_bind_text(stmt, 5, data, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a service(%s)\n", sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       ret = 0;
+       if (sqlite3_step(stmt) != SQLITE_DONE) {
+               ErrPrint("Failed to execute the DML for %s - %s\n", appid, name);
+               ret = -EIO;
+       }
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+       sqlite3_finalize(stmt);
+       return ret;
+}
+
+static inline int db_insert_name(int id, const char *lang, const char *name)
+{
+       static const char *dml = "INSERT INTO shortcut_name (id, lang, name) VALUES (?, ?, ?)";
+       sqlite3_stmt *stmt;
+       int ret;
+
+       if (id < 0 || !lang || !name) {
+               ErrPrint("Invalid parameters\n");
+               return -EINVAL;
+       }
+
+       ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
+               return -EIO;
+       }
+
+       if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
+               ErrPrint("Failed to bind a id(%s)\n", sqlite3_errmsg(s_info.handle));
+               ret = -EIO;
+               goto out;
+       }
+
+       if (sqlite3_bind_text(stmt, 2, lang, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a id(%s)\n", sqlite3_errmsg(s_info.handle));
+               ret = -EIO;
+               goto out;
+       }
+
+       if (sqlite3_bind_text(stmt, 3, name, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a id(%s)\n", sqlite3_errmsg(s_info.handle));
+               ret = -EIO;
+               goto out;
+       }
+
+       ret = 0;
+       if (sqlite3_step(stmt) != SQLITE_DONE) {
+               ErrPrint("Failed to execute the DML for %d %s %s\n", id, lang, name);
+               ret = -EIO;
+       }
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+       sqlite3_finalize(stmt);
+       return ret;
+}
+
+static inline int db_get_id(const char *appid, const char *key, const char *data)
+{
+       static const char *dml = "SELECT id FROM shortcut_service WHERE appid = ? AND extra_key = ? AND extra_data = ?";
+       sqlite3_stmt *stmt;
+       int ret;
+
+       if (!appid || !key || !data) {
+               ErrPrint("Invalid argument\n");
+               return -EINVAL;
+       }
+
+       ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
+               return -EIO;
+       }
+
+       ret = -EIO;
+       if (sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a appid(%s) - %s\n", appid, sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       if (sqlite3_bind_text(stmt, 2, key, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a key(%s) - %s\n", key, sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       if (sqlite3_bind_text(stmt, 3, data, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
+               ErrPrint("Failed to bind a data(%s) - %s\n", data, sqlite3_errmsg(s_info.handle));
+               goto out;
+       }
+
+       if (sqlite3_step(stmt) != SQLITE_ROW) {
+               ErrPrint("Failed to execute the DML for %s - %s, %s\n", appid, key, data);
+               ret = -EIO;
+               goto out;
+       }
+
+       ret = sqlite3_column_int(stmt, 0);
+
+out:
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+       sqlite3_finalize(stmt);
+       return ret;
+}
+
+static inline int db_init(void)
+{
+       int ret;
+       struct stat stat;
+
+       ret = db_util_open(s_info.dbfile, &s_info.handle, DB_UTIL_REGISTER_HOOK_METHOD);
+       if (ret != SQLITE_OK) {
+               ErrPrint("Failed to open a DB\n");
+               return -EIO;
+       }
+
+       if (lstat(s_info.dbfile, &stat) < 0) {
+               ErrPrint("%s\n", strerror(errno));
+               db_util_close(s_info.handle);
+               s_info.handle = NULL;
+               return -EIO;
+       }
+
+       if (!S_ISREG(stat.st_mode)) {
+               ErrPrint("Invalid file\n");
+               db_util_close(s_info.handle);
+               s_info.handle = NULL;
+               return -EINVAL;
+       }
+
+       if (!stat.st_size)
+               db_create_table();
+
+       return 0;
+}
+
+static inline int db_fini(void)
+{
+       if (!s_info.handle)
+               return 0;
+
+       db_util_close(s_info.handle);
+       s_info.handle = NULL;
+
+       return 0;
+}
+
+int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr docPtr, const char *_appid)
+{
+       xmlNodePtr node = NULL;
+       xmlChar *key;
+       xmlChar *data;
+       xmlChar *appid;
+       xmlNodePtr root;
+       int id;
+
+       root = xmlDocGetRootElement(docPtr);
+       if (!root) {
+               ErrPrint("Invalid node ptr\n");
+               return -EINVAL;
+       }
+
+       if (!s_info.handle) {
+               if (db_init() < 0)
+                       return -EIO;
+       }
+
+       for (root = root->children; root; root = root->next) {
+               if (!xmlStrcasecmp(root->name, (const xmlChar *)"shortcut-list"))
+                       break;
+       }
+
+       if (!root) {
+               ErrPrint("Root has no shortcut-list\n");
+               return -EINVAL;
+       }
+
+       DbgPrint("AppID: %s\n", _appid);
+       root = root->children;
+       for (node = root; node; node = node->next) {
+               if (node->type == XML_ELEMENT_NODE)
+                       DbgPrint("Element %s\n", node->name);
+
+               if (xmlStrcasecmp(node->name, (const xmlChar *)"shortcut"))
+                       continue;
+
+               if (!xmlHasProp(node, (xmlChar *)"extra_data")
+                       || !xmlHasProp(node, (xmlChar *)"extra_key")
+                       || !xmlHasProp(node, (xmlChar *)"appid"))
+               {
+                       DbgPrint("Invalid element %s\n", node->name);
+                       continue;
+               }
+
+               appid = xmlGetProp(node, (xmlChar *)"appid");
+               key = xmlGetProp(node, (xmlChar *)"extra_key");
+               data = xmlGetProp(node, (xmlChar *)"extra_data");
+
+               DbgPrint("appid: %s\n", appid);
+               DbgPrint("key: %s\n", key);
+               DbgPrint("data: %s\n", data);
+
+               id = db_get_id((char *)appid, (char *)key, (char *)data);
+               if (id < 0) {
+                       ErrPrint("No records found\n");
+                       xmlFree(appid);
+                       xmlFree(key);
+                       xmlFree(data);
+                       continue;
+               }
+
+               begin_transaction();
+               if (db_remove_record((char *)appid, (char *)key, (char *)data) < 0) {
+                       ErrPrint("Failed to remove a record\n");
+                       rollback_transaction();
+                       xmlFree(appid);
+                       xmlFree(key);
+                       xmlFree(data);
+                       continue;
+               }
+
+               if (db_remove_name(id) < 0) {
+                       ErrPrint("Failed to remove name records\n");
+                       rollback_transaction();
+                       xmlFree(appid);
+                       xmlFree(key);
+                       xmlFree(data);
+                       continue;
+               }
+               commit_transaction();
+               xmlFree(appid);
+               xmlFree(key);
+               xmlFree(data);
+
+               /*!
+                * \note
+                * if (node->children)
+                * DbgPrint("Skip this node's children\n");
+                */
+       }
+
+       return 0;
+}
+
+int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr docPtr, const char *appid)
+{
+       xmlNodePtr node = NULL;
+       xmlNodePtr child = NULL;
+       xmlChar *key;
+       xmlChar *data;
+       xmlChar *name;
+       xmlChar *icon;
+       xmlChar *shortcut_appid;
+       xmlNodePtr root;
+       struct i18n_name {
+               xmlChar *name;
+               xmlChar *lang;
+       } *i18n;
+       struct dlist *i18n_list = NULL;
+       struct dlist *l;
+       struct dlist *n;
+       int id;
+
+       root = xmlDocGetRootElement(docPtr);
+       if (!root) {
+               ErrPrint("Invalid node ptr\n");
+               return -EINVAL;
+       }
+
+       if (!s_info.handle) {
+               if (db_init() < 0)
+                       return -EIO;
+       }
+
+       for (root = root->children; root; root = root->next) {
+               if (!xmlStrcasecmp(root->name, (const xmlChar *)"shortcut-list"))
+                       break;
+       }
+
+       if (!root) {
+               ErrPrint("Root has no children\n");
+               return -EINVAL;
+       }
+
+       DbgPrint("AppID: %s\n", appid);
+
+       root = root->children; /* Jump to children node */
+       for (node = root; node; node = node->next) {
+               if (node->type == XML_ELEMENT_NODE)
+                       DbgPrint("Element %s\n", node->name);
+
+               if (xmlStrcasecmp(node->name, (const xmlChar *)"shortcut"))
+                       continue;
+
+               if (!xmlHasProp(node, (xmlChar *)"extra_key") || !xmlHasProp(node, (xmlChar *)"extra_data")) {
+                       DbgPrint("Invalid element %s\n", node->name);
+                       continue;
+               }
+
+               key = xmlGetProp(node, (xmlChar *)"extra_key");
+               data = xmlGetProp(node, (xmlChar *)"extra_data");
+               shortcut_appid = xmlGetProp(node, (xmlChar *)"appid");
+
+               icon = NULL;
+               name = NULL;
+               for (child = node->children; child; child = child->next) {
+                       if (!xmlStrcasecmp(child->name, (const xmlChar *)"icon")) {
+                               if (icon) {
+                                       DbgPrint("Icon is duplicated\n");
+                                       continue;
+                               }
+
+                               icon = xmlNodeGetContent(child);
+                               continue;
+                       }
+
+                       if (!xmlStrcasecmp(child->name, (const xmlChar *)"label")) {
+                               xmlChar *lang;
+                               lang = xmlNodeGetLang(child);
+                               if (!lang) {
+                                       if (name) {
+                                               DbgPrint("Default name is duplicated\n");
+                                       } else {
+                                               name = xmlNodeGetContent(child);
+                                               DbgPrint("Default name is %s\n", name);
+                                       }
+
+                                       continue;
+                               }
+
+                               i18n = malloc(sizeof(*i18n));
+                               if (!i18n) {
+                                       ErrPrint("Heap: %s\n", strerror(errno));
+                                       break;
+                               }
+
+                               i18n->lang = lang;
+                               i18n->name = xmlNodeGetContent(child);
+                               i18n_list = dlist_append(i18n_list, i18n);
+                               continue;
+                       }
+               }
+
+               DbgPrint("appid: %s\n", appid);
+               DbgPrint("shortcut appid: %s\n", shortcut_appid);
+               DbgPrint("key: %s\n", key);
+               DbgPrint("data: %s\n", data);
+               DbgPrint("icon: %s\n", icon);
+               DbgPrint("Default name: %s\n", name);
+
+               if (!shortcut_appid) {
+                       shortcut_appid = xmlStrdup((xmlChar *)appid);
+                       DbgPrint("Use the default appid\n");
+               }
+
+               begin_transaction();
+               if (db_insert_record((char *)shortcut_appid, (char *)icon, (char *)name, (char *)key, (char *)data) < 0) {
+                       ErrPrint("Failed to insert a new record\n");
+                       rollback_transaction();
+
+                       dlist_foreach_safe(i18n_list, l, n, i18n) {
+                               i18n_list = dlist_remove(i18n_list, l);
+                               xmlFree(i18n->lang);
+                               xmlFree(i18n->name);
+                               free(i18n);
+                       }
+               } else {
+                       id = db_get_id((char *)shortcut_appid, (char *)key, (char *)data);
+                       if (id < 0) {
+                               ErrPrint("Failed to insert a new record\n");
+                               rollback_transaction();
+
+                               dlist_foreach_safe(i18n_list, l, n, i18n) {
+                                       i18n_list = dlist_remove(i18n_list, l);
+                                       xmlFree(i18n->lang);
+                                       xmlFree(i18n->name);
+                                       free(i18n);
+                               }
+                       } else {
+                               dlist_foreach_safe(i18n_list, l, n, i18n) {
+                                       i18n_list = dlist_remove(i18n_list, l);
+                                       if (db_insert_name(id, (char *)i18n->lang, (char *)i18n->name) < 0)
+                                               ErrPrint("Failed to add i18n name: %s(%s)\n", i18n->name, i18n->lang);
+                                       xmlFree(i18n->lang);
+                                       xmlFree(i18n->name);
+                                       free(i18n);
+                               }
+                               commit_transaction();
+                       }
+               }
+
+               xmlFree(key);
+               xmlFree(data);
+               xmlFree(icon);
+               xmlFree(name);
+               xmlFree(shortcut_appid);
+       }
+
+       return 0;
+}
+
+int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr docPtr, const char *appid)
+{
+       /* So... ugly */
+       PKGMGR_PARSER_PLUGIN_UNINSTALL(docPtr, appid);
+       PKGMGR_PARSER_PLUGIN_INSTALL(docPtr, appid);
+       return 0;
+}
+
+/*
+int main(int argc, char *argv[])
+{
+       xmlDoc *doc;
+       xmlNode *root;
+
+       if (argc != 2) {
+               ErrPRint("Invalid argument: %s XML_FILENAME\n", argv[0]);
+               return -EINVAL;
+       }
+
+       doc = xmlReadFile(argv[1], NULL, 0);
+       if (!doc) {
+               ErrPrint("Failed to parse %s\n", argv[1]);
+               return -EIO;
+       }
+
+       root = xmlDocGetRootElement(doc);
+
+       db_init();
+       install_shortcut("", root);
+       db_fini();
+
+       xmlFreeDoc(doc);
+       xmlCleanupParser();
+       return 0;
+}
+*/
+
+/* End of a file */
diff --git a/sample.xml b/sample.xml
new file mode 100644 (file)
index 0000000..0e471a0
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<manifest xmlns="http://tizen.org/ns/packages" package="org.tizen.myapp" version="0.3.5" install-location="auto">
+<shortcut-list test="a">
+       <shortcut appid="org.tizen.myapp" extra_key="key" extra_data="SERVICE INFORMATION 1">
+               <icon>/opt/usr/apps/org.tizen.myapp/res/icon/myapp_shortcut01.png</icon>
+               <label>Default Name</label>
+               <label xml:lang="en-us">Name en</label>
+               <label xml:lang="nl-nl">Name nl</label>
+               <label xml:lang="de-de">Name de</label>
+               <label xml:lang="zh-hk">Name hk</label>
+               <label xml:lang="zh-cn">Name cn</label>
+               <label xml:lang="ru-ru">Name ru</label>
+               <label xml:lang="zh-tw">Name tw</label>
+               <label xml:lang="ja-jp">Name jp</label>
+               <label xml:lang="es-es">Name es</label>
+               <label xml:lang="el-gr">Name gr</label>
+               <label xml:lang="it-it">Name it</label>
+               <label xml:lang="tr-tr">Name tr</label>
+               <label xml:lang="pt-pt">Name pt</label>
+               <label xml:lang="fr-fr">Name fr</label>
+               <label xml:lang="kor-kr">Name kr</label>
+       </shortcut>
+       <shortcut appid="org.tizen.myapp-gadget" extra_key="key" extra_data="SERVICE INFORMATION 2">
+               <icon>/opt/usr/apps/org.tizen.myapp/res/icon/gadget_shortcut01.png</icon>
+               <label>Default Name 02</label>
+               <label xml:lang="en-us">Name en</label>
+               <label xml:lang="nl-nl">Name nl</label>
+               <label xml:lang="de-de">Name de</label>
+               <label xml:lang="zh-hk">Name hk</label>
+               <label xml:lang="zh-cn">Name cn</label>
+               <label xml:lang="ru-ru">Name ru</label>
+               <label xml:lang="zh-tw">Name tw</label>
+               <label xml:lang="ja-jp">Name jp</label>
+               <label xml:lang="es-es">Name es</label>
+               <label xml:lang="el-gr">Name gr</label>
+               <label xml:lang="it-it">Name it</label>
+               <label xml:lang="tr-tr">Name tr</label>
+               <label xml:lang="pt-pt">Name pt</label>
+               <label xml:lang="fr-fr">Name fr</label>
+               <label xml:lang="kor-kr">Name kr</label>
+       </shortcut>
+       <shortcut appid="org.tizen.myapp" extra_key="key" extra_data="SERVICE INFORMATION 3">
+               <icon>/opt/usr/apps/org.tizen.myapp/res/icon/mayapp_shortcut02.png</icon>
+               <label>Default Name 03</label>
+               <label xml:lang="en-us">Name en</label>
+               <label xml:lang="nl-nl">Name nl</label>
+               <label xml:lang="de-de">Name de</label>
+               <label xml:lang="zh-hk">Name hk</label>
+               <label xml:lang="zh-cn">Name cn</label>
+               <label xml:lang="ru-ru">Name ru</label>
+               <label xml:lang="zh-tw">Name tw</label>
+               <label xml:lang="ja-jp">Name jp</label>
+               <label xml:lang="es-es">Name es</label>
+               <label xml:lang="el-gr">Name gr</label>
+               <label xml:lang="it-it">Name it</label>
+               <label xml:lang="tr-tr">Name tr</label>
+               <label xml:lang="pt-pt">Name pt</label>
+               <label xml:lang="fr-fr">Name fr</label>
+               <label xml:lang="kor-kr">Name kr</label>
+       </shortcut>
+</shortcut-list>
+</manifest>
diff --git a/src/main.c b/src/main.c
deleted file mode 100644 (file)
index ef4d76e..0000000
+++ /dev/null
@@ -1,791 +0,0 @@
-/*
- * Copyright 2012  Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
- *
- * 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 <stdlib.h>
-#include <pthread.h>
-#include <errno.h>
-#include <glib.h>
-#include <dlog.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include <secom_socket.h>
-#include <shortcut.h>
-
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-
-
-
-#define EAPI __attribute__((visibility("default")))
-
-
-
-extern int errno;
-
-
-
-struct server_cb {
-       request_cb_t request_cb;
-       void *data;
-};
-
-
-
-struct client_cb {
-       result_cb_t result_cb;
-       void *data;
-};
-
-
-
-static struct info {
-       pthread_mutex_t server_mutex;
-       int server_fd;
-       const char *socket_file;
-       struct server_cb server_cb;
-       unsigned int seq;
-} s_info = {
-       .server_mutex = PTHREAD_MUTEX_INITIALIZER,
-       .server_fd = -1,
-       .socket_file = "/tmp/.shortcut",
-       .seq = 0,
-};
-
-
-
-struct packet {
-       struct {
-               unsigned int seq;
-               enum {
-                       PACKET_ERR = 0x0,
-                       PACKET_REQ,
-                       PACKET_ACK,
-                       PACKET_MAX = 0xFF, /* MAX */
-               } type;
-
-               int payload_size;
-
-               union {
-                       struct {
-                               int shortcut_type;
-                               struct {
-                                       int pkgname;
-                                       int name;
-                                       int exec;
-                                       int icon;
-                               } field_size;
-                       } req;
-
-                       struct {
-                               int ret;
-                       } ack;
-               } data;
-       } head;
-
-       char payload[];
-};
-
-
-
-struct connection_state {
-       void *data;
-       struct packet packet;
-       enum {
-               BEGIN,
-               HEADER,
-               PAYLOAD,
-               END,
-               ERROR,
-       } state;
-       int length;
-       int from_pid;
-       char *payload;
-};
-
-
-
-static inline
-gboolean check_reply_service(int conn_fd, struct connection_state *state)
-{
-       struct client_cb *client_cb = state->data;
-
-       if (client_cb->result_cb) {
-               /* If the callback return FAILURE,
-                * remove itself from the callback list */
-               client_cb->result_cb(state->packet.head.data.ack.ret,
-                                       state->from_pid, client_cb->data);
-       }
-
-       state->state = BEGIN;
-       state->length = 0;
-       state->from_pid = 0;
-
-       /* NOTE: If we want close the connection, returns FALSE */
-       return FALSE;
-}
-
-
-
-static inline
-gboolean do_reply_service(int conn_fd, struct connection_state *state)
-{
-       int ret;
-       struct packet send_packet;
-
-       ret = -ENOSYS;
-       if (s_info.server_cb.request_cb) {
-               char *pkgname;
-               char *name;
-               char *exec;
-               char *icon;
-
-               if (state->packet.head.data.req.field_size.pkgname)
-                       pkgname = state->payload;
-               else
-                       pkgname = NULL;
-
-               if (state->packet.head.data.req.field_size.name)
-                       name = state->payload + state->packet.head.data.req.field_size.pkgname;
-               else
-                       name = NULL;
-
-               if (state->packet.head.data.req.field_size.exec) {
-                       exec = state->payload + state->packet.head.data.req.field_size.pkgname;
-                       exec += state->packet.head.data.req.field_size.name;
-               } else {
-                       exec = NULL;
-               }
-
-               if (state->packet.head.data.req.field_size.icon) {
-                       icon = state->payload + state->packet.head.data.req.field_size.pkgname;
-                       icon += state->packet.head.data.req.field_size.name;
-                       icon += state->packet.head.data.req.field_size.exec;
-               } else {
-                       icon = NULL;
-               }
-
-               LOGD("Pkgname: [%s] Type: [%x], Name: [%s], Exec: [%s], Icon: [%s]\n",
-                               pkgname,
-                               state->packet.head.data.req.shortcut_type,
-                               name,
-                               exec,
-                               icon);
-
-               ret = s_info.server_cb.request_cb(
-                               pkgname,
-                               name,
-                               state->packet.head.data.req.shortcut_type,
-                               exec,
-                               icon,
-                               state->from_pid,
-                               s_info.server_cb.data);
-       }
-
-       send_packet.head.type = PACKET_ACK;
-       send_packet.head.payload_size = 0;
-       send_packet.head.seq = state->packet.head.seq;
-       send_packet.head.data.ack.ret = ret;
-
-       if (secom_send(conn_fd, (const char*)&send_packet, sizeof(send_packet)) != sizeof(send_packet)) {
-               LOGE("Faield to send ack packet\n");
-               return FALSE;
-       }
-
-       state->state = BEGIN;
-       state->length = 0;
-       state->from_pid = 0;
-       return TRUE;
-}
-
-
-
-static inline
-gboolean filling_payload(int conn_fd, struct connection_state *state)
-{
-       if (state->length < state->packet.head.payload_size) {
-               int ret;
-               int check_pid;
-
-               ret = secom_recv(conn_fd,
-                       state->payload + state->length,
-                       state->packet.head.payload_size - state->length,
-                       &check_pid);
-               if (ret < 0)
-                       return FALSE;
-
-               if (state->from_pid != check_pid) {
-                       LOGD("PID is not matched (%d, expected %d)\n",
-                                               check_pid, state->from_pid);
-                       return FALSE;
-               }
-
-               state->length += ret;
-       }
-
-       if (state->length == state->packet.head.payload_size) {
-               state->length = 0;
-               state->state = END;
-       }
-
-       return TRUE;
-}
-
-
-
-static inline
-gboolean deal_error_packet(int conn_fd, struct connection_state *state)
-{
-       if (state->length < state->packet.head.payload_size) {
-               int ret;
-               char *buf;
-               int check_pid;
-
-               buf = alloca(state->packet.head.payload_size - state->length);
-
-               ret = secom_recv(conn_fd,
-                       buf,
-                       state->packet.head.payload_size - state->length,
-                       &check_pid);
-               if (ret < 0)
-                       return FALSE;
-
-               if (check_pid != state->from_pid)
-                       LOGD("PID is not matched (%d, expected %d)\n",
-                                               check_pid, state->from_pid);
-
-               state->length += ret;
-       }
-
-       if (state->length < state->packet.head.payload_size)
-               return TRUE;
-
-       /* Now, drop this connection */
-       return FALSE;
-}
-
-
-
-static inline
-gboolean filling_header(int conn_fd, struct connection_state *state)
-{
-       if (state->length < sizeof(state->packet)) {
-               int ret;
-               int check_pid;
-
-               ret = secom_recv(conn_fd,
-                       ((char*)&state->packet) + state->length, 
-                       sizeof(state->packet) - state->length,
-                       &check_pid);
-               if (ret < 0)
-                       return FALSE;
-
-               if (state->from_pid == 0)
-                       state->from_pid = check_pid;
-
-               if (state->from_pid != check_pid) {
-                       LOGD("PID is not matched (%d, expected %d)\n",
-                                               check_pid, state->from_pid);
-                       return FALSE;
-               }
-
-               state->length += ret;
-       }
-
-       if (state->length < sizeof(state->packet))
-               return TRUE;
-
-       if (state->packet.head.type == PACKET_ACK) {
-               state->length = 0;
-
-               if (state->packet.head.payload_size)
-                       state->state = ERROR;
-               else
-                       state->state = END;
-       } else if (state->packet.head.type == PACKET_REQ) {
-               /* Let's take the next part. */
-               state->state = PAYLOAD;
-               state->length = 0;
-
-               state->payload = calloc(1, state->packet.head.payload_size);
-               if (!state->payload) {
-                       LOGE("Heap: %s\n", strerror(errno));
-                       return FALSE;
-               }
-       } else {
-               LOGE("Invalid packet type\n");
-               return FALSE;
-       }
-
-       return TRUE;
-}
-
-
-
-static
-gboolean client_connection_cb(GIOChannel *src, GIOCondition cond, gpointer data)
-{
-       int conn_fd = -1;
-       gboolean ret;
-       int read_size;
-       struct connection_state *state = data;
-       struct client_cb *client_cb = state->data;
-
-       if (!(cond & G_IO_IN)) {
-               LOGE("Condition value is unexpected value\n");
-               ret = FALSE;
-               goto out;
-       }
-
-       conn_fd = g_io_channel_unix_get_fd(src);
-
-       if (ioctl(conn_fd, FIONREAD, &read_size) < 0) {
-               LOGE("Failed to get q size\n");
-               ret = FALSE;
-               goto out;
-       }
-
-       if (read_size == 0) {
-               if (client_cb->result_cb) {
-                       /* If the callback return FAILURE,
-                        * remove itself from the callback list */
-                       client_cb->result_cb(-ECONNABORTED,
-                                       state->from_pid, client_cb->data);
-               }
-               ret = FALSE;
-               goto out;
-       }
-
-       switch (state->state) {
-       case BEGIN:
-               state->state = HEADER;
-       case HEADER:
-               ret = filling_header(conn_fd, state);
-               break;
-       case ERROR:
-               ret = deal_error_packet(conn_fd, state);
-               break;
-       default:
-               ret = FALSE;
-               break;
-       }
-
-       if (state->state == END)
-               ret = check_reply_service(conn_fd, state);
-
-out:
-       if (ret == FALSE) {
-               if (conn_fd >= 0)
-                       close(conn_fd);
-               free(state->data);
-               free(state);
-       }
-
-       return ret;
-}
-
-
-
-static
-gboolean connection_cb(GIOChannel *src, GIOCondition cond, gpointer data)
-{
-       int conn_fd = -1;
-       struct connection_state *state = data;
-       gboolean ret;
-       int read_size;
-
-       if (!(cond & G_IO_IN)) {
-               ret = FALSE;
-               goto out;
-       }
-
-       conn_fd = g_io_channel_unix_get_fd(src);
-
-       if (ioctl(conn_fd, FIONREAD, &read_size) < 0) {
-               LOGE("Failed to get q size\n");
-               ret = FALSE;
-               goto out;
-       }
-
-       if (read_size == 0) {
-               LOGE("Disconnected\n");
-               ret = FALSE;
-               goto out;
-       }
-
-       switch (state->state) {
-       case BEGIN:
-               state->state = HEADER;
-       case HEADER:
-               ret = filling_header(conn_fd, state);
-               break;
-       case PAYLOAD:
-               ret = filling_payload(conn_fd, state);
-               break;
-       default:
-               LOGE("[%s:%d] Invalid state(%x)\n",
-                                       __func__, __LINE__, state->state);
-               ret = FALSE;
-               break;
-       }
-
-       if (state->state == END) {
-               ret = do_reply_service(conn_fd, state);
-               if (state->payload) {
-                       free(state->payload);
-                       state->payload = NULL;
-               }
-
-               memset(&state->packet, 0, sizeof(state->packet));
-       }
-
-out:
-       if (ret == FALSE) {
-               if (conn_fd >= 0)
-                       secom_put_connection_handle(conn_fd);
-
-               if (state->payload)
-                       free(state->payload);
-
-               free(state);
-       }
-
-       return ret;
-}
-
-
-
-static
-gboolean accept_cb(GIOChannel *src, GIOCondition cond, gpointer data)
-{
-       int server_fd;
-       int connection_fd;
-       GIOChannel *gio;
-       guint id;
-       struct connection_state *state;
-
-       server_fd = g_io_channel_unix_get_fd(src);
-       if (server_fd != s_info.server_fd) {
-               LOGE("Unknown FD is gotten.\n");
-               /* NOTE:
-                * In this case, don't try to do anything. 
-                * This is not recoverble error */
-               return FALSE;
-       }
-
-       if (!(cond & G_IO_IN)) {
-               close(s_info.server_fd);
-               if (pthread_mutex_lock(&s_info.server_mutex) != 0)
-                       LOGE("[%s:%d] Failed to get lock (%s)\n",
-                                               __func__, __LINE__, strerror(errno));
-               s_info.server_fd = -1;
-               if (pthread_mutex_unlock(&s_info.server_mutex) != 0)
-                       LOGE("[%s:%d] Failed to do unlock mutex (%s)\n",
-                                       __func__, __LINE__, strerror(errno));
-               return FALSE;
-       }
-
-       connection_fd = secom_get_connection_handle(server_fd);
-       if (connection_fd < 0) {
-               /* Error log will be printed from
-                * get_connection_handle function */
-               return FALSE;
-       }
-
-       if (fcntl(connection_fd, F_SETFD, FD_CLOEXEC) < 0)
-               LOGE("Error: %s\n", strerror(errno));
-
-       if (fcntl(connection_fd, F_SETFL, O_NONBLOCK) < 0)
-               LOGE("Error: %s\n", strerror(errno));
-
-       gio = g_io_channel_unix_new(connection_fd);
-       if (!gio) {
-               LOGE("Failed to create a new connection channel\n");
-               secom_put_connection_handle(connection_fd);
-               return FALSE;
-       }
-
-       state = calloc(1, sizeof(*state));
-       if (!state) {
-               LOGE("Heap: %s\n", strerror(errno));
-               secom_put_connection_handle(connection_fd);
-               return FALSE;
-       }
-
-       state->state = BEGIN;
-       id = g_io_add_watch(gio,
-                       G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-                       (GIOFunc)connection_cb, state);
-       if (id == 0) {
-               GError *err = NULL;
-               LOGE("Failed to create g_io watch\n");
-               free(state);
-               g_io_channel_unref(gio);
-               g_io_channel_shutdown(gio, TRUE, &err);
-               secom_put_connection_handle(connection_fd);
-               return FALSE;
-       }
-
-       g_io_channel_unref(gio);
-       return TRUE;
-}
-
-
-
-static inline int init_client(struct client_cb *client_cb,
-                                       const char *packet, int packet_size)
-{
-       GIOChannel *gio;
-       guint id;
-       int client_fd;
-       struct connection_state *state;
-
-       client_fd = secom_create_client(s_info.socket_file);
-       if (client_fd < 0) {
-               LOGE("Failed to make the client FD\n");
-               return -EFAULT;
-       }
-
-       if (fcntl(client_fd, F_SETFD, FD_CLOEXEC) < 0)
-               LOGE("Error: %s\n", strerror(errno));
-
-       if (fcntl(client_fd, F_SETFL, O_NONBLOCK) < 0)
-               LOGE("Error: %s\n", strerror(errno));
-
-       gio = g_io_channel_unix_new(client_fd);
-       if (!gio) {
-               close(client_fd);
-               return -EFAULT;
-       }
-
-       state = calloc(1, sizeof(*state));
-       if (!state) {
-               LOGE("Error: %s\n", strerror(errno));
-               close(client_fd);
-               return -ENOMEM;
-       }
-
-       state->data = client_cb;
-
-       id = g_io_add_watch(gio,
-               G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-               (GIOFunc)client_connection_cb, state);
-       if (id == 0) {
-               GError *err = NULL;
-               LOGE("Failed to create g_io watch\n");
-               free(state);
-               g_io_channel_unref(gio);
-               g_io_channel_shutdown(gio, TRUE, &err);
-               close(client_fd);
-               return -EFAULT;
-       }
-
-       g_io_channel_unref(gio);
-
-       if (secom_send(client_fd, packet, packet_size) != packet_size) {
-               GError *err = NULL;
-               LOGE("Failed to send all packet "
-                       "(g_io_channel is not cleared now\n");
-               free(state);
-               g_io_channel_shutdown(gio, TRUE, &err);
-               close(client_fd);
-               return -EFAULT;
-       }
-
-       return client_fd;
-}
-
-
-
-static inline
-int init_server(void)
-{
-       GIOChannel *gio;
-       guint id;
-
-       if (s_info.server_fd != -1) {
-               LOGE("Already initialized\n");
-               return 0;
-       }
-
-       if (pthread_mutex_lock(&s_info.server_mutex) != 0) {
-               LOGE("[%s:%d] Failed to get lock (%s)\n",
-                                       __func__, __LINE__, strerror(errno));
-               return -EFAULT;
-       }
-
-       unlink(s_info.socket_file);
-       s_info.server_fd = secom_create_server(s_info.socket_file);
-
-       if (s_info.server_fd < 0) {
-               LOGE("Failed to open a socket (%s)\n", strerror(errno));
-               if (pthread_mutex_unlock(&s_info.server_mutex) != 0)
-                       LOGE("[%s:%d] Failed to do unlock mutex (%s)\n",
-                                       __func__, __LINE__, strerror(errno));
-               return -EFAULT;
-       }
-
-       if (fcntl(s_info.server_fd, F_SETFD, FD_CLOEXEC) < 0)
-               LOGE("Error: %s\n", strerror(errno));
-
-       if (fcntl(s_info.server_fd, F_SETFL, O_NONBLOCK) < 0)
-               LOGE("Error: %s\n", strerror(errno));
-
-       gio = g_io_channel_unix_new(s_info.server_fd);
-       if (!gio) {
-               close(s_info.server_fd);
-               s_info.server_fd = -1;
-               if (pthread_mutex_unlock(&s_info.server_mutex) != 0)
-                       LOGE("[%s:%d] Failed to do unlock mutex (%s)\n",
-                                       __func__, __LINE__, strerror(errno));
-               return -EFAULT;
-       }
-
-       id = g_io_add_watch(gio,
-                       G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-                       (GIOFunc)accept_cb, NULL);
-       if (id == 0) {
-               GError *err = NULL;
-               LOGE("Failed to create g_io watch\n");
-               g_io_channel_unref(gio);
-               g_io_channel_shutdown(gio, TRUE, &err);
-               close(s_info.server_fd);
-               s_info.server_fd = -1;
-               if (pthread_mutex_unlock(&s_info.server_mutex) != 0)
-                       LOGE("[%s:%d] Failed to do unlock mutex (%s)\n",
-                                       __func__, __LINE__, strerror(errno));
-
-               return -EFAULT;
-       }
-
-       g_io_channel_unref(gio);
-
-       if (pthread_mutex_unlock(&s_info.server_mutex) != 0) {
-               GError *err = NULL;
-               g_io_channel_shutdown(gio, TRUE, &err);
-               LOGE("[%s:%d] Failed to do unlock mutex (%s)\n",
-                                       __func__, __LINE__, strerror(errno));
-               /* NOTE:
-                * We couldn't make a lock for this statements.
-                * We already meet the unrecoverble error
-                */
-               close(s_info.server_fd);
-               s_info.server_fd = -1;
-               return -EFAULT;
-       }
-
-       return 0;
-}
-
-
-
-EAPI int shortcut_set_request_cb(request_cb_t request_cb, void *data)
-{
-       int ret;
-       s_info.server_cb.request_cb = request_cb;
-       s_info.server_cb.data = data;
-
-       ret = init_server();
-       if (ret != 0) {
-               LOGE("Failed to initialize the server\n");
-       }
-
-       return ret;
-}
-
-
-
-EAPI int add_to_home_shortcut(const char *pkgname, const char *name, int type, const char *content_info, const char *icon, result_cb_t result_cb, void *data)
-{
-       struct packet *packet;
-       int pkgname_len;
-       int name_len;
-       int exec_len;
-       int icon_len;
-       int packet_size;
-       char *payload;
-       struct client_cb *client_cb;
-       int client_fd;
-
-       pkgname_len = pkgname ? strlen(pkgname) + 1 : 0;
-       name_len = name ? strlen(name) + 1 : 0;
-       exec_len = content_info ? strlen(content_info) + 1 : 0;
-       icon_len = icon ? strlen(icon) + 1 : 0;
-
-       packet_size = sizeof(*packet) + name_len + exec_len + icon_len + pkgname_len + 1;
-
-       packet = alloca(packet_size);
-       if (!packet) {
-               LOGE("Heap: %s\n", strerror(errno));
-               return -ENOMEM;
-       }
-
-       packet->head.seq = s_info.seq++;
-       packet->head.type = PACKET_REQ;
-       packet->head.data.req.shortcut_type = type;
-       packet->head.data.req.field_size.pkgname = pkgname_len;
-       packet->head.data.req.field_size.name = name_len;
-       packet->head.data.req.field_size.exec = exec_len;
-       packet->head.data.req.field_size.icon = icon_len;
-       packet->head.payload_size = pkgname_len + name_len + exec_len + icon_len + 1;
-
-       payload = packet->payload;
-
-       if (pkgname_len) {
-               strncpy(payload, pkgname, pkgname_len);
-               payload += pkgname_len;
-       }
-
-       if (name_len) {
-               strncpy(payload, name, name_len);
-               payload += name_len;
-       }
-
-       if (exec_len) {
-               strncpy(payload, content_info, exec_len);
-               payload += exec_len;
-       }
-
-       if (icon_len)
-               strncpy(payload, icon, icon_len);
-
-       client_cb = malloc(sizeof(*client_cb));
-       if (!client_cb) {
-               LOGE("Heap: %s\n", strerror(errno));
-               return -ENOMEM;
-       }
-
-       client_cb->result_cb = result_cb;
-       client_cb->data = data;
-
-       if (init_client(client_cb, (const char*)packet, packet_size) < 0) {
-               LOGE("Failed to init client FD\n");
-               free(client_cb);
-               return -EFAULT;
-       }
-
-       return 0;
-}
-
-EAPI int shortcut_add_to_home(const char *pkgname, const char *name, int type, const char *content_info, const char *icon, result_cb_t result_cb, void *data)
-{
-       return add_to_home_shortcut(pkgname, name, type, content_info, icon, result_cb, data);
-}
-
-
-
-/* End of a file */
diff --git a/src/secom_socket.c b/src/secom_socket.c
deleted file mode 100644 (file)
index 60bac2b..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright 2012  Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
- *
- * 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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <unistd.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <errno.h>
-
-#include <secom_socket.h>
-#include <dlog.h>
-
-
-
-extern int errno;
-
-
-
-inline static
-int create_socket(const char *peer, struct sockaddr_un *addr)
-{
-       int len;
-       int handle;
-
-       len = sizeof(struct sockaddr_un);
-       bzero(addr, len);
-
-       if (strlen(peer) >= sizeof(addr->sun_path)) {
-               LOGE("peer %s is too long to remember it\\n", peer);
-               return -1;
-       }
-
-       // We can believe this has no prob, because 
-       // we already check the size of add.rsun_path
-       strcpy(addr->sun_path, peer);
-       addr->sun_family = AF_UNIX;
-
-       handle = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
-       if (handle < 0) {
-               LOGE("Failed to create a socket %s\n", strerror(errno));
-               return -1;
-       }
-
-       return handle;
-}
-
-
-
-int secom_create_client(const char *peer)
-{
-       struct sockaddr_un addr;
-       int handle;
-       int state;
-       int on = 1;
-
-       handle = create_socket(peer, &addr);
-       if (handle < 0)
-               return handle;
-
-       state = connect(handle, (struct sockaddr*)&addr, sizeof(addr));
-       if (state < 0) {
-               LOGE("Failed to connect to server [%s] %s\n", peer, strerror(errno));
-               if (close(handle) < 0)
-                       LOGE("Failed to close a handle\n");
-
-               return -1;
-       }
-
-       if (setsockopt(handle, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0)
-               LOGE("Failed to change sock opt : %s\n", strerror(errno));
-
-       return handle;
-}
-
-
-
-int secom_create_server(const char *peer)
-{
-       int handle;
-       int state;
-       struct sockaddr_un addr;
-
-       handle = create_socket(peer, &addr);
-       if (handle < 0) return handle;
-
-       state = bind(handle, &addr, sizeof(addr));
-       if (state < 0) {
-               LOGE("Failed to bind a socket %s\n", strerror(errno));
-               if (close(handle) < 0) {
-                       LOGE("Failed to close a handle\n");
-               }
-               return -1;
-       }
-
-       state = listen(handle, 5);
-       if (state < 0) {
-               LOGE("Failed to listen a socket %s\n", strerror(errno));
-               if (close(handle) < 0) {
-                       LOGE("Failed to close a handle\n");
-               }
-               return -1;
-       }
-
-       if (chmod(peer, 0666) < 0) {
-               LOGE("Failed to change the permission of a socket (%s)\n", strerror(errno));
-       }
-
-       return handle;
-}
-
-
-
-int secom_get_connection_handle(int server_handle)
-{
-       struct sockaddr_un addr;
-       int handle;
-       int on = 1;
-       socklen_t size = sizeof(addr);
-
-       handle = accept(server_handle, (struct sockaddr*)&addr, &size);
-       if (handle < 0) {
-               LOGE("Failed to accept a new client %s\n", strerror(errno));
-               return -1;
-       }
-
-       if (setsockopt(handle, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
-               LOGE("Failed to change sock opt : %s\n", strerror(errno));
-       }
-
-       return handle;
-}
-
-
-
-int secom_put_connection_handle(int conn_handle)
-{
-       if (close(conn_handle) < 0) {
-               LOGE("Failed to close a handle\n");
-               return -1;
-       }
-       return 0;
-}
-
-
-
-int secom_send(int handle, const char *buffer, int size)
-{
-       struct msghdr msg;
-       struct iovec iov;
-       int ret;
-
-       memset(&msg, 0, sizeof(msg));
-       iov.iov_base = (char*)buffer;
-       iov.iov_len = size;
-       msg.msg_iov = &iov;
-       msg.msg_iovlen = 1;
-
-       ret = sendmsg(handle, &msg, 0);
-       if (ret < 0) {
-               LOGE("Failed to send message [%s]\n", strerror(errno));
-               return -1;
-       }
-       LOGD("Send done: %d\n", ret);
-
-       return iov.iov_len;
-}
-
-
-
-int secom_recv(int handle, char *buffer, int size, int *sender_pid)
-{
-       struct msghdr msg;
-       struct cmsghdr *cmsg;
-       struct iovec iov;
-       int _pid;
-       int ret;
-       char control[1024];
-
-       if (!sender_pid) sender_pid = &_pid;
-       *sender_pid = -1;
-
-       memset(&msg, 0, sizeof(msg));
-       iov.iov_base = buffer;
-       iov.iov_len = size;
-       msg.msg_iov = &iov;
-       msg.msg_iovlen = 1;
-       msg.msg_control = control;
-       msg.msg_controllen = sizeof(control);
-
-       ret = recvmsg(handle, &msg, 0);
-       if (ret < 0) {
-               LOGE("Failed to recvmsg [%s] (%d)\n", strerror(errno), ret);
-               return -1;
-       }
-
-       cmsg = CMSG_FIRSTHDR(&msg);
-       while (cmsg) {
-               if (cmsg->cmsg_level == SOL_SOCKET
-                       && cmsg->cmsg_type == SCM_CREDENTIALS)
-               {
-                       struct ucred *cred;
-                       cred = (struct ucred*)CMSG_DATA(cmsg);
-                       *sender_pid = cred->pid;
-               }
-
-               cmsg = CMSG_NXTHDR(&msg, cmsg);
-       }
-
-       return iov.iov_len;
-}
-
-
-
-int secom_destroy(int handle)
-{
-       if (close(handle) < 0) {
-               LOGE("Failed to close a handle\n");
-               return -1;
-       }
-       return 0;
-}
-
-
-
-#undef _GNU_SOURCE
-// End of a file
index 45201b2..abe5c1b 100644 (file)
@@ -1,3 +1,4 @@
 all:
-       @gcc homescreen.c -o homescreen `pkg-config ecore elementary shortcut --cflags --libs`
-       @gcc application.c -o application `pkg-config ecore elementary shortcut --cflags --libs`
+       @gcc homescreen.c -Wall -o homescreen `pkg-config ecore elementary shortcut --cflags --libs`
+       @gcc application.c -Wall -o application `pkg-config ecore elementary shortcut --cflags --libs`
+       @gcc shortcut.c -Wall -o shortcut `pkg-config ecore elementary shortcut --cflags --libs`
index fd1f3b7..563273e 100644 (file)
@@ -1,18 +1,19 @@
 /*
- * Copyright 2012  Samsung Electronics Co., Ltd
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Licensed under the Flora License, Version 1.0 (the "License");
+ * 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.tizenopensource.org/license
+ * 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 <Elementary.h>
 #include <shortcut.h>
@@ -28,9 +29,12 @@ static Eina_Bool shortcut_add_cb(void *data)
 {
        int ret;
 
-       ret = shortcut_add_to_home("MyName", 0, "/usr/bin/true", "/opt/share/image/what.png", result_cb, NULL);
+       ret = add_to_home_shortcut("pkgname", "MyName", 0, "/usr/bin/true", "/opt/share/image/what.png", result_cb, NULL);
        printf("Client: shortcut_add_to_home returns: %d\n", ret);
 
+       ret = add_to_home_livebox("pkgname", "MyName", 0, "/usr/bin/true", "/opt/share/image/what.png", 1.0f, result_cb, NULL);
+       printf("Client: shortcut_add_to_home_with_period returns: %d\n", ret);
+
        return ECORE_CALLBACK_RENEW;
 }
 
index 5a05357..68a221b 100644 (file)
@@ -1,32 +1,32 @@
 /*
- * Copyright 2012  Samsung Electronics Co., Ltd
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Licensed under the Flora License, Version 1.0 (the "License");
+ * 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.tizenopensource.org/license
+ * 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 <Elementary.h>
 #include <shortcut.h>
 
-int shortcut_request_cb(const char *name, int type, const char *exec, const char *icon, int pid, void *data)
+int shortcut_request_cb(const char *pkgname, const char *name, int type, const char *exec, const char *icon, int pid, double period, void *data)
 {
-       printf("SERVER: name: %s, type: %d, exec: %s, icon: %s, pid: %d, data: %p\n",
-               name, type, exec, icon, pid, data);
+       printf("SERVER: name: %s, type: %d, exec: %s, icon: %s, pid: %d, data: %p, period: %lf\n",
+               name, type, exec, icon, pid, data, period);
        return 0;
 }
 
 int elm_main(int argc, char *argv[])
 {
-       int ret;
        shortcut_set_request_cb(shortcut_request_cb, NULL);
 
        elm_run();
similarity index 50%
rename from include/secom_socket.h
rename to test/shortcut.c
index 3e6b7d6..d6c7012 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- */
+*/
 
+#include <Elementary.h>
+#include <shortcut.h>
 
-/*
- * Create client connection
- */
-extern int secom_create_client(const char *peer);
-
-/*
- * Create server connection
- */
-extern int secom_create_server(const char *peer);
-
-/*
- * Get the raw handle to use it for non-blocking mode.
- */
-extern int secom_get_connection_handle(int server_handle);
-extern int secom_put_connection_handle(int conn_handle);
+static int shortcut_list_cb(const char *appid, const char *icon, const char *name, const char *extra_key, const char *extra_data, void *data)
+{
+       printf("appid[%s] icon[%s], name[%s] extra_key[%s], extra_ata[%s]\n", appid, icon, name, extra_key, extra_data);
+       return 0;
+}
 
-/*
- * Send data to the connected peer.
- */
-extern int secom_send(int conn, const char *buffer, int size);
+int elm_main(int argc, char *argv[])
+{
+       int ret;
+       ret = shortcut_get_list(NULL, shortcut_list_cb, NULL);
+       if (ret < 0)
+               printf("Error: %d\n", ret);
 
-/*
- * Recv data from the connected peer. and its PID value
- */
-extern int secom_recv(int conn, char *buffer, int size, int *sender_pid);
+       elm_run();
+       elm_shutdown();
 
-/*
- * Destroy a connection
- */
-extern int secom_destroy(int conn);
+       return 0;
+}
 
+ELM_MAIN()
 /* End of a file */
diff --git a/test_db_builder.sh b/test_db_builder.sh
new file mode 100755 (executable)
index 0000000..bf9ede4
--- /dev/null
@@ -0,0 +1,80 @@
+#!/bin/sh
+#/*
+# * Copyright (c) 2000 - 2011 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.
+# *
+#*/
+
+DBFILE="/opt/dbspace/.shortcut_service.db"
+
+APPID=(
+"org.tizen.facebook"
+"org.tizen.facebook"
+"org.tizen.facebook"
+"org.tizen.facebook"
+"org.tizen.facebook"
+)
+
+ICON=(
+""
+""
+""
+""
+""
+)
+
+NAME=(
+"Friend's wall"
+"Groups"
+"Update status"
+"Like by me"
+"My wall"
+)
+
+KEY=(
+"livebox_shortcut_type"
+"livebox_shortcut_type"
+"livebox_shortcut_type"
+"livebox_shortcut_type"
+"livebox_shortcut_type"
+)
+
+VALUE=(
+"shortcut_friends"
+"shortcut_groups"
+"shortcut_post"
+"shortcut_like"
+"shortcut_me"
+)
+
+CNT=0
+ERR=0
+MAX=5
+
+sqlite3 $DBFILE "CREATE TABLE shortcut_service (id INTEGER PRIMARY KEY AUTOINCREMENT, appid TEXT, icon TEXT, name TEXT, extra_key TEXT, extra_data TEXT)"
+sqlite3 $DBFILE "CREATE TABLE shortcut_name (id INTEGER, lang TEXT, name TEXT)"
+while [ $CNT -lt $MAX ]
+do
+       echo "Insert a new record ('${APPID[$CNT]}', '${ICON[$CNT]}', '${NAME[$CNT]}', \"${KEY[$CNT]}\", \"${VALUE[$CNT]}\")"
+       sqlite3 $DBFILE "INSERT INTO shortcut_service (appid, icon, name, extra_key, extra_data) VALUES ('${APPID[$CNT]}', '${ICON[$CNT]}', \"${NAME[$CNT]}\", \"${KEY[$CNT]}\", \"${VALUE[$CNT]}\")" 2>/dev/null
+       if [ $? -ne 0 ]; then
+               let ERR=$ERR+1
+       fi
+       ID=`sqlite3 $DBFILE "SELECT id FROM shortcut_service WHERE appid = \"${APPID[$CNT]}\" AND extra_key = \"${KEY[$CNT]}\" AND extra_data = \"${VALUE[$CNT]}\""`
+       echo "Insert a name: \"${NAME[$CNT]}\""
+       sqlite3 $DBFILE "INSERT INTO shortcut_name (id, lang, name) VALUES ('$ID', 'en-us', \"${NAME[CNT]}\")"
+       let CNT=$CNT+1
+done
+
+echo "Error/Total: $ERR/$CNT"