Add initial companion service 68/223868/5
authorJihoon Kim <jihoon48.kim@samsung.com>
Tue, 4 Feb 2020 11:08:47 +0000 (20:08 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Thu, 6 Feb 2020 05:28:02 +0000 (14:28 +0900)
Change-Id: I2edf5681b4f6998d778e2c40b7a8c4fde17fc518
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
13 files changed:
CMakeLists.txt
companion/CMakeLists.txt [new file with mode: 0644]
companion/inc/ft.h [new file with mode: 0644]
companion/inc/log.h [new file with mode: 0644]
companion/inc/main.h [new file with mode: 0644]
companion/inc/sticker_info.h [new file with mode: 0644]
companion/org.tizen.sticker-consumer.manifest [new file with mode: 0644]
companion/res/xml/accessoryservices.xml [new file with mode: 0644]
companion/src/ft.cpp [new file with mode: 0644]
companion/src/main.cpp [new file with mode: 0644]
companion/src/sticker_info.cpp [new file with mode: 0644]
companion/tizen-manifest.xml [new file with mode: 0644]
packaging/capi-ui-sticker.spec

index e27150e..b03a770 100755 (executable)
@@ -46,5 +46,10 @@ ADD_SUBDIRECTORY(consumer)
 ## Sticker parser ##
 ADD_SUBDIRECTORY(sticker-parser)
 
+IF(DEFINED COMPANION_MODE)
+## Sticker companion service ##
+ADD_SUBDIRECTORY(companion)
+ENDIF()
+
 ## config ##
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/capi-ui-sticker.info DESTINATION ${TZ_SYS_RO_SHARE}/parser-plugins)
\ No newline at end of file
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/capi-ui-sticker.info DESTINATION ${TZ_SYS_RO_SHARE}/parser-plugins)
diff --git a/companion/CMakeLists.txt b/companion/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e326999
--- /dev/null
@@ -0,0 +1,43 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(sticker-consumer CXX)
+
+SET(SRCS
+       src/main.cpp
+       src/ft.cpp
+       src/sticker_info.cpp
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_test REQUIRED
+    capi-base-common
+    dlog
+    capi-appfw-service-application
+    sap-client-stub-api
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/companion/inc)
+
+FOREACH(flag ${pkgs_test_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+ADD_DEFINITIONS("-DEXPORTED=__attribute__((visibility(\"default\")))")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fPIE")
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_test_LDFLAGS} capi-ui-sticker-provider)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${TZ_SYS_RO_APP}/org.tizen.${PROJECT_NAME}/bin)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/companion/tizen-manifest.xml DESTINATION ${TZ_SYS_RO_PACKAGES} RENAME org.tizen.${PROJECT_NAME}.xml)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/companion/res/xml/accessoryservices.xml DESTINATION ${TZ_SYS_RO_APP}/org.tizen.${PROJECT_NAME}/res/xml)
diff --git a/companion/inc/ft.h b/companion/inc/ft.h
new file mode 100644 (file)
index 0000000..9aa4b9b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2020 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 <glib.h>
+
+#ifndef __FT_H__
+#define __FT_H__
+
+#if !defined(PACKAGE)
+#define PACKAGE "org.tizen.sticker-consumer"
+#endif
+
+#define GRP_MAIN "main"
+
+void     reject_file(void);
+void     accept_file(void);
+gboolean initialize_sap(void);
+
+void sap_file_transfer_get_receive_filepath(char **filepath);
+
+#endif /* __FT_H__ */
diff --git a/companion/inc/log.h b/companion/inc/log.h
new file mode 100644 (file)
index 0000000..df3f0b2
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __debug_H__
+#define __debug_H__
+
+#include <dlog.h>
+
+#ifndef  _LOG
+#define _LOG(logLevel, fmt, ...) do {           \
+       dlog_print(logLevel, LOG_TAG, "%s : %s(%d) > " fmt, rindex(__FILE__, '/')+1, __FUNCTION__, __LINE__, ##__VA_ARGS__);    \
+} while (0)
+#endif
+
+#ifndef  LOGD
+#define LOGD(format, arg...) _LOG(DLOG_DEBUG, format, ##arg)
+#endif
+
+#ifndef  LOGI
+#define LOGI(format, arg...) _LOG(DLOG_INFO, format, ##arg)
+#endif
+
+#ifndef  LOGW
+#define LOGW(format, arg...) _LOG(DLOG_WARN, format, ##arg)
+#endif
+
+#ifndef  LOGE
+#define LOGE(format, arg...) _LOG(DLOG_ERROR, format, ##arg)
+#endif
+
+#ifndef  LOGF
+#define LOGF(format, arg...) _LOG(DLOG_FATAL, format, ##arg)
+#endif
+
+#endif /* __debug_H__ */
+
diff --git a/companion/inc/main.h b/companion/inc/main.h
new file mode 100644 (file)
index 0000000..361bdd5
--- /dev/null
@@ -0,0 +1,14 @@
+#include <app_common.h>
+#include <dlog.h>
+#include <glib.h>
+
+#ifndef __MAIN_H__
+#define __MAIN_H__
+
+#define TAG "STICKER_CONSUMER"
+
+#if !defined(PACKAGE)
+#define PACKAGE "org.tizen.sticker-consumer"
+#endif
+
+#endif /* __MAIN_H__ */
diff --git a/companion/inc/sticker_info.h b/companion/inc/sticker_info.h
new file mode 100644 (file)
index 0000000..b06c885
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __STICKER_INFO_H__
+#define __STICKER_INFO_H__
+
+#define TAG "STICKER_CONSUMER"
+
+void insert_sticker_data(const char *filepath, const char *keyword, const char *group, const char *desc);
+void create_sticker_provider_handle(void);
+void destroy_sticker_provider_handle(void);
+
+#endif /* __STICKER_INF_H__ */
\ No newline at end of file
diff --git a/companion/org.tizen.sticker-consumer.manifest b/companion/org.tizen.sticker-consumer.manifest
new file mode 100644 (file)
index 0000000..017d22d
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+    <domain name="_"/>
+ </request>
+</manifest>
diff --git a/companion/res/xml/accessoryservices.xml b/companion/res/xml/accessoryservices.xml
new file mode 100644 (file)
index 0000000..6419f03
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources>
+       <application name="org.tizen.sticker-consumer">
+               <serviceProfile
+                               autoLaunchAppId="org.tizen.sticker-consumer"
+                               id="/sample/filetransfer"
+                               name="FileTransferReceiver"
+                               role="provider"
+                               version="2.0">
+                       <supportedTransports>
+                               <transport type="TRANSPORT_BT"/>
+                               <transport type="TRANSPORT_WIFI"/>
+                       </supportedTransports>
+                       <serviceChannel
+                               id="107"
+                               dataRate="low"
+                               priority="low"
+                               reliability="enable"/>
+               </serviceProfile>
+       </application>
+</resources>
diff --git a/companion/src/ft.cpp b/companion/src/ft.cpp
new file mode 100644 (file)
index 0000000..1cc0c38
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2020 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 <glib.h>
+#include <dlog.h>
+#include <app_common.h>
+#include <sap.h>
+#include <sap_file_transfer.h>
+#include <sticker_provider.h>
+#include <string.h>
+#include <string>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+
+#include "sticker_info.h"
+
+using namespace std;
+
+struct priv {
+       sap_agent_h agent;
+       sap_file_transaction_h socket;
+};
+
+static struct priv priv_data = { 0 };
+
+gboolean file_on_progress = 0;
+static string incoming_file_name;
+static string recv_filepath;
+
+static void _on_send_completed(sap_file_transaction_h file_transaction,
+                              sap_ft_transfer_e result,
+                              const char *file_path,
+                              void *user_data)
+{
+       char error_message[100];
+
+       dlog_print(DLOG_INFO, TAG, "# transfer completed");
+
+       if (priv_data.socket) {
+               sap_file_transfer_destroy(file_transaction);
+               priv_data.socket = NULL;
+       }
+
+       if (result == SAP_FT_TRANSFER_SUCCESS) {
+               sprintf(error_message, "Transfer Completed");
+               dlog_print(DLOG_INFO, TAG, "Transfer Completed");
+
+               if (chmod(recv_filepath.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
+                       dlog_print(DLOG_ERROR, TAG, "Failed to change permission : %s. error : %s", recv_filepath.c_str(), strerror(errno));
+               }
+               else {
+                       dlog_print(DLOG_INFO, TAG, "Succeed to change permission : %s", recv_filepath.c_str());
+                       create_sticker_provider_handle();
+                       insert_sticker_data(recv_filepath.c_str(), "keyword", "group", "test icon");
+                       destroy_sticker_provider_handle();
+               }
+       } else {
+               switch (result) {
+               case (SAP_FT_TRANSFER_FAIL_CHANNEL_IO): {
+                       sprintf(error_message, "Channel IO Error.");
+                       dlog_print(DLOG_WARN, TAG, "Channel IO Error.");
+                       break;
+               }
+
+               case (SAP_FT_TRANSFER_FAIL_FILE_IO): {
+                       sprintf(error_message, "File IO Error.");
+                       dlog_print(DLOG_WARN, TAG, "File IO Error.");
+                       break;
+               }
+
+               case (SAP_FT_TRANSFER_FAIL_CMD_DROPPED): {
+                       sprintf(error_message, "Transfer dropped.");
+                       dlog_print(DLOG_WARN, TAG, "Transfer dropped.");
+                       break;
+               }
+
+               case (SAP_FT_TRANSFER_FAIL_PEER_UNRESPONSIVE): {
+                       sprintf(error_message, "Peer Un Responsive.");
+                       dlog_print(DLOG_WARN, TAG, "Peer Un Responsive.");
+                       break;
+               }
+
+               case (SAP_FT_TRANSFER_FAIL_PEER_CONN_LOST): {
+                       sprintf(error_message, "Connection Lost.");
+                       dlog_print(DLOG_WARN, TAG, "Connection Lost.");
+                       break;
+               }
+
+               case (SAP_FT_TRANSFER_FAIL_PEER_CANCELLED): {
+                       sprintf(error_message, "Peer Cancelled.");
+                       dlog_print(DLOG_WARN, TAG, "Peer Cancelled.");
+                       break;
+               }
+
+               case (SAP_FT_TRANSFER_FAIL_SPACE_NOT_AVAILABLE): {
+                       sprintf(error_message, "No Space.");
+                       dlog_print(DLOG_WARN, TAG, "No Space.");
+                       break;
+               }
+
+               default:
+                       sprintf(error_message, "Unknown Error");
+                       dlog_print(DLOG_WARN, TAG, "Unknown Error");
+               }
+       }
+
+       file_on_progress = 0;
+}
+
+static void _on_sending_file_in_progress(sap_file_transaction_h file_transaction,
+                                        unsigned short int percentage_progress,
+                                        void *user_data)
+{
+       dlog_print(DLOG_INFO, TAG, "# progress %d", percentage_progress);
+}
+
+static void __set_file_transfer_cb(sap_file_transaction_h file_socket)
+{
+       dlog_print(DLOG_INFO, TAG, "# set callbacks");
+       sap_file_transfer_set_progress_cb(file_socket, _on_sending_file_in_progress, NULL);
+
+       sap_file_transfer_set_done_cb(file_socket, _on_send_completed, NULL);
+}
+
+void accept_file()
+{
+       int ret;
+       char file_path[100];
+       char *data_path = NULL;
+
+       data_path = app_get_shared_data_path();
+       dlog_print(DLOG_INFO, TAG, "Path : %s", data_path);
+       sprintf(file_path, "%s/%s", data_path, incoming_file_name.c_str());
+       dlog_print(DLOG_INFO, TAG, "Receive filepath : %s", file_path);
+       recv_filepath = string(file_path);
+       free(data_path);
+
+       ret = sap_file_transfer_receive(priv_data.socket, file_path);
+       switch(ret) {
+       case SAP_RESULT_PERMISSION_DENIED:
+               dlog_print(DLOG_WARN, TAG, "permission denied");
+               break;
+       case SAP_RESULT_FAILURE:
+               dlog_print(DLOG_WARN, TAG, "Fail");
+               break;
+       case SAP_RESULT_SUCCESS:
+               dlog_print(DLOG_INFO, TAG, "Success");
+               break;
+       }
+
+       file_on_progress = 1;
+}
+
+void sap_file_transfer_get_receive_filepath(char **filepath)
+{
+       *filepath = strdup(recv_filepath.c_str());
+}
+
+void reject_file()
+{
+       int ret = sap_file_transfer_reject(priv_data.socket);
+       dlog_print(DLOG_INFO, TAG, "ret : %d", ret);
+
+       file_on_progress = 0;
+}
+
+static void _on_receive_file_cb(sap_peer_agent_h peer_agent_h,
+                         sap_file_transaction_h socket,
+                         const char *file_path,
+                         void *user_data)
+{
+       file_on_progress = 1;
+       priv_data.socket = socket;
+       dlog_print(DLOG_INFO, TAG, "# incoming file request.");
+       __set_file_transfer_cb(priv_data.socket);
+
+       incoming_file_name = file_path;
+       std::size_t found = incoming_file_name.find_last_of("/");
+       incoming_file_name = incoming_file_name.substr(found+1);
+
+       dlog_print(DLOG_INFO, TAG, "# file path : %s, incoming file name : %s", file_path, incoming_file_name.c_str());
+
+       accept_file();
+}
+
+void conn_terminated(sap_peer_agent_h peer_agent,
+                    sap_socket_h socket,
+                    sap_service_connection_terminated_reason_e result,
+                    void *user_data)
+{
+       dlog_print(DLOG_INFO, TAG, "connection terminated");
+}
+
+void
+on_message_received(sap_peer_agent_h peer_agent, unsigned int payload_length, void *buffer,
+                void *user_data) /* message exchange on_receive callback (sap_agent_data_received_cb) */
+{
+       char *peer_app;
+       sap_peer_agent_get_app_name(peer_agent, &peer_app);
+       dlog_print(DLOG_INFO, TAG, "received data: %s, len:%d from %s", (char *)buffer, payload_length, peer_app);
+       g_free(peer_app);
+}
+
+void
+on_data_received(sap_socket_h socket, unsigned short int channel_id, unsigned int payload_length, void *buffer,
+                void *user_data) /* message exchange on_receive callback (sap_agent_data_received_cb) */
+{
+       dlog_print(DLOG_INFO, TAG, "received data: %s, len:%d", (char *)buffer, payload_length);
+}
+
+static void on_conn_req(sap_peer_agent_h peer_agent,
+                       sap_socket_h socket,
+                       sap_service_connection_result_e result,
+                       void *user_data)
+{
+       sap_peer_agent_accept_service_connection(peer_agent);
+       sap_peer_agent_set_service_connection_terminated_cb(peer_agent, conn_terminated, NULL);
+
+       sap_socket_set_data_received_cb(socket, on_data_received, peer_agent);
+}
+
+static void on_agent_initialized(sap_agent_h agent,
+                                sap_agent_initialized_result_e result,
+                                void *user_data)
+{
+       switch (result) {
+       case SAP_AGENT_INITIALIZED_RESULT_SUCCESS:
+
+               dlog_print(DLOG_DEBUG, TAG, "agent is initialized");
+
+               priv_data.agent = agent;
+
+               sap_file_transfer_set_incoming_file_cb(agent, _on_receive_file_cb, NULL);
+               sap_agent_set_service_connection_requested_cb(agent, on_conn_req, NULL);
+
+               break;
+
+       case SAP_AGENT_INITIALIZED_RESULT_DUPLICATED:
+               dlog_print(DLOG_ERROR, TAG, "duplicate registration");
+
+               break;
+
+       case SAP_AGENT_INITIALIZED_RESULT_INVALID_ARGUMENTS:
+               dlog_print(DLOG_ERROR, TAG, "invalid arguments");
+
+               break;
+
+       case SAP_AGENT_INITIALIZED_RESULT_INTERNAL_ERROR:
+               dlog_print(DLOG_ERROR, TAG, "internal sap error");
+
+               break;
+
+       default:
+               dlog_print(DLOG_ERROR, TAG, "unknown status (%d)", result);
+
+               break;
+       }
+}
+
+static void _on_device_status_changed(sap_device_status_e status,
+                                     sap_transport_type_e transport_type,
+                                     void *user_data)
+{
+       dlog_print(DLOG_DEBUG, TAG, "%s, status :%d", __func__, status);
+
+       switch (transport_type) {
+       case SAP_TRANSPORT_TYPE_BT:
+               dlog_print(DLOG_DEBUG, TAG, "transport_type (%d): bt", transport_type);
+               break;
+
+       case SAP_TRANSPORT_TYPE_BLE:
+               dlog_print(DLOG_DEBUG, TAG, "transport_type (%d): ble", transport_type);
+               break;
+
+       case SAP_TRANSPORT_TYPE_TCP:
+               dlog_print(DLOG_DEBUG, TAG, "transport_type (%d): tcp/ip", transport_type);
+               break;
+
+       case SAP_TRANSPORT_TYPE_USB:
+               dlog_print(DLOG_DEBUG, TAG, "transport_type (%d): usb", transport_type);
+               break;
+
+       case SAP_TRANSPORT_TYPE_MOBILE:
+               dlog_print(DLOG_DEBUG, TAG, "transport_type (%d): mobile", transport_type);
+               break;
+
+       default:
+               dlog_print(DLOG_ERROR, TAG, "unknown transport_type (%d)", transport_type);
+               break;
+       }
+
+       switch (status) {
+       case SAP_DEVICE_STATUS_DETACHED:
+               dlog_print(DLOG_DEBUG, TAG, "device is not connected.");
+               break;
+
+       case SAP_DEVICE_STATUS_ATTACHED:
+               dlog_print(DLOG_DEBUG, TAG, "Attached calling find peer now");
+               break;
+
+       default:
+               dlog_print(DLOG_ERROR, TAG, "unknown status (%d)", status);
+               break;
+       }
+}
+
+gboolean agent_initialize()
+{
+       int result = 0;
+
+       do {
+               result = sap_agent_initialize(priv_data.agent, "/sample/filetransfer", SAP_AGENT_ROLE_PROVIDER,
+                                             on_agent_initialized, NULL);
+
+               dlog_print(DLOG_DEBUG, TAG, "SAP >>> getRegisteredServiceAgent() >>> %d", result);
+       } while (result != SAP_RESULT_SUCCESS);
+
+       return TRUE;
+}
+
+gboolean initialize_sap(void)
+{
+       sap_agent_h agent = NULL;
+
+       sap_agent_create(&agent);
+
+       priv_data.agent = agent;
+
+       agent_initialize();
+
+       sap_set_device_status_changed_cb(_on_device_status_changed, NULL);
+
+       return TRUE;
+}
diff --git a/companion/src/main.cpp b/companion/src/main.cpp
new file mode 100644 (file)
index 0000000..3192e42
--- /dev/null
@@ -0,0 +1,44 @@
+#include "main.h"
+#include "ft.h"
+#include <app_common.h>
+#include <service_app.h>
+
+static bool app_create(void *data)
+{
+       /* Hook to take necessary actions before main event loop starts
+               Initialize UI resources and application's data
+               If this function returns true, the main loop of application starts
+               If this function returns false, the application is terminated */
+
+       initialize_sap();
+
+       return true;
+}
+
+static void app_control(app_control_h app_control, void *data)
+{
+       /* Handle the launch request. */
+}
+
+static void app_terminate(void *data)
+{
+       /* Release all resources. */
+}
+
+int main(int argc, char *argv[])
+{
+       int ret = 0;
+
+       service_app_lifecycle_callback_s event_callback;
+       memset(&event_callback, 0x0, sizeof(service_app_lifecycle_callback_s));
+
+       event_callback.create = (service_app_create_cb)app_create;
+       event_callback.terminate = (service_app_terminate_cb)app_terminate;
+       event_callback.app_control = (service_app_control_cb)app_control;
+
+       ret = service_app_main(argc, argv, &event_callback, NULL);
+       if (ret != APP_ERROR_NONE) {
+               dlog_print(DLOG_ERROR, TAG, "app_main() is failed. err = %d", ret);
+       }
+       return ret;
+}
diff --git a/companion/src/sticker_info.cpp b/companion/src/sticker_info.cpp
new file mode 100644 (file)
index 0000000..280b357
--- /dev/null
@@ -0,0 +1,106 @@
+#include "sticker_info.h"
+#include <sticker_provider.h>
+#include <dlog.h>
+#include <app_common.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static sticker_provider_h sticker_provider = NULL;
+
+sticker_data_h
+set_sticker_data(sticker_data_uri_type_e type, const char* uri, const char* keyword,
+int len, const char* group, const char* thumbnail, const char* description)
+{
+
+    sticker_data_h sticker_data;
+    int ret;
+
+    /* Creates a Sticker data handle */
+    ret = sticker_data_create(&sticker_data);
+    if (ret != STICKER_ERROR_NONE) {
+        /* Error handling */
+        dlog_print(DLOG_ERROR, TAG, "Failed to create sticker data");
+    }
+
+    /* Sets the URI and URI type of the sticker */
+    ret = sticker_data_set_uri(sticker_data, type, uri);
+    if (ret != STICKER_ERROR_NONE) {
+        /* Error handling */
+        dlog_print(DLOG_ERROR, TAG, "Failed to set uri");
+    }
+
+    //for (int i = 0; i < len; i++)
+    {
+        /* Adds a keyword of the sticker to the list */
+        ret = sticker_data_add_keyword(sticker_data, keyword);
+        if (ret != STICKER_ERROR_NONE) {
+            /* Error handling */
+            dlog_print(DLOG_ERROR, TAG, "Failed to add keyword");
+        }
+    }
+
+    /* Sets the group name of the sticker */
+    ret = sticker_data_set_group_name(sticker_data, group);
+    if (ret != STICKER_ERROR_NONE) {
+        /* Error handling */
+        dlog_print(DLOG_ERROR, TAG, "Failed to set group name");
+    }
+
+    /* Sets the thumbnail local path of the sticker */
+    if (thumbnail) {
+        ret = sticker_data_set_thumbnail(sticker_data, thumbnail);
+        if (ret != STICKER_ERROR_NONE) {
+            /* Error handling */
+            dlog_print(DLOG_ERROR, TAG, "Failed to set thumbnail");
+        }
+    }
+
+    /* Sets the description of the sticker */
+    ret = sticker_data_set_description(sticker_data, description);
+    if (ret != STICKER_ERROR_NONE) {
+        /* Error handling */
+        dlog_print(DLOG_ERROR, TAG, "Failed to set description");
+    }
+
+    return sticker_data;
+}
+
+void
+insert_sticker_data(const char *filepath, const char *keyword, const char *group, const char *desc)
+{
+    sticker_data_h data_handle;
+    int ret;
+
+    data_handle = set_sticker_data(STICKER_DATA_URI_LOCAL_PATH, filepath, keyword, 1, group, NULL, desc);
+
+    ret = sticker_provider_insert_data(sticker_provider, data_handle);
+    if (ret != STICKER_ERROR_NONE) {
+        dlog_print(DLOG_ERROR, TAG, "Failed to insert data. error code : %x. message : %s", ret, get_error_message(ret));
+    }
+    else {
+        dlog_print(DLOG_INFO, TAG, "Succeeded to insert data");
+    }
+
+    /* Destroys a sticker data handle */
+    ret = sticker_data_destroy(data_handle);
+    if (ret != STICKER_ERROR_NONE) {
+        /* Error handling */
+        dlog_print(DLOG_ERROR, TAG, "Failed to destroy sticker data");
+    }
+}
+
+void create_sticker_provider_handle(void)
+{
+    int ret;
+    ret = sticker_provider_create(&sticker_provider);
+    if (ret != STICKER_ERROR_NONE) {
+        /* Error handling */
+        dlog_print(DLOG_ERROR, TAG, "Failed to create sticker provider");
+    }
+}
+
+void destroy_sticker_provider_handle(void)
+{
+    sticker_provider_destroy(sticker_provider);
+    sticker_provider = NULL;
+}
\ No newline at end of file
diff --git a/companion/tizen-manifest.xml b/companion/tizen-manifest.xml
new file mode 100644 (file)
index 0000000..f5f784e
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="5.5" package="org.tizen.sticker-consumer" version="1.0.1">
+        <profile name="wearable" />
+        <service-application appid="org.tizen.sticker-consumer" exec="sticker-consumer" type="capp" multiple="false" taskmanage="false" nodisplay="true" launch_mode="single">
+        <label>sticker-consumer</label>
+                <metadata key="accessory-services-location" value="/res/xml/accessoryservices.xml"/>
+                <metadata key="launch-on-attach" value="false"/>
+                <background-category value="system"/>
+        </service-application>
+        <privileges>
+            <privilege>http://developer.samsung.com/tizen/privilege/accessoryprotocol</privilege>
+            <privilege>http://tizen.org/privilege/content.write</privilege>
+            <privilege>http://tizen.org/privilege/mediastorage</privilege>
+            <privilege>http://tizen.org/privilege/appdir.shareddata</privilege>
+        </privileges>
+        <category name="http://tizen.org/category/sticker"/>
+</manifest>
index 1efb809..c57ea60 100644 (file)
@@ -23,6 +23,16 @@ BuildRequires:  pkgconfig(json-glib-1.0)
 BuildRequires:  pkgconfig(libtzplatform-config)
 BuildRequires:  pkgconfig(pkgmgr-info)
 BuildRequires:  pkgconfig(sqlite3)
+
+%if 0%{?sec_product_feature_profile_wearable}
+BuildRequires:  pkgconfig(capi-base-common)
+BuildRequires:  pkgconfig(capi-appfw-service-application)
+BuildRequires:  pkgconfig(sap-client-stub-api)
+BuildRequires:  hash-signer
+
+Requires(post): signing-client
+%endif
+
 Requires:       security-config
 Requires(post): /sbin/ldconfig
 Requires(post): dbus
@@ -36,9 +46,24 @@ Summary:    Sticker client library and daemon (Development)
 Group:      Graphics & UI Framework/Input
 Requires:   %{name} = %{version}-%{release}
 
+%if 0%{?sec_product_feature_profile_wearable}
+%define _companion_app_name org.tizen.sticker-consumer
+
+%package -n %{_companion_app_name}
+Summary:    Sticker companion service
+Group:      Graphics & UI Framework/Input
+Requires:   %{name} = %{version}-%{release}
+%endif
+
+
 %description devel
 Sticker client library and daemon (Development)
 
+%if 0%{?sec_product_feature_profile_wearable}
+%description -n %{_companion_app_name}
+Sticker companion service
+%endif
+
 %if 0%{?gcov:1}
 %package gcov
 Summary:  Sticker client library and daemon (gcov)
@@ -63,8 +88,13 @@ export CFLAGS+=" -DTIZEN_DEBUG_ENABLE -fvisibility=hidden -Werror"
 export CXXFLAGS+=" -DTIZEN_DEBUG_ENABLE -fvisibility=hidden -Werror"
 export FFLAGS+=" -DTIZEN_DEBUG_ENABLE -fvisibility=hidden"
 
-%cmake . -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=%{_libdir} -DBINDIR=%{_bindir} -DINCLUDEDIR=%{_includedir} \
-         -DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE -DTZ_SYS_BIN=%TZ_SYS_BIN -DTZ_SYS_SHARE=%TZ_SYS_SHARE
+%cmake . \
+%if 0%{?sec_product_feature_profile_wearable}
+        -DCOMPANION_MODE=true \
+%endif
+         -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=%{_libdir} -DBINDIR=%{_bindir} -DINCLUDEDIR=%{_includedir} \
+         -DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE -DTZ_SYS_BIN=%TZ_SYS_BIN -DTZ_SYS_SHARE=%TZ_SYS_SHARE \
+         -DTZ_SYS_RO_APP=%TZ_SYS_RO_APP -DTZ_SYS_RO_PACKAGES=%TZ_SYS_RO_PACKAGES
 make %{?jobs:-j%jobs}
 
 %if 0%{?gcov:1}
@@ -90,6 +120,14 @@ mkdir -p %{buildroot}%{_datadir}/gcov/obj
 install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj
 %endif
 
+%if 0%{?sec_product_feature_profile_wearable}
+%define tizen_sign 1
+%define tizen_sign_base %{TZ_SYS_RO_APP}/%{_companion_app_name}
+%define tizen_sign_level public
+%define tizen_author_sign 1
+%define tizen_dist_sign 1
+%endif
+
 %post
 /sbin/ldconfig
 
@@ -98,6 +136,10 @@ chown -R ui_fw:ui_fw %{TZ_SYS_SHARE}/sticker-data
 chsmack -t %{TZ_SYS_SHARE}/sticker-data
 chsmack -a "System::Shared" %{TZ_SYS_SHARE}/sticker-data
 
+%if 0%{?sec_product_feature_profile_wearable}
+/usr/bin/signing-client/hash-signer-client.sh -a -d -p platform %{TZ_SYS_RO_APP}/%{_companion_app_name}
+%endif
+
 %postun -p /sbin/ldconfig
 
 %files
@@ -123,6 +165,13 @@ chsmack -a "System::Shared" %{TZ_SYS_SHARE}/sticker-data
 %{_includedir}/sticker_consumer.h
 %{_includedir}/sticker_provider.h
 
+%if 0%{?sec_product_feature_profile_wearable}
+%files -n %{_companion_app_name}
+%manifest companion/%{_companion_app_name}.manifest
+%{TZ_SYS_RO_PACKAGES}/%{_companion_app_name}.xml
+%{TZ_SYS_RO_APP}/%{_companion_app_name}/*
+%endif
+
 %if 0%{?gcov:1}
 %files gcov
 %{_datadir}/gcov/obj/*