summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJinkun Jang <jinkun.jang@samsung.com>2013-03-16 01:12:42 +0900
committerJinkun Jang <jinkun.jang@samsung.com>2013-03-16 01:12:42 +0900
commit11a58e2aed32893adf9d71c16914bcdbbe7836b4 (patch)
treef38613f2cfb6400941c1845b0622ddccb819babf
parent0a52e4e6079e7b2342c10e1a818bc5b6d8684b2c (diff)
downloadshortcut-11a58e2aed32893adf9d71c16914bcdbbe7836b4.tar.gz
shortcut-11a58e2aed32893adf9d71c16914bcdbbe7836b4.tar.bz2
shortcut-11a58e2aed32893adf9d71c16914bcdbbe7836b4.zip
merge with master
-rw-r--r--CMakeLists.txt50
-rw-r--r--debian/changelog6
-rw-r--r--debian/compat1
-rw-r--r--debian/control29
-rw-r--r--debian/dirs2
-rw-r--r--debian/libslp-shortcut-0.install.in1
-rw-r--r--debian/libslp-shortcut-dev.install.in3
-rwxr-xr-xdebian/rules114
-rw-r--r--lib/CMakeLists.txt49
-rw-r--r--lib/LICENSE (renamed from LICENSE)0
-rw-r--r--lib/include/shortcut.h (renamed from include/shortcut.h)91
-rw-r--r--lib/include/shortcut_PG.h (renamed from include/SLP_shortcut_PG.h)11
-rw-r--r--lib/shortcut.pc.in (renamed from shortcut.pc.in)1
-rw-r--r--lib/src/main.c776
-rw-r--r--libshortcut.manifest17
-rw-r--r--packaging/libshortcut.spec32
-rw-r--r--pkgmgr_shortcut/CMakeLists.txt31
-rw-r--r--pkgmgr_shortcut/include/dlist.h44
-rw-r--r--pkgmgr_shortcut/src/dlist.c181
-rw-r--r--pkgmgr_shortcut/src/service_register.c756
-rw-r--r--sample.xml62
-rw-r--r--src/main.c791
-rw-r--r--src/secom_socket.c245
-rw-r--r--test/Makefile5
-rw-r--r--test/application.c14
-rw-r--r--test/homescreen.c16
-rw-r--r--test/shortcut.c (renamed from include/secom_socket.h)47
-rwxr-xr-xtest_db_builder.sh80
28 files changed, 2136 insertions, 1319 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c2e1079..ea60a32 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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
index 0bfc7b0..0000000
--- a/debian/changelog
+++ /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
index 7ed6ff8..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-5
diff --git a/debian/control b/debian/control
deleted file mode 100644
index f8a7fda..0000000
--- a/debian/control
+++ /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
index ca882bb..0000000
--- a/debian/dirs
+++ /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
index a7c24c5..0000000
--- a/debian/libslp-shortcut-0.install.in
+++ /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
index 4430783..0000000
--- a/debian/libslp-shortcut-dev.install.in
+++ /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
index 6618431..0000000
--- a/debian/rules
+++ /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
index 0000000..0e27e2d
--- /dev/null
+++ b/lib/CMakeLists.txt
@@ -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})
diff --git a/LICENSE b/lib/LICENSE
index 9c13a9b..9c13a9b 100644
--- a/LICENSE
+++ b/lib/LICENSE
diff --git a/include/shortcut.h b/lib/include/shortcut.h
index b488faf..5edd598 100644
--- a/include/shortcut.h
+++ b/lib/include/shortcut.h
@@ -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
}
diff --git a/include/SLP_shortcut_PG.h b/lib/include/shortcut_PG.h
index eec5363..c3bd6c2 100644
--- a/include/SLP_shortcut_PG.h
+++ b/lib/include/shortcut_PG.h
@@ -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
diff --git a/shortcut.pc.in b/lib/shortcut.pc.in
index 9798259..8daf96d 100644
--- a/shortcut.pc.in
+++ b/lib/shortcut.pc.in
@@ -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
index 0000000..d485a53
--- /dev/null
+++ b/lib/src/main.c
@@ -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("[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#define ErrPrint(format, arg...) LOGE("[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#else
+extern FILE *__file_log_fp;
+#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
+
+#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [%s/%s:%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 */
diff --git a/libshortcut.manifest b/libshortcut.manifest
index a76fdba..f1055e7 100644
--- a/libshortcut.manifest
+++ b/libshortcut.manifest
@@ -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>
diff --git a/packaging/libshortcut.spec b/packaging/libshortcut.spec
index c04cf87..b53a521 100644
--- a/packaging/libshortcut.spec
+++ b/packaging/libshortcut.spec
@@ -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
index 0000000..0a4abc7
--- /dev/null
+++ b/pkgmgr_shortcut/CMakeLists.txt
@@ -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
index 0000000..f840f92
--- /dev/null
+++ b/pkgmgr_shortcut/include/dlist.h
@@ -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
index 0000000..a212608
--- /dev/null
+++ b/pkgmgr_shortcut/src/dlist.c
@@ -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
index 0000000..50b5ae2
--- /dev/null
+++ b/pkgmgr_shortcut/src/service_register.c
@@ -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("[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#define ErrPrint(format, arg...) LOGE("[%s/%s:%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
index 0000000..0e471a0
--- /dev/null
+++ b/sample.xml
@@ -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
index ef4d76e..0000000
--- a/src/main.c
+++ /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
index 60bac2b..0000000
--- a/src/secom_socket.c
+++ /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
diff --git a/test/Makefile b/test/Makefile
index 45201b2..abe5c1b 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -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`
diff --git a/test/application.c b/test/application.c
index fd1f3b7..563273e 100644
--- a/test/application.c
+++ b/test/application.c
@@ -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;
}
diff --git a/test/homescreen.c b/test/homescreen.c
index 5a05357..68a221b 100644
--- a/test/homescreen.c
+++ b/test/homescreen.c
@@ -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();
diff --git a/include/secom_socket.h b/test/shortcut.c
index 3e6b7d6..d6c7012 100644
--- a/include/secom_socket.h
+++ b/test/shortcut.c
@@ -13,38 +13,29 @@
* 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
index 0000000..bf9ede4
--- /dev/null
+++ b/test_db_builder.sh
@@ -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"