diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 67 | ||||
-rw-r--r-- | src/export.map | 1 | ||||
-rw-r--r-- | src/homescreen.c | 270 | ||||
-rw-r--r-- | src/hs-helper.c | 156 | ||||
-rw-r--r-- | src/hs-helper.h | 47 |
5 files changed, 541 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..5dcc0a5 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,67 @@ +# +# Copyright (c) 2017 TOYOTA MOTOR CORPORATION +# +# 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. +# + +cmake_minimum_required(VERSION 2.8) + +set(TARGETS_SMBINDER homescreen-service) + +INCLUDE(FindThreads) +FIND_PACKAGE(Threads) + +pkg_check_modules(hs_binding_depends afb-daemon glib-2.0 gio-2.0 gio-unix-2.0 json-c) +set(binding_hs_sources + homescreen.c + hs-helper.c) + +link_libraries(-Wl,--as-needed -Wl,--gc-sections -Wl,--no-undefined) + +add_library(${TARGETS_SMBINDER} MODULE ${binding_hs_sources}) + +target_compile_options(${TARGETS_SMBINDER} PRIVATE ${hs_binding_depends_CFLAGS}) +if(DEFINED DEBUGMODE) + target_compile_options(${TARGETS_SMBINDER} PRIVATE -g -O0) +else(DEFINED DEBUGMODE) + target_compile_options(${TARGETS_SMBINDER} PRIVATE -g -O2) +endif(DEFINED DEBUGMODE) + +target_include_directories(${TARGETS_SMBINDER} PRIVATE ${hs_binding_depends_INCLUDE_DIRS}) +target_link_libraries(${TARGETS_SMBINDER} ${CMAKE_THREAD_LIBS_INIT} ${link_libraries} ${hs_binding_depends_LIBRARIES}) + +# Binder exposes a unique public entry point + +set_target_properties(${TARGETS_SMBINDER} PROPERTIES + PREFIX "" + LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/export.map" + ) + +# installation directory +#INSTALL(TARGETS ${TARGETS_SMBINDER} +# LIBRARY DESTINATION ${binding_install_dir}) + +if(NOT EXISTS ${PROJECT_BINARY_DIR}/package) + add_custom_command(TARGET ${TARGETS_SMBINDER} POST_BUILD + COMMAND cp -rf ${PROJECT_SOURCE_DIR}/package ${PROJECT_BINARY_DIR} + ) +endif() + +add_custom_command(TARGET ${TARGETS_SMBINDER} POST_BUILD + COMMAND mkdir -p ${PROJECT_BINARY_DIR}/package/root/lib + COMMAND cp -rf ${PROJECT_BINARY_DIR}/src/${TARGETS_SMBINDER}.so ${PROJECT_BINARY_DIR}/package/root/lib +) + +add_custom_target(package DEPENDS ${PROJECT_BINARY_DIR}/package/root + COMMAND wgtpkg-pack -f -o ${PROJECT_BINARY_DIR}/package/${TARGETS_SMBINDER}-2017.wgt ${PROJECT_BINARY_DIR}/package/root +) diff --git a/src/export.map b/src/export.map new file mode 100644 index 0000000..f3961c0 --- /dev/null +++ b/src/export.map @@ -0,0 +1 @@ +{ global: afbBindingV*; local: *; };
\ No newline at end of file diff --git a/src/homescreen.c b/src/homescreen.c new file mode 100644 index 0000000..4a15861 --- /dev/null +++ b/src/homescreen.c @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2017 TOYOTA MOTOR CORPORATION + * + * 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 _GNU_SOURCE +#define AFB_BINDING_VERSION 2 +#include <afb/afb-binding.h> + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <json-c/json.h> +#include <glib.h> +#include <pthread.h> +#include "hs-helper.h" + +#define COMMAND_EVENT_NUM 3 +#define EVENT_SUBSCRIBE_ERROR_CODE 100 + +/* To Do hash table is better */ +struct event{ + const char* name; + struct afb_event* event; + }; + +static struct event event_list[COMMAND_EVENT_NUM]; + +static struct afb_event ev_tap_shortcut; +static struct afb_event ev_on_screen_message; +static struct afb_event ev_reserved; + +static const char _error[] = "error"; + +static const char _application_name[] = "application_name"; +static const char _display_message[] = "display_message"; + +/* +********** Method of HomeScreen Service (API) ********** +*/ + +static void pingSample(struct afb_req request) +{ + static int pingcount = 0; + afb_req_success_f(request, json_object_new_int(pingcount), "Ping count = %d", pingcount); + AFB_NOTICE("Verbosity macro at level notice invoked at ping invocation count = %d", pingcount); + pingcount++; +} + +/** + * HomeScreenから呼ばれる + * ショートカットがタップされたことをアプリケーションに通知するために使用する + * アプリケーションからは使用されない + * + * #### Parameters + * Request key + * - application_name : アプリケーション名 + * + * #### Return + * Nothing + * + */ +static void tap_shortcut (struct afb_req request) +{ + AFB_NOTICE("%s is called.", __FUNCTION__); + + int ret = 0; + const char* value = afb_req_value(request, _application_name); + if (value) { + + AFB_NOTICE("request params = %s.", value); + + struct json_object* push_obj = json_object_new_object(); + hs_add_object_to_json_object_str( push_obj, 2, + _application_name, value); + afb_event_push(ev_tap_shortcut, push_obj); + } else { + afb_req_fail_f(request, "failed", "called %s, Unknown palameter", __FUNCTION__); + return; + } + + // HomeScreenに返すレスポンス + struct json_object *res = json_object_new_object(); + hs_add_object_to_json_object_func(res, __FUNCTION__, 2, + _error, ret); + afb_req_success(request, res, "afb_event_push event [tap_shortcut]"); +} + +/** + * HomeScreenのOnScreenを表示する + * + * #### Parameters + * Request key + * - display_message : 表示したい文字列 + * + * #### Return + * Nothing + * + */ +static void on_screen_message (struct afb_req request) +{ + AFB_NOTICE("%s is called.", __FUNCTION__); + + int ret = 0; + const char* value = afb_req_value(request, _display_message); + if (value) { + + AFB_NOTICE("request params = %s.", value); + + struct json_object* push_obj = json_object_new_object(); + hs_add_object_to_json_object_str( push_obj, 2, + _display_message, value); + afb_event_push(ev_on_screen_message, push_obj); + } else { + afb_req_fail_f(request, "failed", "called %s, Unknown palameter", __FUNCTION__); + return; + } + + // HomeScreenに返すレスポンス + struct json_object *res = json_object_new_object(); + hs_add_object_to_json_object_func(res, __FUNCTION__, 2, + _error, ret); + afb_req_success(request, res, "afb_event_push event [on_screen_message]"); +} + +/** + * Subscribe event + * + * #### Parameters + * - event : Event name. Event list is written in libhomescreen.cpp + * + * #### Return + * Nothing + * + * #### Note + * + */ +static void subscribe(struct afb_req request) +{ + const char *value = afb_req_value(request, "event"); + AFB_NOTICE("value is %s", value); + int ret = 0; + if(value) { + int index = hs_search_event_name_index(value); + if(index < 0) + { + AFB_NOTICE("dedicated event doesn't exist"); + ret = EVENT_SUBSCRIBE_ERROR_CODE; + } + else + { + afb_req_subscribe(request, *event_list[index].event); + } + } + else{ + AFB_NOTICE("Please input event name"); + ret = EVENT_SUBSCRIBE_ERROR_CODE; + } + /*create response json object*/ + struct json_object *res = json_object_new_object(); + hs_add_object_to_json_object_func(res, __FUNCTION__, 2, + _error, ret); + afb_req_success_f(request, res, "homescreen binder subscribe event name [%s]", value); +} + +/** + * Unsubscribe event + * + * #### Parameters + * - event : Event name. Event list is written in libhomescreen.cpp + * + * #### Return + * Nothing + * + * #### Note + * + */ +static void unsubscribe(struct afb_req request) +{ + const char *value = afb_req_value(request, "event"); + AFB_NOTICE("value is %s", value); + int ret = 0; + if(value) { + int index = hs_search_event_name_index(value); + if(index < 0) + { + AFB_NOTICE("dedicated event doesn't exist"); + ret = EVENT_SUBSCRIBE_ERROR_CODE; + } + else + { + afb_req_unsubscribe(request, *event_list[index].event); + } + } + else{ + AFB_NOTICE("Please input event name"); + ret = EVENT_SUBSCRIBE_ERROR_CODE; + } + /*create response json object*/ + struct json_object *res = json_object_new_object(); + hs_add_object_to_json_object_func(res, __FUNCTION__, 2, + _error, ret); + afb_req_success_f(request, res, "homescreen binder unsubscribe event name [%s]", value); +} + +/* + * array of the verbs exported to afb-daemon + */ +static const struct afb_verb_v2 verbs[]= { + /* VERB'S NAME SESSION MANAGEMENT FUNCTION TO CALL */ + { .verb = "ping", .session = AFB_SESSION_NONE, .callback = pingSample, .auth = NULL }, + { .verb = "tap_shortcut", .session = AFB_SESSION_NONE, .callback = tap_shortcut, .auth = NULL }, + { .verb = "on_screen_message", .session = AFB_SESSION_NONE, .callback = on_screen_message, .auth = NULL }, + { .verb = "subscribe", .session = AFB_SESSION_NONE, .callback = subscribe, .auth = NULL }, + { .verb = "unsubscribe", .session = AFB_SESSION_NONE, .callback = unsubscribe, .auth = NULL }, + {NULL } /* marker for end of the array */ +}; + +static int preinit() +{ + AFB_NOTICE("binding preinit (was register)"); + return 0; +} + +static int init() +{ + AFB_NOTICE("binding init"); + + ev_tap_shortcut = afb_daemon_make_event(evlist[0]); + ev_on_screen_message = afb_daemon_make_event(evlist[1]); + ev_reserved = afb_daemon_make_event(evlist[2]); + + event_list[0].name = evlist[0]; + event_list[0].event = &ev_tap_shortcut; + + event_list[1].name = evlist[1]; + event_list[1].event = &ev_on_screen_message; + + event_list[2].name = evlist[2]; + event_list[2].event = &ev_reserved; + + return 0; +} + +static void onevent(const char *event, struct json_object *object) +{ + AFB_NOTICE("on_event %s", event); +} + +const struct afb_binding_v2 afbBindingV2 = { + .api = "homescreen", + .specification = NULL, + .verbs = verbs, + .preinit = preinit, + .init = init, + .onevent = onevent +}; diff --git a/src/hs-helper.c b/src/hs-helper.c new file mode 100644 index 0000000..3415510 --- /dev/null +++ b/src/hs-helper.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2017 TOYOTA MOTOR CORPORATION + * + * 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 "hs-helper.h" +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <json-c/json.h> +#include <stdarg.h> + +REQ_ERROR get_value_uint16(const struct afb_req request, const char *source, uint16_t *out_id) +{ + char* endptr; + const char* tmp = afb_req_value (request, source); + if(!tmp) + { + return REQ_FAIL; + } + long tmp_id = strtol(tmp,&endptr,10); + + /* error check of range */ + if( (tmp_id > UINT16_MAX) || (tmp_id < 0) ) + { + return OUT_RANGE; + } + if(*endptr != '\0') + { + return NOT_NUMBER; + } + + *out_id = (uint16_t)tmp_id; + return REQ_OK; +} + +REQ_ERROR get_value_int16(const struct afb_req request, const char *source, int16_t *out_id) +{ + char* endptr; + const char* tmp = afb_req_value (request, source); + if(!tmp) + { + return REQ_FAIL; + } + long tmp_id = strtol(tmp,&endptr,10); + + /* error check of range */ + if( (tmp_id > INT16_MAX) || (tmp_id < INT16_MIN) ) + { + return OUT_RANGE; + } + if(*endptr != '\0') + { + return NOT_NUMBER; + } + + *out_id = (int16_t)tmp_id; + return REQ_OK; +} + +REQ_ERROR get_value_int32(const struct afb_req request, const char *source, int32_t *out_id) +{ + char* endptr; + const char* tmp = afb_req_value (request, source); + if(!tmp) + { + return REQ_FAIL; + } + long tmp_id = strtol(tmp,&endptr,10); + + /* error check of range */ + if( (tmp_id > INT32_MAX) || (tmp_id < INT32_MIN) ) + { + return OUT_RANGE; + } + if(*endptr != '\0') + { + return NOT_NUMBER; + } + + *out_id = (int32_t)tmp_id; + return REQ_OK; +} + +void hs_add_object_to_json_object(struct json_object* j_obj, int count,...) +{ + va_list args; + va_start(args, count); + for(int i = 0; i < count; ++i ) + { + char *key = va_arg(args, char*); + int value = va_arg(args, int); + json_object_object_add(j_obj, key, json_object_new_int((int32_t)value)); + ++i; + } + va_end(args); +} + +void hs_add_object_to_json_object_str(struct json_object* j_obj, int count,...) +{ + va_list args; + va_start(args, count); + for(int i = 0; i < count; ++i ) + { + char *key = va_arg(args, char*); + char *value = va_arg(args, char*); + json_object_object_add(j_obj, key, json_object_new_string(value)); + ++i; + } + va_end(args); +} + + +void hs_add_object_to_json_object_func(struct json_object* j_obj, const char* verb_name, int count, ...) +{ + va_list args; + va_start(args, count); + + json_object_object_add(j_obj,"verb", json_object_new_string(verb_name)); + + for(int i = 0; i < count; ++i ) + { + char *key = va_arg(args, char*); + int value = va_arg(args, int); + json_object_object_add(j_obj, key, json_object_new_int((int32_t)value)); + ++i; + } + va_end(args); +} + +int hs_search_event_name_index(const char* value) +{ + size_t buf_size = 50; + size_t size = sizeof evlist / sizeof *evlist; + int ret = -1; + for(size_t i = 0 ; i < size ; ++i) + { + if(!strncmp(value, evlist[i], buf_size)) + { + ret = i; + break; + } + } + return ret; +} diff --git a/src/hs-helper.h b/src/hs-helper.h new file mode 100644 index 0000000..f6337d8 --- /dev/null +++ b/src/hs-helper.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 TOYOTA MOTOR CORPORATION + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HOMESCREEN_HELPER_H +#define HOMESCREEN_HELPER_H +#define AFB_BINDING_VERSION 2 +#include <afb/afb-binding.h> +#include <stdint.h> +#include <glib.h> +#include <errno.h> + +typedef enum REQ_ERROR +{ + REQ_FAIL = -1, + REQ_OK=0, + NOT_NUMBER, + OUT_RANGE +}REQ_ERROR; + +static const char* evlist[] = { + "tap_shortcut", + "on_screen_message", + "reserved" + }; + +REQ_ERROR get_value_uint16(const struct afb_req request, const char *source, uint16_t *out_id); +REQ_ERROR get_value_int16(const struct afb_req request, const char *source, int16_t *out_id); +REQ_ERROR get_value_int32(const struct afb_req request, const char *source, int32_t *out_id); +void hs_add_object_to_json_object(struct json_object* j_obj, int count, ...); +void hs_add_object_to_json_object_str(struct json_object* j_obj, int count, ...); +void hs_add_object_to_json_object_func(struct json_object* j_obj, const char* verb_name, int count, ...); +int hs_search_event_name_index(const char* value); + +#endif /*HOMESCREEN_HELPER_H*/ |