From: Ji-hoon Lee Date: Tue, 10 Sep 2024 11:28:43 +0000 (+0900) Subject: Sync with latest code X-Git-Tag: accepted/tizen/unified/20241001.004133~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b13bfdb093d339ff264abac598691e586e905427;p=platform%2Fcore%2Fuifw%2Fmmi-framework.git Sync with latest code Change-Id: I6ff802dcae3776e457c081499d9900dbe6dc8c93 --- diff --git a/capi/meson.build b/capi/meson.build deleted file mode 100644 index f4ce9ac..0000000 --- a/capi/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -install_headers( - 'mmi-primitive-value.h', - 'mmi-data.h', - 'mmi-attribute.h', - 'mmi-error.h', - 'mmi-workflow.h', - 'mmi-node.h', - 'mmi-node-source.h', - 'mmi-node-processor.h', - 'mmi-node-logic.h', - 'mmi-node-controller.h', - 'mmi-node-action.h', - 'mmi-node-custom.h', - 'mmi-port.h', - 'mmi-signal.h', - 'mmi-defines.h', - 'mmi-plugin-module.h', - 'mmi-plugin-storage.h', - 'mmi.h', - 'mmi-config-parser.h', - ) diff --git a/capi/mmi-attribute.h b/capi/mmi-attribute.h deleted file mode 100644 index c4a5205..0000000 --- a/capi/mmi-attribute.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_ATTRIBUTE_H__ -#define __TIZEN_UIX_MMI_ATTRIBUTE_H__ - - -#include "mmi-platform-config.h" -#include -#include - - -/** -* @file mmi-attribute.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct mmi_attribute_s* mmi_attribute_h; - - -int mmi_attribute_create(mmi_primitive_value_h value, const char *name, mmi_attribute_h *attribute); - -int mmi_attribute_set_name(mmi_attribute_h attribute, const char *name); - -int mmi_attribute_get_name(mmi_attribute_h attribute, char **name); - -int mmi_attribute_get_value(mmi_attribute_h attribute, mmi_primitive_value_h *value); - -int mmi_attribute_clone(mmi_attribute_h attribute, mmi_attribute_h *cloned); - -int mmi_attribute_destroy(mmi_attribute_h attribute); - -int mmi_attribute_to_bytes(mmi_attribute_h attribute, unsigned char **bytes, size_t *length); - -int mmi_attribute_from_bytes(const unsigned char *bytes, size_t length, mmi_attribute_h *attribute); - -/* Utility functions */ -int mmi_attribute_create_string_array(const char *name, const char *strings[], size_t count, mmi_attribute_h *attribute); - - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_ATTRIBUTE_H__ */ diff --git a/capi/mmi-config-parser.h b/capi/mmi-config-parser.h deleted file mode 100644 index 6c3fd31..0000000 --- a/capi/mmi-config-parser.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright © 2023 Samsung Electronics co., Ltd. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - - -#ifndef __MMI_CONFIG_PARSER_H_ -#define __MMI_CONFIG_PARSER_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct { - float confidence; -} mmi_config_s; - -int mmi_parser_initialize(void); -int mmi_parser_deinitialize(void); -int mmi_parser_get_confidence(float *confidence); - - -#ifdef __cplusplus -} -#endif - -#endif /* __MMI_CONFIG_PARSER_H_ */ diff --git a/capi/mmi-data.h b/capi/mmi-data.h deleted file mode 100644 index 01ee761..0000000 --- a/capi/mmi-data.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_DATA_H__ -#define __TIZEN_UIX_MMI_DATA_H__ - - -#include "mmi-platform-config.h" -#include - - -/** -* @file mmi-data.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef enum { - MMI_DATA_TYPE_BOOLEAN, - MMI_DATA_TYPE_INTEGER, - MMI_DATA_TYPE_FLOAT, - MMI_DATA_TYPE_TEXT, - MMI_DATA_TYPE_JSON, - MMI_DATA_TYPE_USER_IDENTIFICATION, - MMI_DATA_TYPE_AUDIO, - MMI_DATA_TYPE_VIDEO, - MMI_DATA_TYPE_COORDINATE, - MMI_DATA_TYPE_BOUNDING_BOX, - MMI_DATA_TYPE_ARRAY, - MMI_DATA_TYPE_STRUCT, - MMI_DATA_TYPE_ANY, -} mmi_data_type_e; - -/* Data Format */ -/* -- MMI_DATA_BOOLEAN - data : pointer to a byte - datalen : 1 byte - description : false if all bits are 0, true otherwise - -- MMI_DATA_INTEGER - data : pointer to a signed integer type - datalen : 4 bytes - description : cast 'data' to a 32-bit signed integer (e.g. int) - -- MMI_DATA_FLOAT - data : pointer to a floating-point type - datalen : 4 bytes - description : cast 'data' to a 32-bit floating-point type (e.g. float) - -- MMI_DATA_TEXT - data : pointer to a null-terminated string - datalen : length of the text - description : cast 'data' to a char* - -- MMI_DATA_JSON - data : pointer to a null-terminated string - datalen : length of the json string - description : cast 'data' to a char* - -- MMI_DATA_USER_IDENTIFICATION - data : pointer to a platform-dependent id for a user - datalen : platform-dependent - description : this value can be used to acquire platform-dependent user information - -- MMI_DATA_AUDIO - data : pointer to bytes - datalen : size of 'data' in bytes - format: - { - "bitrate" : 48000, - "format" : { - "signed" : true, - "bits" : 16 - }, - "channels" : 1 - } - description : audio frame data - -- MMI_DATA_VIDEO - data : pointer to bytes - datalen : size of 'data' in bytes - format: - { - "width":1920, - "height":1080, - "encoding":"mp4" - } - description : video frame data - -- MMI_DATA_COORDINATE - data : pointer to an array of 2 signed integers - datalen : 8 bytes - description : data is composed in below order - [ x , y ] - -- MMI_DATA_BOUNDING_BOX - data : pointer to an array of 4 signed integers - datalen : 16 bytes - description : data is composed in below order - [ x , y , w , h ] - -- MMI_DATA_ARRAY - data : pointer to an array of mmi_data_h struct - datalen : size of a pointer * number of items - description : A container that can hold multiple mmi_data_h with the same type. - -- MMI_DATA_STRUCT - data : pointer to an array of mmi_data_h struct - datalen : size of a pointer * number of items * 2 (one for key, one for value) - description : A container that can hold multiple mmi_data_h with different types. - A key is a MMI_DATA_TEXT that identifies the value. -- MMI_DATA_ANY - data : pointer to an mmi_data_h struct - datalen : size of a pointer - description : Represents a data type that can be any of the above types. -*/ - - - - -typedef struct mmi_data_timestamp_s *mmi_data_timestamp_h; - -typedef struct mmi_data_s *mmi_data_h; - -int mmi_data_create_bool(bool value, mmi_data_h *data); - -int mmi_data_create_int(int value, mmi_data_h *data); - -int mmi_data_create_float(float value, mmi_data_h *data); - -int mmi_data_create_text(const char *value, mmi_data_h *data); - -int mmi_data_create_audio(const void *ptr, size_t len, mmi_data_h *data); - -int mmi_data_create_video(const void *ptr, size_t len, mmi_data_h *data); - -int mmi_data_create_user_identification(const void *ptr, size_t len, mmi_data_h *data); - -int mmi_data_create_coordinate(int x, int y, mmi_data_h *data); - -int mmi_data_create_bounding_box(int x, int y, int w, int h, mmi_data_h *data); - -int mmi_data_create_array(mmi_data_h *array_handle); - -int mmi_data_add_array_element(mmi_data_h array_handle, mmi_data_h element); - -int mmi_data_create_struct(mmi_data_h *struct_handle); - -int mmi_data_set_struct_element(mmi_data_h struct_handle, const char *name, mmi_data_h element); - -int mmi_data_get_type(mmi_data_h data, mmi_data_type_e *type); - -int mmi_data_get_bool(mmi_data_h data, bool *value); - -int mmi_data_get_int(mmi_data_h data, int *value); - -int mmi_data_get_float(mmi_data_h data, float *value); - -int mmi_data_get_text(mmi_data_h data, const char **string); - -int mmi_data_get_audio(mmi_data_h data, const void **ptr, size_t *len); - -int mmi_data_get_video(mmi_data_h data, const void **ptr, size_t *len); - -int mmi_data_get_user_identification(mmi_data_h data, const void **ptr, size_t *len); - -int mmi_data_get_coordinate(mmi_data_h data, int *x, int *y); - -int mmi_data_get_bounding_box(mmi_data_h data, int *x, int *y, int *w, int *h); - -int mmi_data_get_array_count(mmi_data_h array, size_t *count); - -int mmi_data_get_array_element(mmi_data_h array, size_t index, mmi_data_h *element); - -int mmi_data_get_struct_element(mmi_data_h struct_handle, const char *name, mmi_data_h *element); - -int mmi_data_get_struct_count(mmi_data_h struct_handle, size_t *count); - -int mmi_data_get_struct_element_name(mmi_data_h struct_handle, size_t index, const char **string); - -int mmi_data_get_struct_element_value(mmi_data_h struct_handle, size_t index, mmi_data_h *element); - -int mmi_data_get_node_timestamp(mmi_data_h data, mmi_data_timestamp_h *timestamp); - -int mmi_data_get_source_timestamp(mmi_data_h data, mmi_data_timestamp_h *timestamp); - -int mmi_data_set_source_timestamp(mmi_data_h data, mmi_data_timestamp_h timestamp); - -int mmi_data_to_bytes(mmi_data_h data, unsigned char **bytes, size_t *length); - -int mmi_data_from_bytes(unsigned char *bytes, size_t length, mmi_data_h *data); - -int mmi_data_destroy(mmi_data_h data); - - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_DATA_H__ */ diff --git a/capi/mmi-defines.h b/capi/mmi-defines.h deleted file mode 100644 index e8d26ad..0000000 --- a/capi/mmi-defines.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_DEFINES_H__ -#define __TIZEN_UIX_MMI_DEFINES_H__ - - -/** -* @file mmi-defines.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define MMI_NAME_MAX_LENGTH 32 -#define MMI_PARAMETER_MAX_COUNT 32 -#define MMI_PORT_MAX_COUNT 32 -#define MMI_NODE_MAX_COUNT 128 -#define MMI_LINK_MAX_COUNT 128 -#define MMI_OUTPUT_MAX_COUNT 32 -#define MMI_WORKFLOW_MAX_COUNT 64 - - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_DEFINES_H__ */ diff --git a/capi/mmi-error.h b/capi/mmi-error.h deleted file mode 100644 index 3e8bd45..0000000 --- a/capi/mmi-error.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_ERROR_H__ -#define __TIZEN_UIX_MMI_ERROR_H__ - - -#include "mmi-platform-config.h" - - -/** -* @file mmi-error.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef enum { - MMI_ERROR_NONE = PLATFORM_ERROR_NONE, /**< Successful */ - MMI_ERROR_OUT_OF_MEMORY = PLATFORM_ERROR_OUT_OF_MEMORY, /**< Out of Memory */ - MMI_ERROR_IO_ERROR = PLATFORM_ERROR_IO_ERROR, /**< I/O error */ - MMI_ERROR_INVALID_PARAMETER = PLATFORM_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ - MMI_ERROR_TIMED_OUT = PLATFORM_ERROR_TIMED_OUT, /**< No answer from the daemon */ - MMI_ERROR_PERMISSION_DENIED = PLATFORM_ERROR_PERMISSION_DENIED, /**< Permission denied */ - MMI_ERROR_NOT_SUPPORTED = PLATFORM_ERROR_NOT_SUPPORTED, /**< MMI NOT supported */ - MMI_ERROR_OPERATION_FAILED = PLATFORM_ERROR_OPERATION_FAILED, /**< Operation failed */ - MMI_ERROR_RESOURCE_BUSY = PLATFORM_ERROR_RESOURCE_BUSY, /**< Resource busy */ -} mmi_error_e; - - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_ERROR_H__ */ diff --git a/capi/mmi-node-action.h b/capi/mmi-node-action.h deleted file mode 100644 index 1141c46..0000000 --- a/capi/mmi-node-action.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_NODE_ACTION_H__ -#define __TIZEN_UIX_MMI_NODE_ACTION_H__ - - - -#include - -/** -* @file mmi-node-action.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - - -enum mmi_node_action_type_e { - MMI_NODE_ACTION_TYPE_NONE, - - /* - Description : Emits a mouse event - - Attributes : - - "EVENT" : string - Default : "CLICK" - Description : The type of mouse event to emit - Supported values are : "CLICK", "DOWN", "UP" - - Input Port 1 - Name : "COORDINATE" - Data Type : MMI_DATA_TYPE_COORDINATE - Description : When a coordinate data is received, emits a mouse event - */ - MMI_NODE_ACTION_TYPE_MOUSE_EVENT, - - MMI_NODE_ACTION_TYPE_KEY_EVENT, -}; - -int mmi_node_create_action(mmi_node_action_type_e type, mmi_node_h *node); - -int mmi_node_get_action_type(mmi_node_h node, mmi_node_action_type_e *type); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_NODE_LOGIC_H__ */ diff --git a/capi/mmi-node-controller.h b/capi/mmi-node-controller.h deleted file mode 100644 index 03eb074..0000000 --- a/capi/mmi-node-controller.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_NODE_CONTROLLER_H__ -#define __TIZEN_UIX_MMI_NODE_CONTROLLER_H__ - - - -#include - -/** -* @file mmi-node-controller.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - - -enum mmi_node_controller_type_e { - MMI_NODE_CONTROLLER_TYPE_NONE, - - /* - Description : Turns the node with a name specified in the attribute "TARGET" on or off - - Attributes : - "TARGET" : string - - Input Port 1 - Name : "VALUE" - Data Type : MMI_DATA_TYPE_BOOLEAN - */ - MMI_NODE_CONTROLLER_TYPE_SWITCH, -}; - -int mmi_node_create_controller(mmi_node_controller_type_e type, mmi_node_h *node); - -int mmi_node_get_controller_type(mmi_node_h node, mmi_node_controller_type_e *type); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_NODE_LOGIC_H__ */ diff --git a/capi/mmi-node-custom.h b/capi/mmi-node-custom.h deleted file mode 100644 index d2f9bdc..0000000 --- a/capi/mmi-node-custom.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_NODE_CUSTOM_H__ -#define __TIZEN_UIX_MMI_NODE_CUSTOM_H__ - - - -#include - -/** -* @file mmi-node-custom.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - -int mmi_node_create_custom(const char *custom_type_id, mmi_node_h *node); - -int mmi_node_get_custom_type(mmi_node_h node, const char **custom_type_id); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_NODE_CUSTOM_H__ */ diff --git a/capi/mmi-node-logic.h b/capi/mmi-node-logic.h deleted file mode 100644 index 13ef9ad..0000000 --- a/capi/mmi-node-logic.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_NODE_LOGIC_H__ -#define __TIZEN_UIX_MMI_NODE_LOGIC_H__ - - - -#include - -/** -* @file mmi-node-logic.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - - -enum mmi_node_logic_type_e { - MMI_NODE_LOGIC_TYPE_NONE, - - /* - - Description : Compares the text received from the input port 1 ("TEXT") with - 1) the fixed strings specified in the attribute "CANDIDATES" - 2) the array of texts received from input port 2 ("TEXT_ARRAY") - 3) the array of structs received from input port 3 ("STRUCT_ARRAY"), - for the element specified in the attribute "COMPARAND_STRUCT_ELEMENT" - ex) if the struct has two elements named "label" and "text", and - "COMPARAND_STRUCT_ELEMENT" is "label", then the value of - "label" will be compared with the text received from input port 1 - And outputs the mmi_data_t to the corresponding OUT port when matched. - ex1) if the text received from input port 1 is "Hello", and the fixed strings - specified in the attribute "CANDIDATES" is ["Hello", "World"], then the - text "Hello" will be sent to output port 1. - ex2) if the text received from input port 1 is "Hello", and the array of texts - received from input port 2 is ["Hello", "World", "Goodbye"], then the - text "Hello" will be sent to output port 2. - ex3) if the text received from input port 1 is "Hello", with the attribute - "COMPARAND_STRUCT_ELEMENT" set to "label", and the array of structs - received from input port 3 is like below, - [ - {"label":"Hello"}, - {"label":"World"}, - {"label":"Goodbye"} - ] - then the struct {"label":"Hello"} will be sent to output port 3. - - Attributes : - "CANDIDATES" : array [ string ] - "COMPARAND_STRUCT_ELEMENT" : string - - Input Port 1 - Name : "TEXT" - Data Type : MMI_DATA_TYPE_TEXT - - Input Port 2 - Name : "TEXT_ARRAY" - Data Type : MMI_DATA_TYPE_ARRAY [ MMI_DATA_TYPE_TEXT ] - - Input Port 3 - Name : "STRUCT_ARRAY" - Data Type : MMI_DATA_TYPE_ARRAY [ MMI_DATA_TYPE_STRUCT ] - - Output Port 1 - Name : "MATCHED_CANDIDATE" - Data Type : MMI_DATA_TYPE_TEXT - - Output Port 2 - Name : "MATCHED_TEXT_ARRAY" - Data Type : MMI_DATA_TYPE_TEXT - - Output Port 3 - Name : "MATCHED_STRUCT_ARRAY" - Data Type : MMI_DATA_TYPE_STRUCT - */ - MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, - - /* - - Description : Tests if the regex strings specified in the attribute "REGEX" with - 1) the text received from the input port 1 ("TEXT") matches - 2) the array of texts received from input port 2 ("TEXT_ARRAY") - 3) the array of structs received from input port 3 ("STRUCT_ARRAY"), - for the element specified in the attribute "COMPARAND_STRUCT_ELEMENT" - - Attributes : - "REGEX" : array [ string ] - "COMPARAND_STRUCT_ELEMENT" : string - - Input Port 1 - Name : "TEXT" - Data Type : MMI_DATA_TYPE_TEXT - - Input Port 2 - Name : "TEXT_ARRAY" - Data Type : MMI_DATA_TYPE_ARRAY [ MMI_DATA_TYPE_TEXT ] - - Input Port 3 - Name : "STRUCT_ARRAY" - Data Type : MMI_DATA_TYPE_ARRAY [ MMI_DATA_TYPE_STRUCT ] - - Output Port 1 - Name : "MATCHED_TEXT" - Data Type : MMI_DATA_TYPE_TEXT - - Output Port 2 - Name : "MATCHED_TEXT_ARRAY" - Data Type : MMI_DATA_TYPE_TEXT - - Output Port 3 - Name : "MATCHED_STRUCT_ARRAY" - Data Type : MMI_DATA_TYPE_STRUCT - */ - MMI_NODE_LOGIC_TYPE_REGEX_STRING_MATCH, - - - /* - - Description : Compares the User Recognition Struct from each input ports - and selects the one with the highest score. - - Input Port 1 - Name : "Port1" - Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT - Format of MMI_DATA_TYPE_STRUCT : - - "USER" : MMI_DATA_TYPE_USER_IDENTIFICATION - - "SCORE" : MMI_DATA_TYPE_FLOAT - - Input Port 2 - Name : "Port2" - Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT - Format of MMI_DATA_TYPE_STRUCT : - - "USER" : MMI_DATA_TYPE_USER_IDENTIFICATION - - "SCORE" : MMI_DATA_TYPE_FLOAT - - Output Port 1 - Name : "BYPASS_RESULT" - Data Type : MMI_DATA_TYPE_USER_IDENTIFICATION - - Output Port 2 - Name : "COMPARISON_RESULT" - Data Type : MMI_DATA_TYPE_USER_IDENTIFICATION - */ - MMI_NODE_LOGIC_TYPE_USER_COMPARISON, -}; - -int mmi_node_create_logic(mmi_node_logic_type_e type, mmi_node_h *node); - -int mmi_node_get_logic_type(mmi_node_h node, mmi_node_logic_type_e *type); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_NODE_LOGIC_H__ */ diff --git a/capi/mmi-node-processor.h b/capi/mmi-node-processor.h deleted file mode 100644 index a864e47..0000000 --- a/capi/mmi-node-processor.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_NODE_PROCESSOR_H__ -#define __TIZEN_UIX_MMI_NODE_PROCESSOR_H__ - - - -#include - -/** -* @file mmi-node-processor.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - - -enum mmi_node_processor_type_e { - MMI_NODE_PROCESSOR_TYPE_NONE, - - /* - - Attributes : None - - Input Port 1 - Name : "AUDIO" - Data Type : MMI_DATA_TYPE_AUDIO - - Output Port 1 - Name : "PARTIAL" - Data Type : MMI_DATA_TYPE_TEXT - - Output Port 2 - Name : "FINAL" - Data Type : MMI_DATA_TYPE_TEXT - */ - MMI_NODE_PROCESSOR_TYPE_ASR, - - /* - - Attributes : None - - Input Port 1 - Name : "VIDEO_IN" - Data Type : MMI_DATA_TYPE_VIDEO - - Output Port 1 - Name : "VIDEO_OUT" - Data Type : MMI_DATA_TYPE_VIDEO - */ - MMI_NODE_PROCESSOR_TYPE_VIDEO_CONVERTER, - - /* - - Attributes : None - - Input Port 1 - Name : "VIDEO" - Data Type : MMI_DATA_TYPE_VIDEO - - Output Port 1 - Name : "MATCHED_FACES" - Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT - Format of MMI_DATA_TYPE_STRUCT : - - "USER" : MMI_DATA_TYPE_USER_IDENTIFICATION - - "SCORE" : MMI_DATA_TYPE_FLOAT - */ - MMI_NODE_PROCESSOR_TYPE_FACE_RECOGNITION, - - /* - - Attributes : None - - Input Port 1 - Name : "AUDIO" - Data Type : MMI_DATA_TYPE_AUDIO - - Output Port 1 - Name : "MATCHED_SPEAKERS" - Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT - Format of MMI_DATA_TYPE_STRUCT : - - "USER" : MMI_DATA_TYPE_USER_IDENTIFICATION - - "SCORE" : MMI_DATA_TYPE_FLOAT - */ - MMI_NODE_PROCESSOR_TYPE_SPEAKER_RECOGNITION, - - /* - - Attributes : - "GRID_CONFIGURATION" : array [ integer ] - - Input Port 1 - Name : "SCREEN_INFO" - Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT - MMI_DATA_TYPE STRUCT format: { - "coord_x": MMI_DATA_TYPE_INT, - "coord_y": MMI_DATA_TYPE_INT, - "width": MMI_DATA_TYPE_INT, - "height": MMI_DATA_TYPE_INT, - "object_id": MMI_DATA_TYPE_TEXT, - "label": MMI_DATA_TYPE_TEXT, - "role": MMI_DATA_TYPE_TEXT, - } - - Input Port 2 - Name : "MODE_COMMANDS" - Data Type : MMI_DATA_TYPE_TEXT - - Input Port 3 - Name : "UTTERANCE" - Data Type : MMI_DATA_TYPE_TEXT - - Output Port 1 - Name : "CANDIDATES" - Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT - MMI_DATA_TYPE STRUCT format: { - "mode": MMI_DATA_TYPE_INT, - "coord_x": MMI_DATA_TYPE_INT, - "coord_y": MMI_DATA_TYPE_INT, - "width": MMI_DATA_TYPE_INT, - "height": MMI_DATA_TYPE_INT, - "label": MMI_DATA_TYPE_TEXT, - } - - Output Port 2 - Name : "MATCHED_RESULT" - Data Type : MMI_DATA_TYPE_STRUCT - MMI_DATA_TYPE STRUCT format: { - "candidate_info": MMI_DATA_TYPE_STRUCT { - "mode": MMI_DATA_TYPE_INT, - "coord_x": MMI_DATA_TYPE_INT, - "coord_y": MMI_DATA_TYPE_INT, - "width": MMI_DATA_TYPE_INT, - "height": MMI_DATA_TYPE_INT, - "label": MMI_DATA_TYPE_TEXT, - }, - "click_info": MMI_DATA_TYPE_STRUCT { - "x": MMI_DATA_TYPE_INT, - "y": MMI_DATA_TYPE_INT, - "object_id": MMI_DATA_TYPE_TEXT, - } - } - - Output Port 3 - Name : "REJECTED" - Data Type : MMI_DATA_TYPE_TEXT - */ - MMI_NODE_PROCESSOR_TYPE_VOICE_TOUCH, - - /* - - Attributes : None - - Input Port 1 - Name : "AUDIO" - Data Type : MMI_DATA_TYPE_AUDIO - - Output Port 1 - Name : "DETECTED_BOS" - Data Type : MMI_DATA_TYPE_BOOLEAN - - Output Port 2 - Name : "DETECTED_EOS" - Data Type : MMI_DATA_TYPE_BOOLEAN - */ - MMI_NODE_PROCESSOR_TYPE_VOICE_ACTIVITY_DETECTOR, -}; - -int mmi_node_create_processor(mmi_node_processor_type_e type, mmi_node_h *node); - -int mmi_node_get_processor_type(mmi_node_h node, mmi_node_processor_type_e *type); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_NODE_PROCESSOR_H__ */ diff --git a/capi/mmi-node-source.h b/capi/mmi-node-source.h deleted file mode 100644 index a78fc89..0000000 --- a/capi/mmi-node-source.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_NODE_SOURCE_H__ -#define __TIZEN_UIX_MMI_NODE_SOURCE_H__ - - - -#include - -/** -* @file mmi-node-source.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - -enum mmi_node_source_type_e { - MMI_NODE_SOURCE_TYPE_NONE, - - /* - - Description : A microphone that captures sound all the time. - - Attributes : - - "UNFOCUSED_ONLY" : bool - Default : false - Description : If true, the node will be activated only when there is - no other application currently acquired sound focus. - - Output Port 1 - Name : "AUDIO" - Type : OUT - Data Type : MMI_DATA_TYPE_AUDIO - */ - MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, - - /* - - Description : A camera that captures video. - - Output Port 1 - Name : "VIDEO" - Type : OUT - Data Type : MMI_DATA_TYPE_VIDEO - */ - MMI_NODE_SOURCE_TYPE_CAMERA, - - /* - - Description : A screen analyzer that gets screen info when rescanning occur. - // FIXME: temporary attribute for replacing signal - - Attributes : - - "RESCANNING" : bool - Default : false - Description : If true, the node will rescan the screen and make screen info - - Output Port 1 - Name : "SCREEN_INFO" - Type : OUT - Data Type : MMI_DATA_TYPE_ARRAY of MMI_DATA_TYPE_STRUCT - MMI_DATA_TYPE STRUCT format: { - "coord_x": MMI_DATA_TYPE_INT, - "coord_y": MMI_DATA_TYPE_INT, - "width": MMI_DATA_TYPE_INT, - "height": MMI_DATA_TYPE_INT, - "object_id": MMI_DATA_TYPE_TEXT, - "label": MMI_DATA_TYPE_TEXT, - "role": MMI_DATA_TYPE_TEXT, - } - */ - MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER, -}; - -int mmi_node_create_source(mmi_node_source_type_e type, mmi_node_h *node); - -int mmi_node_get_source_type(mmi_node_h node, mmi_node_source_type_e *type); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_NODE_SOURCE_H__ */ diff --git a/capi/mmi-node.h b/capi/mmi-node.h deleted file mode 100644 index 14e0501..0000000 --- a/capi/mmi-node.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_NODE_H__ -#define __TIZEN_UIX_MMI_NODE_H__ - - -#include "mmi-platform-config.h" - -#include -#include -#include -#include -#include - -/** -* @file mmi-node.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - -enum mmi_node_type_e { - MMI_NODE_TYPE_NONE, - MMI_NODE_TYPE_SOURCE, - MMI_NODE_TYPE_PROCESSOR, - MMI_NODE_TYPE_LOGIC, - MMI_NODE_TYPE_CONTROLLER, - MMI_NODE_TYPE_ACTION, - MMI_NODE_TYPE_CUSTOM, -}; - -typedef void* mmi_node_instance_h; - -typedef int (*mmi_node_initialized_cb)(mmi_node_instance_h instance); -typedef int (*mmi_node_deinitialized_cb)(mmi_node_instance_h instance); -typedef int (*mmi_node_attribute_set_cb)(mmi_node_instance_h instance, mmi_attribute_h attribute); -typedef int (*mmi_node_activated_cb)(mmi_node_instance_h instance); -typedef int (*mmi_node_deactivated_cb)(mmi_node_instance_h instance); -typedef int (*mmi_node_signal_received_cb)(mmi_node_instance_h instance, mmi_signal_h signal); - -typedef struct { - mmi_node_initialized_cb initialized_cb; - mmi_node_deinitialized_cb deinitialized_cb; - mmi_node_attribute_set_cb attribute_set_cb; - mmi_node_activated_cb activated_cb; - mmi_node_deactivated_cb deactivated_cb; - mmi_node_signal_received_cb signal_received_cb; -} mmi_node_callbacks; - -typedef struct { - mmi_node_type_e type; - int sub_type; - char custom_type_id[MMI_NAME_MAX_LENGTH]; - mmi_port_h *ports; - size_t port_count; - mmi_node_callbacks callbacks; -} mmi_node_s; - -typedef mmi_node_s* mmi_node_h; - -/* Adds a static port to a static node. The port has to be already created before calling this function. */ -int mmi_node_add_port(mmi_node_h node, mmi_port_h port); - -/* Finds a port in a node matching the given name and type. */ -int mmi_node_find_port(mmi_node_h node, mmi_port_type_e port_type, const char *port_name, mmi_port_h *port); - -/* Retrieves the type of a node. */ -int mmi_node_get_type(mmi_node_h node, mmi_node_type_e *type); - -/* Retrieves the number of ports in a node. */ -int mmi_node_get_port_count(mmi_node_h node, size_t *port_count); - -/* Retrieves the port at the given index. */ -int mmi_node_get_port(mmi_node_h node, size_t index, mmi_port_h *port); - -/* Get the callbacks of a node */ -int mmi_node_get_callbacks(mmi_node_h node, mmi_node_callbacks *callbacks); - -/* Set the callbacks of a node */ -int mmi_node_set_callbacks(mmi_node_h node, mmi_node_callbacks callbacks); - -/* Registers a node. */ -int mmi_node_register(mmi_node_h node); - -/* Clones a node. */ -int mmi_node_clone(mmi_node_h node, mmi_node_h *cloned); - -/* Destroys a node. */ -int mmi_node_destroy(mmi_node_h node); - -/* Provide a attribute to a node instance. */ -int mmi_node_instance_set_attribute(mmi_node_instance_h instance, mmi_attribute_h attribute); - -/* Provide a attribute bundle to a node instance. */ -//int mmi_node_instance_attribute_bundle_set(mmi_node_instance_h instance, mmi_attribute_bundle_h bundle); - -/* Retrieve a port instance of a node instance. */ -int mmi_node_instance_find_port(mmi_node_instance_h instance, mmi_port_type_e port_type, const char *port_name, mmi_port_instance_h *port); - -/* Retrieve a sibiling port instance of a port instance in a node, that matches the given name. */ -int mmi_node_instance_find_sibling_port(mmi_port_instance_h instance, const char *sibling_name, mmi_port_instance_h *sibling); - -/* Emits a signal from a node instance. */ -int mmi_node_instance_emit_signal(mmi_node_instance_h instance, mmi_signal_h signal); - -/* If the correct result could not be returned on last activate_cb() call, it needs to be updated afterwards using this function. */ -int mmi_node_instance_update_pending_activation_result(mmi_error_e result); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_NODE_H__ */ diff --git a/capi/mmi-plugin-module.h b/capi/mmi-plugin-module.h deleted file mode 100644 index 7581a15..0000000 --- a/capi/mmi-plugin-module.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_PLUGIN_MODULE_H__ -#define __TIZEN_UIX_MMI_PLUGIN_MODULE_H__ - - -#include - -/** -* @file mmi-plugin-module.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - -/* If a plugin module wants to provide Nodes to mmi framework, - * it should implement a function named "mmi_plugin_module_get_node_list", - * with the following prototype. */ -#define MMI_PLUGIN_MODULE_GET_NODE_LIST_FUNC_NAME "mmi_plugin_module_get_node_list" -typedef void (*mmi_plugin_module_get_node_list_func)(); - -/* If a plugin module wants to provide Workflows to mmi framework, - * it should implement a function named "mmi_plugin_module_get_workflow_list", - * with the following prototype. */ -#define MMI_PLUGIN_MODULE_GET_WORKFLOW_LIST_FUNC_NAME "mmi_plugin_module_get_workflow_list" -typedef void (*mmi_plugin_module_get_workflow_list_func)(); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_PLUGIN_MODULE_H__ */ diff --git a/capi/mmi-plugin-storage.h b/capi/mmi-plugin-storage.h deleted file mode 100644 index 97e97b6..0000000 --- a/capi/mmi-plugin-storage.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__ -#define __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** -* @file mmi-plugin-storage.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - -/* The functions and structs below are used by MMI framework */ - -typedef struct { - mmi_node_h *nodes; - size_t node_count; -} mmi_plugin_module_node_list_s; - -typedef struct { - mmi_workflow_h *workflows; - size_t workflow_count; -} mmi_plugin_module_workflow_list_s; - - -typedef struct { - char name[MMI_NAME_MAX_LENGTH]; - mmi_port_instance_h port; -} mmi_plugin_module_port_instance_info_s; - -typedef struct { - mmi_node_instance_h node; - mmi_plugin_module_port_instance_info_s port_infos[MMI_PORT_MAX_COUNT]; - size_t port_info_count; -} mmi_plugin_module_node_instance_info_s; - -typedef void (*mmi_plugin_module_port_instance_output_handler_func)( - mmi_port_instance_h port, mmi_data_h data, void *user_data); - -typedef void (*mmi_plugin_module_switch_node_event_handler_func)( - mmi_node_instance_h node, const char *controllee, bool state, void *user_data); - -typedef struct { - mmi_plugin_module_port_instance_output_handler_func port_instance_output_handler; - mmi_plugin_module_switch_node_event_handler_func switch_node_event_handler; -} mmi_plugin_module_event_handler_info_s; - -/* MMI Manager will invoke this function to set the current identifier of the plugin module. */ -void mmi_plugin_storage_set_current_module_identifier(const char *identifier); - -/* Each plugin modules will call this functino to get the current identifier of the plugin module. */ -const char* mmi_plugin_storage_get_current_module_identifier(); - -/* Each plugin modules will call these functions to register their nodes and workflows. */ -void mmi_plugin_storage_set_node_list(mmi_plugin_module_node_list_s node_list); -void mmi_plugin_storage_set_workflow_list(mmi_plugin_module_workflow_list_s workflow_list); - -/* MMI Manager will invoke these functions to get the node list of the plugin module. */ -mmi_plugin_module_node_list_s mmi_plugin_storage_get_node_list(const char *identifier); -mmi_plugin_module_workflow_list_s mmi_plugin_storage_get_workflow_list(const char *identifier); - -/* MMI Manager will invoke these function to notify the node instance addition and removal. */ -void mmi_plugin_storage_add_node_instance_info(mmi_plugin_module_node_instance_info_s *info); -void mmi_plugin_storage_remove_node_instance_info(mmi_node_instance_h node_instance); - -/* Each plugin modules will call this function to find appropriate port instance */ -mmi_port_instance_h mmi_plugin_storage_find_port_instance( - mmi_node_instance_h node_instance, const char *port_name); -mmi_node_instance_h mmi_plugin_storage_find_node_instance_by_port_instance(mmi_port_instance_h port_instance); - -/* MMI Manager will invoke these function to register / unregister the event handlers */ -void mmi_plugin_storage_set_plugin_module_event_handler( - mmi_plugin_module_event_handler_info_s handler_info, void *user_data); -void mmi_plugin_storage_unset_plugin_module_event_handler(); - -/* Each plugin modules will call this function to notify the plugin module events */ -mmi_plugin_module_event_handler_info_s mmi_plugin_storage_get_plugin_module_event_handler(); -void* mmi_plugin_storage_get_plugin_module_event_handler_user_data(); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__ */ diff --git a/capi/mmi-port.h b/capi/mmi-port.h deleted file mode 100644 index 23963fb..0000000 --- a/capi/mmi-port.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_PORT_H__ -#define __TIZEN_UIX_MMI_PORT_H__ - - -#include "mmi-platform-config.h" - -#include -#include -#include - -/** -* @file mmi-port.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - -enum mmi_port_type_e { - MMI_PORT_TYPE_IN, - MMI_PORT_TYPE_OUT -}; - -typedef void* mmi_port_instance_h; - -typedef int (*mmi_port_output_format_requested_cb)(mmi_port_instance_h instance, const char *format); -typedef int (*mmi_port_input_data_received_cb)(mmi_port_instance_h instance, mmi_data_h data); - -typedef struct { - mmi_port_output_format_requested_cb output_format_requested_cb; - mmi_port_input_data_received_cb input_data_received_cb; -} mmi_port_callbacks; - -typedef struct { - char name[MMI_NAME_MAX_LENGTH]; - mmi_port_type_e type; - mmi_data_type_e data_type; - mmi_port_callbacks callbacks; -} mmi_port_s; - -typedef mmi_port_s* mmi_port_h; - -/* Create a port */ -int mmi_port_create(mmi_port_h *port); - -/* Get the name of a port */ -int mmi_port_get_name(mmi_port_h port, char **name, size_t *length); - -/* Get the type of a port */ -int mmi_port_get_type(mmi_port_h port, mmi_port_type_e *type); - -/* Get the data type of a port */ -int mmi_port_get_data_type(mmi_port_h port, mmi_data_type_e *data_type); - -/* Get the callbacks of a port */ -int mmi_port_get_callbacks(mmi_port_h port, mmi_port_callbacks *callbacks); - -/* Set the name of a port */ -int mmi_port_set_name(mmi_port_h port, const char *name); - -/* Set the type of a port */ -int mmi_port_set_type(mmi_port_h port, mmi_port_type_e type); - -/* Set the data type of a port */ -int mmi_port_set_data_type(mmi_port_h port, mmi_data_type_e data_type); - -/* Set the callbacks of a port */ -int mmi_port_set_callbacks(mmi_port_h port, mmi_port_callbacks callbacks); - -/* Clones a port */ -int mmi_port_clone(mmi_port_h port, mmi_port_h *cloned); - -/* Destroy a port */ -int mmi_port_destroy(mmi_port_h port); - -/* Provide a link information between two static ports. */ -// int mmi_port_link(mmi_port_h out, mmi_port_h in); - -/* Registers a port with the given type, data type, and callbacks. */ -// int mmi_port_register(mmi_port_type_e port_type, mmi_data_type_e data_type, mmi_port_callbacks *callbacks, mmi_port_h port); - -/* Generates data to the port with the given port instance. */ -int mmi_port_instance_generate_output(mmi_port_instance_h instance, mmi_data_h data); - -/* Requests the port instance to transform the data to the given format. */ -int mmi_port_instance_request_auto_transform(mmi_port_instance_h instance, const char *from_format, const char *to_format); - -/* Requests the port instance to retrieve the data with the given format. */ -int mmi_port_instance_request_input_data_format(mmi_port_instance_h instance, const char *format); - -/* Announce the data format to the port instance. */ -int mmi_port_instance_announce_output_data_format(mmi_port_instance_h instance, const char *format); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_PORT_H__ */ diff --git a/capi/mmi-primitive-value.h b/capi/mmi-primitive-value.h deleted file mode 100644 index 8679ca8..0000000 --- a/capi/mmi-primitive-value.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_PRIMITIVE_VALUE_H__ -#define __TIZEN_UIX_MMI_PRIMITIVE_VALUE_H__ - - -#include "mmi-platform-config.h" -#include - - -/** -* @file mmi-primitive-value.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef enum { - MMI_PRIMITIVE_VALUE_TYPE_INT, - MMI_PRIMITIVE_VALUE_TYPE_FLOAT, - MMI_PRIMITIVE_VALUE_TYPE_STRING, - MMI_PRIMITIVE_VALUE_TYPE_BOOL, - MMI_PRIMITIVE_VALUE_TYPE_ARRAY, -} mmi_primitive_value_type_e; - - -typedef struct mmi_primitive_value_s* mmi_primitive_value_h; - - -int mmi_primitive_value_create_int(int data, mmi_primitive_value_h *handle); - -int mmi_primitive_value_create_float(float data, mmi_primitive_value_h *handle); - -int mmi_primitive_value_create_string(const char *data, mmi_primitive_value_h *handle); - -int mmi_primitive_value_create_bool(bool data, mmi_primitive_value_h *handle); - -int mmi_primitive_value_create_array(mmi_primitive_value_h *handle); - -int mmi_primitive_value_add_array_element(mmi_primitive_value_h array, mmi_primitive_value_h element); - -int mmi_primitive_value_get_type(mmi_primitive_value_h handle, mmi_primitive_value_type_e *type); - -int mmi_primitive_value_get_int(mmi_primitive_value_h handle, int *value); - -int mmi_primitive_value_get_float(mmi_primitive_value_h handle, float *value); - -int mmi_primitive_value_get_string(mmi_primitive_value_h handle, const char **string); - -int mmi_primitive_value_get_bool(mmi_primitive_value_h handle, bool *value); - -int mmi_primitive_value_get_array_count(mmi_primitive_value_h array, size_t *count); - -int mmi_primitive_value_get_array_element(mmi_primitive_value_h array, size_t index, mmi_primitive_value_h *element); - -int mmi_primitive_value_clone(mmi_primitive_value_h handle, mmi_primitive_value_h *cloned); - -int mmi_primitive_value_destroy(mmi_primitive_value_h handle); - -int mmi_primitive_value_to_bytes(mmi_primitive_value_h handle, unsigned char **bytes, size_t *size); - -int mmi_primitive_value_from_bytes(unsigned char *bytes, size_t size, mmi_primitive_value_h *handle); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_PRIMITIVE_VALUE_H__ */ diff --git a/capi/mmi-signal.h b/capi/mmi-signal.h deleted file mode 100644 index 7db8613..0000000 --- a/capi/mmi-signal.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_SIGNAL_H__ -#define __TIZEN_UIX_MMI_SIGNAL_H__ - - -#include "mmi-platform-config.h" - -#include -#include -#include - -#include -#include - -/** -* @file mmi-port.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - char name[MMI_NAME_MAX_LENGTH]; - mmi_primitive_value_h value; -} mmi_signal_parameter_s; - -typedef mmi_signal_parameter_s* mmi_signal_parameter_h; - -typedef struct { - char name[MMI_NAME_MAX_LENGTH]; - mmi_signal_parameter_h parameters[MMI_PARAMETER_MAX_COUNT]; - int parameter_count; -} mmi_signal_s; - -typedef mmi_signal_s* mmi_signal_h; - -int mmi_signal_parameter_create(mmi_primitive_value_h value, const char *name, mmi_signal_parameter_h *parameter); - -int mmi_signal_parameter_get_name(mmi_signal_parameter_h parameter, char **name); - -int mmi_signal_parameter_get_value(mmi_signal_parameter_h parameter, mmi_primitive_value_h *value); - -int mmi_signal_parameter_clone(mmi_signal_parameter_h parameter, mmi_signal_parameter_h *cloned); - -int mmi_signal_parameter_destroy(mmi_signal_parameter_h parameter); - -int mmi_signal_create(const char *name, mmi_signal_h *handle); - -int mmi_signal_add_parameter(mmi_signal_h handle, mmi_signal_parameter_h parameter); - -int mmi_signal_get_name(mmi_signal_h handle, char **name); - -int mmi_signal_get_parameter_count(mmi_signal_h handle, int *count); - -int mmi_signal_get_parameter(mmi_signal_h handle, int index, mmi_signal_parameter_h *parameter); - -int mmi_signal_destroy(mmi_signal_h handle); - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_SIGNAL_H__ */ diff --git a/capi/mmi-workflow.h b/capi/mmi-workflow.h deleted file mode 100644 index d4e97d1..0000000 --- a/capi/mmi-workflow.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2023 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. - * - */ - - -#ifndef __TIZEN_UIX_MMI_WORKFLOW_H__ -#define __TIZEN_UIX_MMI_WORKFLOW_H__ - - -#include "mmi-platform-config.h" - -#include -#include -#include - - -/** -* @file mmi-workflow.h -*/ - - -/** -* @addtogroup CAPI_UIX_MMI_MODULE -* @{ -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - MMI_STANDARD_WORKFLOW_NONE, - MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND, - MMI_STANDARD_WORKFLOW_VOICE_TOUCH, - MMI_STANDARD_WORKFLOW_USER_RECOGNITION, -} mmi_standard_workflow_type_e; - - -/* Functions to define a workflow prototype. Mostly used by workflow developers. */ - -typedef struct { - char name[MMI_NAME_MAX_LENGTH]; - mmi_node_h node; -} mmi_workflow_node_info_s; - -typedef struct { - char from_node_name[MMI_NAME_MAX_LENGTH]; - char from_port_name[MMI_NAME_MAX_LENGTH]; - char to_node_name[MMI_NAME_MAX_LENGTH]; - char to_port_name[MMI_NAME_MAX_LENGTH]; -} mmi_workflow_link_info_s; - -typedef struct { - char attribute_name[MMI_NAME_MAX_LENGTH]; - char target_node_name[MMI_NAME_MAX_LENGTH]; - char target_attribute_name[MMI_NAME_MAX_LENGTH]; -} mmi_workflow_attribute_assignment_info_s; - -typedef struct { - size_t serialized_default_value_size; - unsigned char *serialized_default_value; -} mmi_workflow_attribute_default_value_info_s; - -typedef struct { - char signal_name[MMI_NAME_MAX_LENGTH]; - char target_node_name[MMI_NAME_MAX_LENGTH]; - char target_signal_name[MMI_NAME_MAX_LENGTH]; -} mmi_workflow_signal_assignment_info_s; - -typedef struct { - char output_name[MMI_NAME_MAX_LENGTH]; - char from_node_name[MMI_NAME_MAX_LENGTH]; - char from_port_name[MMI_NAME_MAX_LENGTH]; -} mmi_workflow_output_assignment_info_s; - -typedef struct { - mmi_standard_workflow_type_e type; - mmi_workflow_node_info_s *node_infos; - size_t node_info_count; - mmi_workflow_link_info_s *link_infos; - size_t link_info_count; - mmi_workflow_attribute_assignment_info_s *attribute_assignment_infos; - size_t attribute_assignment_info_count; - mmi_workflow_attribute_default_value_info_s *attribute_default_value_infos; - size_t attribute_default_value_info_count; - mmi_workflow_signal_assignment_info_s *signal_assignment_infos; - size_t signal_assignment_info_count; - mmi_workflow_output_assignment_info_s *output_assignment_infos; - size_t output_assignment_info_count; -} mmi_workflow_s; - -typedef mmi_workflow_s* mmi_workflow_h; - -/* Create a workflow prototype */ -int mmi_workflow_create(mmi_workflow_h *workflow); - -/* Set the type of a workflow prototype */ -int mmi_workflow_set_type(mmi_workflow_h workflow, mmi_standard_workflow_type_e type); - -/* Get the type of a workflow prototype */ -int mmi_workflow_get_type(mmi_workflow_h workflow, mmi_standard_workflow_type_e *type); - -/* Add a node to a workflow prototype */ -int mmi_workflow_node_add(mmi_workflow_h workflow, const char *node_name, mmi_node_h node); - -/* A convinience function to link two nodes by automatically finding the appropriate ports in the nodes. */ -/* The linking succeeds only if there is exactly one pair of compatible input and output ports in the nodes. */ -/* int mmi_workflow_link_nodes(mmi_node_h from_node, mmi_node_h to_node); */ - -/* Link two nodes with specifying the port names. */ -/* FIXME: It would be better to use handles instead of names. */ -int mmi_workflow_link_nodes_by_names(mmi_workflow_h workflow, const char *from_node_name, const char *from_port_name, const char *to_node_name, const char *to_port_name); - -/* Assign an attribute of a workflow to an attribute of a specific node in a workflow prototype */ -/* FIXME: It would be better to use handles instead of names. */ -int mmi_workflow_attribute_assign(mmi_workflow_h workflow, const char *attribute_name, const char *target_node_name, const char *target_attribute_name); - -/* Set the default value of an attribute of a workflow */ -int mmi_workflow_attribute_set_default_value(mmi_workflow_h workflow, mmi_attribute_h default_value); - -/* Assign a signal of a workflow to a signal of a specific node in a workflow prototype */ -int mmi_workflow_signal_assign(mmi_workflow_h workflow, const char *signal_name, const char *target_node_name, const char *target_signal_name); - -/* Assign an output of a workflow to a OUT port of a specific node in a workflow prototype */ -/* FIXME: It would be better to use handles instead of names. */ -int mmi_workflow_output_assign(mmi_workflow_h workflow, const char *workflow_output, const char *out_node_name, const char *node_out_port_name); - -/* Assign an output of a workflow to a OUT port of a specific node in a workflow prototype, with a port handle */ -int mmi_workflow_output_assign_by_port(mmi_workflow_h workflow, const char *workflow_output, mmi_port_h port); - -/* Register a standard workflow prototype to the workflow manager */ -int mmi_standard_workflow_register(mmi_workflow_h workflow); - -/* Clones a workflow. */ -int mmi_workflow_clone(mmi_workflow_h workflow, mmi_workflow_h *cloned); - -/* Create a workflow prototype from a script */ -int mmi_workflow_create_from_script(const char *script, mmi_workflow_h *workflow); - -/* Create a workflow prototype from a script file */ -int mmi_workflow_create_from_script_file(const char *script_path, mmi_workflow_h *workflow); - -/* Generate a workflow script from a workflow prototype */ -int mmi_workflow_generate_script(mmi_workflow_h workflow, const char **script); - -/* Destroy a workflow prototype */ -int mmi_workflow_destroy(mmi_workflow_h workflow); - -/* Functions to create a workflow instance. Mostly used by application developers. */ - -typedef void* mmi_workflow_instance_h; - -/* Callback function for workflow output */ -typedef void (*mmi_workflow_output_cb)(mmi_workflow_instance_h instance, const char *name, mmi_data_h data, void *user_data); - -/* Callback function for workflow signal */ -// typedef void (*mmi_workflow_signal_cb)(const char *name, mmi_signal_parameter_h parameter, void *user_data); - -/* Instantiate a workflow from a workflow prototype */ -int mmi_standard_workflow_instance_create(mmi_standard_workflow_type_e type, mmi_workflow_instance_h *instance); - -/* Instantiate a workflow from a custom workflow prototype */ -int mmi_custom_workflow_instance_create(mmi_workflow_h workflow, mmi_workflow_instance_h *instance); - -/* Destroy a workflow instance */ -int mmi_workflow_instance_destroy(mmi_workflow_instance_h instance); - -/* Start a workflow instance */ -int mmi_workflow_instance_activate(mmi_workflow_instance_h instance); - -/* Stop a workflow instance */ -int mmi_workflow_instance_deactivate(mmi_workflow_instance_h instance); - -/* Set an attribute of a workflow instance */ -int mmi_workflow_instance_set_attribute(mmi_workflow_instance_h instance, mmi_attribute_h attribute); - -/* Emit a signal to a workflow instance */ -int mmi_workflow_instance_emit_signal(mmi_workflow_instance_h instance, mmi_signal_h signal); - -/* Feed data to a port of a node with given name pair */ -int mmi_workflow_instance_feed_data(mmi_workflow_instance_h instance, const char *node_name, const char *port_name, mmi_data_h data); - -/* Set a callback function to receive workflow output */ -int mmi_workflow_instance_set_output_callback(mmi_workflow_instance_h instance, const char *name, mmi_workflow_output_cb callback, void *user_data); - -/* Set a callback function to receive workflow signal */ -// int mmi_workflow_instance_set_signal_callback(mmi_workflow_instance_h instance, const char *name, mmi_workflow_signal_cb callback, void *user_data); - - -#ifdef __cplusplus -} -#endif - - -/** - * @} - */ - - -#endif /* __TIZEN_UIX_MMI_WORKFLOW_H__ */ diff --git a/capi/mmi.h b/capi/mmi.h deleted file mode 100644 index 06a1cd4..0000000 --- a/capi/mmi.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2022 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. - * - */ - -#ifndef __MMI_H__ -#define __MMI_H__ - -#include "mmi-platform-config.h" - -#define MMI_API __attribute__ ((visibility("default"))) - -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef enum { - MMI_STATE_NONE = 0, - MMI_STATE_READY, -} mmi_state_e; - -typedef int (*mmi_state_changed_cb)(mmi_state_e state, void *user_data); - -/** @brief Initialize MMI framework - * - * @return 0 on success, otherwise a negative error value - */ -int mmi_initialize(); - -/** @brief Deinitialize MMI framework - * - * @return 0 on success, otherwise a negative error value - */ -int mmi_deinitialize(); - -/** @brief Set callback for state change - * - * @param[in] callback The callback function to be called when state is changed - * @param[in] user_data The user data to be passed to the callback function - * - * @return 0 on success, otherwise a negative error value - * @see mmi_state_changed_cb - */ -int mmi_set_state_changed_cb(mmi_state_changed_cb callback, void *user_data); - -/** @brief Unset callback for state change - * - * @param[in] callback The callback function to be unset - * - * @return 0 on success, otherwise a negative error value - */ -int mmi_unset_state_changed_cb(mmi_state_changed_cb callback); - -#ifdef __cplusplus -} -#endif - - - -#endif //__MMI_H__ diff --git a/external/cppcodec/base32_crockford.hpp b/external/cppcodec/base32_crockford.hpp new file mode 100644 index 0000000..6c2ae36 --- /dev/null +++ b/external/cppcodec/base32_crockford.hpp @@ -0,0 +1,91 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE32_CROCKFORD +#define CPPCODEC_BASE32_CROCKFORD + +#include "detail/codec.hpp" +#include "detail/base32.hpp" + +namespace cppcodec { + +namespace detail { + +static constexpr const char base32_crockford_alphabet[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // at index 10 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 18 - no I + 'J', 'K', // 20 - no L + 'M', 'N', // 22 - no O + 'P', 'Q', 'R', 'S', 'T', // 27 - no U + 'V', 'W', 'X', 'Y', 'Z' // 32 +}; + +class base32_crockford_base +{ +public: + static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() { + static_assert(sizeof(base32_crockford_alphabet) == 32, "base32 alphabet must have 32 values"); + return sizeof(base32_crockford_alphabet); + } + static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t idx) + { + return base32_crockford_alphabet[idx]; + } + static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c) + { + // Hex decoding is always case-insensitive (even in RFC 4648), the question + // is only for encoding whether to use upper-case or lower-case letters. + return (c == 'O' || c == 'o') ? '0' + : (c == 'I' || c == 'i' || c == 'L' || c == 'l') ? '1' + : (c >= 'a' && c <= 'z') ? (c - 'a' + 'A') + : c; + } + + static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return false; } + static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return false; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char) { return false; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; } + + static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char c) { + return c == '-'; // "Hyphens (-) can be inserted into strings [for readability]." + } +}; + +// base32_crockford is a concatenative iterative (i.e. streaming) interpretation of Crockford base32. +// It interprets the statement "zero-extend the number to make its bit-length a multiple of 5" +// to mean zero-extending it on the right. +// (The other possible interpretation is base32_crockford_num, a place-based single number encoding system. +// See http://merrigrove.blogspot.ca/2014/04/what-heck-is-base64-encoding-really.html for more info.) +class base32_crockford : public base32_crockford_base +{ +public: + template using codec_impl = stream_codec; +}; + +} // namespace detail + +using base32_crockford = detail::codec>; + +} // namespace cppcodec + +#endif // CPPCODEC_BASE32_CROCKFORD diff --git a/external/cppcodec/base32_default_crockford.hpp b/external/cppcodec/base32_default_crockford.hpp new file mode 100644 index 0000000..73e94eb --- /dev/null +++ b/external/cppcodec/base32_default_crockford.hpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE32_DEFAULT_CROCKFORD +#define CPPCODEC_BASE32_DEFAULT_CROCKFORD + +#include "base32_crockford.hpp" + +using base32 = cppcodec::base32_crockford; + +#endif // CPPCODEC_BASE32_DEFAULT_CROCKFORD diff --git a/external/cppcodec/base32_default_hex.hpp b/external/cppcodec/base32_default_hex.hpp new file mode 100644 index 0000000..4cd8336 --- /dev/null +++ b/external/cppcodec/base32_default_hex.hpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2015, 2016 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE32_DEFAULT_HEX +#define CPPCODEC_BASE32_DEFAULT_HEX + +#include "base32_hex.hpp" + +using base32 = cppcodec::base32_hex; + +#endif // CPPCODEC_BASE32_DEFAULT_HEX diff --git a/external/cppcodec/base32_default_rfc4648.hpp b/external/cppcodec/base32_default_rfc4648.hpp new file mode 100644 index 0000000..75561bc --- /dev/null +++ b/external/cppcodec/base32_default_rfc4648.hpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE32_DEFAULT_RFC4648 +#define CPPCODEC_BASE32_DEFAULT_RFC4648 + +#include "base32_rfc4648.hpp" + +using base32 = cppcodec::base32_rfc4648; + +#endif // CPPCODEC_BASE32_DEFAULT_RFC4648 diff --git a/external/cppcodec/base32_hex.hpp b/external/cppcodec/base32_hex.hpp new file mode 100644 index 0000000..ce1d84d --- /dev/null +++ b/external/cppcodec/base32_hex.hpp @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2015, 2016 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE32_HEX +#define CPPCODEC_BASE32_HEX + +#include "detail/codec.hpp" +#include "detail/base32.hpp" + +namespace cppcodec { + +namespace detail { + +// RFC 4648 also specifies a hex encoding system which uses 0-9, then A-V. +static constexpr const char base32_hex_alphabet[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V' +}; + +class base32_hex +{ +public: + template using codec_impl = stream_codec; + + static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() { + static_assert(sizeof(base32_hex_alphabet) == 32, "base32 alphabet must have 32 values"); + return sizeof(base32_hex_alphabet); + } + static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t idx) + { + return base32_hex_alphabet[idx]; + } + static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c) + { + // Lower-case letters are accepted, though not generally expected. + return (c >= 'a' && c <= 'v') ? (c - 'a' + 'A') : c; + } + + static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return true; } + static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return true; } + static CPPCODEC_ALWAYS_INLINE constexpr char padding_symbol() { return '='; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char c) { return c == '='; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; } + + // RFC4648 does not specify any whitespace being allowed in base32 encodings. + static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; } +}; + +} // namespace detail + +using base32_hex = detail::codec>; + +} // namespace cppcodec + +#endif // CPPCODEC_BASE32_HEX diff --git a/external/cppcodec/base32_rfc4648.hpp b/external/cppcodec/base32_rfc4648.hpp new file mode 100644 index 0000000..c039702 --- /dev/null +++ b/external/cppcodec/base32_rfc4648.hpp @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE32_RFC4648 +#define CPPCODEC_BASE32_RFC4648 + +#include "detail/codec.hpp" +#include "detail/base32.hpp" + +namespace cppcodec { + +namespace detail { + +// RFC 4648 uses a simple alphabet: A-Z starting at index 0, then 2-7 starting at index 26. +static constexpr const char base32_rfc4648_alphabet[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', // at index 26 + '2', '3', '4', '5', '6', '7' +}; + +class base32_rfc4648 +{ +public: + template using codec_impl = stream_codec; + + static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() { + static_assert(sizeof(base32_rfc4648_alphabet) == 32, "base32 alphabet must have 32 values"); + return sizeof(base32_rfc4648_alphabet); + } + static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t idx) + { + return base32_rfc4648_alphabet[idx]; + } + static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c) + { + // Lower-case letters are accepted, though not generally expected. + return (c >= 'a' && c <= 'z') ? (c - 'a' + 'A') : c; + } + + static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return true; } + static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return true; } + static CPPCODEC_ALWAYS_INLINE constexpr char padding_symbol() { return '='; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char c) { return c == '='; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; } + + // RFC4648 does not specify any whitespace being allowed in base32 encodings. + static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; } +}; + +} // namespace detail + +using base32_rfc4648 = detail::codec>; + +} // namespace cppcodec + +#endif // CPPCODEC_BASE32_RFC4648 diff --git a/external/cppcodec/base64_default_rfc4648.hpp b/external/cppcodec/base64_default_rfc4648.hpp new file mode 100644 index 0000000..3b39a00 --- /dev/null +++ b/external/cppcodec/base64_default_rfc4648.hpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE64_DEFAULT_RFC4648 +#define CPPCODEC_BASE64_DEFAULT_RFC4648 + +#include "base64_rfc4648.hpp" + +using base64 = cppcodec::base64_rfc4648; + +#endif // CPPCODEC_BASE64_DEFAULT_RFC4648 diff --git a/external/cppcodec/base64_default_url.hpp b/external/cppcodec/base64_default_url.hpp new file mode 100644 index 0000000..7db2a39 --- /dev/null +++ b/external/cppcodec/base64_default_url.hpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE64_DEFAULT_URL +#define CPPCODEC_BASE64_DEFAULT_URL + +#include "base64_url.hpp" + +using base64 = cppcodec::base64_url; + +#endif // CPPCODEC_BASE64_DEFAULT_URL diff --git a/external/cppcodec/base64_default_url_unpadded.hpp b/external/cppcodec/base64_default_url_unpadded.hpp new file mode 100644 index 0000000..3173966 --- /dev/null +++ b/external/cppcodec/base64_default_url_unpadded.hpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2016 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE64_DEFAULT_URL_UNPADDED +#define CPPCODEC_BASE64_DEFAULT_URL_UNPADDED + +#include "base64_url_unpadded.hpp" + +using base64 = cppcodec::base64_url_unpadded; + +#endif // CPPCODEC_BASE64_DEFAULT_URL_UNPADDED diff --git a/external/cppcodec/base64_rfc4648.hpp b/external/cppcodec/base64_rfc4648.hpp new file mode 100644 index 0000000..717dcec --- /dev/null +++ b/external/cppcodec/base64_rfc4648.hpp @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE64_RFC4648 +#define CPPCODEC_BASE64_RFC4648 + +#include "detail/codec.hpp" +#include "detail/base64.hpp" + +namespace cppcodec { + +namespace detail { + +static constexpr const char base64_rfc4648_alphabet[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' +}; + +class base64_rfc4648 +{ +public: + template using codec_impl = stream_codec; + + static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() { + static_assert(sizeof(base64_rfc4648_alphabet) == 64, "base64 alphabet must have 64 values"); + return sizeof(base64_rfc4648_alphabet); + } + static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t idx) + { + return base64_rfc4648_alphabet[idx]; + } + static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c) { return c; } + + static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return true; } + static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return true; } + static CPPCODEC_ALWAYS_INLINE constexpr char padding_symbol() { return '='; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char c) { return c == '='; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; } + + // RFC4648 does not specify any whitespace being allowed in base64 encodings. + static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; } +}; + +} // namespace detail + +using base64_rfc4648 = detail::codec>; + +} // namespace cppcodec + +#endif // CPPCODEC_BASE64_RFC4648 diff --git a/external/cppcodec/base64_url.hpp b/external/cppcodec/base64_url.hpp new file mode 100644 index 0000000..04c2f8b --- /dev/null +++ b/external/cppcodec/base64_url.hpp @@ -0,0 +1,75 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE64_URL +#define CPPCODEC_BASE64_URL + +#include "detail/codec.hpp" +#include "detail/base64.hpp" + +namespace cppcodec { + +namespace detail { + +// The URL and filename safe alphabet is also specified by RFC4648, named "base64url". +// We keep the underscore ("base64_url") for consistency with the other codec variants. +static constexpr const char base64_url_alphabet[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' +}; + +class base64_url +{ +public: + template using codec_impl = stream_codec; + + static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() { + static_assert(sizeof(base64_url_alphabet) == 64, "base64 alphabet must have 64 values"); + return sizeof(base64_url_alphabet); + } + static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t idx) + { + return base64_url_alphabet[idx]; + } + static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c) { return c; } + + static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return true; } + static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return true; } + static CPPCODEC_ALWAYS_INLINE constexpr char padding_symbol() { return '='; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char c) { return c == '='; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; } + + // RFC4648 does not specify any whitespace being allowed in base64 encodings. + static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; } +}; + +} // namespace detail + +using base64_url = detail::codec>; + +} // namespace cppcodec + +#endif // CPPCODEC_BASE64_URL diff --git a/external/cppcodec/base64_url_unpadded.hpp b/external/cppcodec/base64_url_unpadded.hpp new file mode 100644 index 0000000..e9a5d3f --- /dev/null +++ b/external/cppcodec/base64_url_unpadded.hpp @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2016 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_BASE64_URL_UNPADDED +#define CPPCODEC_BASE64_URL_UNPADDED + +#include "base64_url.hpp" + +namespace cppcodec { + +namespace detail { + +class base64_url_unpadded : public base64_url +{ +public: + template using codec_impl = stream_codec; + + static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return false; } + static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return false; } +}; + +} // namespace detail + +using base64_url_unpadded = detail::codec>; + +} // namespace cppcodec + +#endif // CPPCODEC_BASE64_URL_UNPADDED diff --git a/external/cppcodec/data/access.hpp b/external/cppcodec/data/access.hpp new file mode 100644 index 0000000..432a3c7 --- /dev/null +++ b/external/cppcodec/data/access.hpp @@ -0,0 +1,328 @@ +/** + * Copyright (C) 2015 Topology LP + * Copyright (C) 2018 Jakob Petsovits + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_DETAIL_DATA_ACCESS +#define CPPCODEC_DETAIL_DATA_ACCESS + +#include // for size_t +#include // for static_assert() checking that string will be optimized +#include // for std::enable_if, std::remove_reference, and such +#include // for std::declval +#include // for static_assert() checking that vector will be optimized + +#include "../detail/config.hpp" // for CPPCODEC_ALWAYS_INLINE + +namespace cppcodec { +namespace data { + +// This file contains a number of templated data accessors that can be +// implemented in the cppcodec::data namespace for types that don't fulfill +// the default type requirements: +// For result types: init(Result&, ResultState&, size_t capacity), +// put(Result&, ResultState&, char), finish(Result&, State&) +// For const (read-only) types: char_data(const T&) +// For both const and result types: size(const T&) + +template +CPPCODEC_ALWAYS_INLINE size_t size(const T& t) { return t.size(); } + +template +CPPCODEC_ALWAYS_INLINE constexpr size_t size(const T (&t)[N]) noexcept { + return (void)t, N * sizeof(t[0]); +} + +class general_t {}; +class specific_t : public general_t {}; + +class empty_result_state { + template + CPPCODEC_ALWAYS_INLINE void size(const Result& result) { return size(result); } +}; + +// SFINAE: Generic fallback in case no specific state function applies. +template +CPPCODEC_ALWAYS_INLINE empty_result_state create_state(Result&, general_t) +{ + return empty_result_state(); +} + +// +// Generic templates for containers: Use these init()/put()/finish() +// implementations if no specialization was found. +// + +template +CPPCODEC_ALWAYS_INLINE void init(Result& result, empty_result_state&, size_t capacity) +{ + result.resize(0); + result.reserve(capacity); +} + +template +CPPCODEC_ALWAYS_INLINE void finish(Result&, empty_result_state&) +{ + // Default is to push_back(), which already increases the size. +} + +// For the put() default implementation, we try calling push_back() with either uint8_t or char, +// whichever compiles. Scary-fancy template magic from http://stackoverflow.com/a/1386390. +namespace fallback { + struct flag { char c[2]; }; // sizeof > 1 + flag put_uint8(...); + + int operator,(flag, flag); + template void operator,(flag, T&); // map everything else to void + char operator,(int, flag); // sizeof 1 +} + +template inline void put_uint8(Result& result, uint8_t c) { result.push_back(c); } + +template struct put_impl; +template <> struct put_impl { // put_uint8() available + template + static CPPCODEC_ALWAYS_INLINE void put(Result& result, uint8_t c) + { + put_uint8(result, c); + } +}; +template <> struct put_impl { // put_uint8() not available + template + static CPPCODEC_ALWAYS_INLINE void put(Result& result, uint8_t c) + { + result.push_back(static_cast(c)); + } +}; + +template +CPPCODEC_ALWAYS_INLINE void put(Result& result, empty_result_state&, uint8_t c) +{ + using namespace fallback; + put_impl::put(result, c); +} + +// +// Specialization for container types with direct mutable data access, +// e.g. std::vector. +// +// The expected way to specialize is to draft a new xyz_result_state type and +// return an instance of it from a create_state() template specialization. +// You can then create overloads for init(), put() and finish() +// for the new result state type. +// +// If desired, a non-templated overload for both specific types +// (result & state) can be added to tailor it to that particular result type. +// + +template +constexpr auto data_is_mutable(T* t) -> decltype(t->data()[size_t(0)] = 'x', bool()) +{ + return (void)t, true; +} +constexpr bool data_is_mutable(...) { return false; } + +template +class direct_data_access_result_state +{ +public: + CPPCODEC_ALWAYS_INLINE void init(Result& result, size_t capacity) + { + // reserve() may not actually allocate the storage right away, + // and it isn't guaranteed that it will be untouched upon the + //.next resize(). In that light, resize from the start and + // slightly reduce the size at the end if necessary. + result.resize(capacity); + + // result.data() may perform a calculation to retrieve the address. + // E.g. std::string (since C++11) will use small string optimization, + // so it needs to check if it's using allocated data or (ab)using + // its own member variables interpreted as char array. + // (This result_state is used for std::string starting with C++17.) + // Conditional code paths are slow so we only do it once, at the start. + m_buffer = result.data(); + } + CPPCODEC_ALWAYS_INLINE void put(Result&, char c) + { + m_buffer[m_offset++] = c; + } + CPPCODEC_ALWAYS_INLINE void finish(Result& result) + { + result.resize(m_offset); + } + CPPCODEC_ALWAYS_INLINE size_t size(const Result&) + { + return m_offset; + } +private: + // Make sure to get the mutable buffer decltype by using assignment. + typename std::remove_reference< + decltype(std::declval().data()[size_t(0)] = 'x')>::type* m_buffer; + size_t m_offset = 0; +}; + +// SFINAE: Select a specific state based on the result type and possible result state type. +// Implement this if direct data access (`result.data()[0] = 'x') isn't already possible +// and you want to specialize it for your own result type. +// Note: The enable_if should ideally be part of the class declaration, +// but Visual Studio C++ will not compile it that way. +// Have it here in the factory function instead. +template (nullptr))>::type> +CPPCODEC_ALWAYS_INLINE direct_data_access_result_state create_state(Result&, specific_t) +{ + return direct_data_access_result_state(); +} + +static_assert(std::is_same< + decltype(create_state(*static_cast*>(nullptr), specific_t())), + direct_data_access_result_state>>::value, + "std::vector must be handled by direct_data_access_result_state"); + +// Specialized init(), put() and finish() functions for direct_data_access_result_state. +template +CPPCODEC_ALWAYS_INLINE void init(Result& result, direct_data_access_result_state& state, size_t capacity) +{ + state.init(result, capacity); +} + +template +CPPCODEC_ALWAYS_INLINE void put(Result& result, direct_data_access_result_state& state, char c) +{ + state.put(result, c); +} + +template +CPPCODEC_ALWAYS_INLINE void finish(Result& result, direct_data_access_result_state& state) +{ + state.finish(result); +} + +// +// Specialization for container types with direct mutable array access, +// e.g. std::string. This is generally faster because bound checks are +// minimal and operator[] is more likely noexcept. In addition, +// std::string::push_back() needs to write a null character on every +// expansion, which should be more efficient when done in bulk by resize(). +// +// Compared to the above, tracking an extra offset variable is cheap. +// + +template +constexpr auto array_access_is_mutable(T* t) -> decltype((*t)[size_t(0)] = 'x', bool()) +{ + return (void)t, true; +} +constexpr bool array_access_is_mutable(...) { return false; } + +template +class array_access_result_state +{ +public: + CPPCODEC_ALWAYS_INLINE void init(Result& result, size_t capacity) + { + // reserve() may not actually allocate the storage right away, + // and it isn't guaranteed that it will be untouched upon the + //.next resize(). In that light, resize from the start and + // slightly reduce the size at the end if necessary. + result.resize(capacity); + } + CPPCODEC_ALWAYS_INLINE void put(Result& result, char c) + { + result[m_offset++] = c; + } + CPPCODEC_ALWAYS_INLINE void finish(Result& result) + { + result.resize(m_offset); + } + CPPCODEC_ALWAYS_INLINE size_t size(const Result&) + { + return m_offset; + } +private: + size_t m_offset = 0; +}; + +// SFINAE: Select a specific state based on the result type and possible result state type. +// Note: The enable_if should ideally be part of the class declaration, +// but Visual Studio C++ will not compile it that way. +// Have it here in the factory function instead. +template (nullptr)) // no more than one template option + && array_access_is_mutable(static_cast(nullptr))>::type> +CPPCODEC_ALWAYS_INLINE array_access_result_state create_state(Result&, specific_t) +{ + return array_access_result_state(); +} + +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG > 201703L) +static_assert(std::is_same< + decltype(create_state(*static_cast(nullptr), specific_t())), + direct_data_access_result_state>::value, + "std::string (C++17 and later) must be handled by direct_data_access_result_state"); +#elif __cplusplus < 201703 && !defined(_MSVC_LANG) // we can't trust MSVC to set this right +static_assert(std::is_same< + decltype(create_state(*static_cast(nullptr), specific_t())), + array_access_result_state>::value, + "std::string (pre-C++17) must be handled by array_access_result_state"); +#endif + +// Specialized init(), put() and finish() functions for array_access_result_state. +template +CPPCODEC_ALWAYS_INLINE void init(Result& result, array_access_result_state& state, size_t capacity) +{ + state.init(result, capacity); +} + +template +CPPCODEC_ALWAYS_INLINE void put(Result& result, array_access_result_state& state, char c) +{ + state.put(result, c); +} + +template +CPPCODEC_ALWAYS_INLINE void finish(Result& result, array_access_result_state& state) +{ + state.finish(result); +} + +// char_data() is only used to read, not for result buffers. +template inline const char* char_data(const T& t) +{ + return reinterpret_cast(t.data()); +} +template inline const char* char_data(const T (&t)[N]) noexcept +{ + return reinterpret_cast(&(t[0])); +} + +template inline const uint8_t* uchar_data(const T& t) +{ + return reinterpret_cast(char_data(t)); +} + +} // namespace data +} // namespace cppcodec + +#endif diff --git a/external/cppcodec/data/raw_result_buffer.hpp b/external/cppcodec/data/raw_result_buffer.hpp new file mode 100644 index 0000000..65b0de5 --- /dev/null +++ b/external/cppcodec/data/raw_result_buffer.hpp @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_DETAIL_RAW_RESULT_BUFFER +#define CPPCODEC_DETAIL_RAW_RESULT_BUFFER + +#include // for size_t +#include // for abort() + +#include "access.hpp" + +namespace cppcodec { +namespace data { + +class raw_result_buffer +{ +public: + raw_result_buffer(char* data, size_t capacity) + : m_ptr(data + capacity) + , m_begin(data) + { + } + + CPPCODEC_ALWAYS_INLINE void push_back(char c) { *m_ptr = c; ++m_ptr; } + CPPCODEC_ALWAYS_INLINE size_t size() const { return m_ptr - m_begin; } + CPPCODEC_ALWAYS_INLINE void resize(size_t size) { m_ptr = m_begin + size; } + +private: + char* m_ptr; + char* m_begin; +}; + + +template <> inline void init( + raw_result_buffer& result, empty_result_state&, size_t capacity) +{ + // This version of init() doesn't do a reserve(), and instead checks whether the + // initial size (capacity) is enough before resetting m_ptr to m_begin. + // The codec is expected not to exceed this capacity. + if (capacity > result.size()) { + abort(); + } + result.resize(0); +} +template <> inline void finish(raw_result_buffer&, empty_result_state&) { } + +} // namespace data +} // namespace cppcodec + +#endif diff --git a/external/cppcodec/detail/base32.hpp b/external/cppcodec/detail/base32.hpp new file mode 100644 index 0000000..7113b7a --- /dev/null +++ b/external/cppcodec/detail/base32.hpp @@ -0,0 +1,166 @@ +/** + * Copyright (C) 2015 Trustifier Inc. + * Copyright (C) 2015 Ahmed Masud + * Copyright (C) 2015 Topology LP + * Copyright (C) 2018 Jakob Petsovits + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Adapted from https://github.com/ahmed-masud/libbase32, + * commit 79761b2b79b0545697945efe0987a8d3004512f9. + * Quite different now. + */ + +#ifndef CPPCODEC_DETAIL_BASE32 +#define CPPCODEC_DETAIL_BASE32 + +#include +#include // for abort() + +#include "../data/access.hpp" +#include "../parse_error.hpp" +#include "config.hpp" +#include "stream_codec.hpp" + +namespace cppcodec { +namespace detail { + +template +class base32 : public CodecVariant::template codec_impl> +{ +public: + static inline constexpr uint8_t binary_block_size() { return 5; } + static inline constexpr uint8_t encoded_block_size() { return 8; } + + static CPPCODEC_ALWAYS_INLINE constexpr uint8_t num_encoded_tail_symbols(uint8_t num_bytes) + { + return (num_bytes == 1) ? 2 // 2 symbols, 6 padding characters + : (num_bytes == 2) ? 4 // 4 symbols, 4 padding characters + : (num_bytes == 3) ? 5 // 5 symbols, 3 padding characters + : (num_bytes == 4) ? 7 // 7 symbols, 1 padding characters + : throw std::domain_error("invalid number of bytes in a tail block"); + } + + template + static CPPCODEC_ALWAYS_INLINE constexpr uint8_t index( + const uint8_t* b /*binary block*/) noexcept + { + static_assert(I >= 0 && I < encoded_block_size(), + "invalid encoding symbol index in a block"); + + return (I == 0) ? ((b[0] >> 3) & 0x1F) // first 5 bits + : (I == 1) ? (((b[0] << 2) & 0x1C) | ((b[1] >> 6) & 0x3)) + : (I == 2) ? ((b[1] >> 1) & 0x1F) + : (I == 3) ? (((b[1] << 4) & 0x10) | ((b[2] >> 4) & 0xF)) + : (I == 4) ? (((b[2] << 1) & 0x1E) | ((b[3] >> 7) & 0x1)) + : (I == 5) ? ((b[3] >> 2) & 0x1F) + : (I == 6) ? (((b[3] << 3) & 0x18) | ((b[4] >> 5) & 0x7)) + : /*I == 7*/ (b[4] & 0x1F); // last 5 bits; + } + + template + using uint8_if = typename std::enable_if::type; + + template + static CPPCODEC_ALWAYS_INLINE constexpr + uint8_if index_last( + const uint8_t* b /*binary block*/) noexcept + { + return (I == 1) ? ((b[0] << 2) & 0x1C) // abbreviated 2nd symbol + : (I == 3) ? ((b[1] << 4) & 0x10) // abbreviated 4th symbol + : (I == 4) ? ((b[2] << 1) & 0x1E) // abbreviated 5th symbol + : /*I == 6*/ ((b[3] << 3) & 0x18); // abbreviated 7th symbol + } + + template + static CPPCODEC_ALWAYS_INLINE + uint8_if index_last( + const uint8_t* /*binary block*/) + { + throw std::domain_error("invalid last encoding symbol index in a tail"); + } + + template + static CPPCODEC_ALWAYS_INLINE void decode_block( + Result& decoded, ResultState&, const alphabet_index_t* idx); + + template + static CPPCODEC_ALWAYS_INLINE void decode_tail( + Result& decoded, ResultState&, const alphabet_index_t* idx, size_t idx_len); +}; + +// +// 11111111 10101010 10110011 10111100 10010100 +// => 11111 11110 10101 01011 00111 01111 00100 10100 +// + +template +template +CPPCODEC_ALWAYS_INLINE void base32::decode_block( + Result& decoded, ResultState& state, const alphabet_index_t* idx) +{ + put(decoded, state, static_cast(((idx[0] << 3) & 0xF8) | ((idx[1] >> 2) & 0x7))); + put(decoded, state, static_cast(((idx[1] << 6) & 0xC0) | ((idx[2] << 1) & 0x3E) | ((idx[3] >> 4) & 0x1))); + put(decoded, state, static_cast(((idx[3] << 4) & 0xF0) | ((idx[4] >> 1) & 0xF))); + put(decoded, state, static_cast(((idx[4] << 7) & 0x80) | ((idx[5] << 2) & 0x7C) | ((idx[6] >> 3) & 0x3))); + put(decoded, state, static_cast(((idx[6] << 5) & 0xE0) | (idx[7] & 0x1F))); +} + +template +template +CPPCODEC_ALWAYS_INLINE void base32::decode_tail( + Result& decoded, ResultState& state, const alphabet_index_t* idx, size_t idx_len) +{ + if (idx_len == 1) { + throw invalid_input_length( + "invalid number of symbols in last base32 block: found 1, expected 2, 4, 5 or 7"); + } + if (idx_len == 3) { + throw invalid_input_length( + "invalid number of symbols in last base32 block: found 3, expected 2, 4, 5 or 7"); + } + if (idx_len == 6) { + throw invalid_input_length( + "invalid number of symbols in last base32 block: found 6, expected 2, 4, 5 or 7"); + } + + // idx_len == 2: decoded size 1 + put(decoded, state, static_cast(((idx[0] << 3) & 0xF8) | ((idx[1] >> 2) & 0x7))); + if (idx_len == 2) { + return; + } + // idx_len == 4: decoded size 2 + put(decoded, state, static_cast(((idx[1] << 6) & 0xC0) | ((idx[2] << 1) & 0x3E) | ((idx[3] >> 4) & 0x1))); + if (idx_len == 4) { + return; + } + // idx_len == 5: decoded size 3 + put(decoded, state, static_cast(((idx[3] << 4) & 0xF0) | ((idx[4] >> 1) & 0xF))); + if (idx_len == 5) { + return; + } + // idx_len == 7: decoded size 4 + put(decoded, state, static_cast(((idx[4] << 7) & 0x80) | ((idx[5] << 2) & 0x7C) | ((idx[6] >> 3) & 0x3))); +} + +} // namespace detail +} // namespace cppcodec + +#endif // CPPCODEC_DETAIL_BASE32 diff --git a/external/cppcodec/detail/base64.hpp b/external/cppcodec/detail/base64.hpp new file mode 100644 index 0000000..b6db6d7 --- /dev/null +++ b/external/cppcodec/detail/base64.hpp @@ -0,0 +1,132 @@ +/** + * Copyright (C) 2015 Topology LP + * Copyright (C) 2013 Adam Rudd (bit calculations) + * Copyright (C) 2018 Jakob Petsovits + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Bit calculations adapted from https://github.com/adamvr/arduino-base64, + * commit 999595783185a0afcba156d7276dfeaa9cb5382f. + */ + +#ifndef CPPCODEC_DETAIL_BASE64 +#define CPPCODEC_DETAIL_BASE64 + +#include +#include + +#include "../data/access.hpp" +#include "../parse_error.hpp" +#include "config.hpp" +#include "stream_codec.hpp" + +namespace cppcodec { +namespace detail { + +template +class base64 : public CodecVariant::template codec_impl> +{ +public: + static inline constexpr uint8_t binary_block_size() { return 3; } + static inline constexpr uint8_t encoded_block_size() { return 4; } + + static CPPCODEC_ALWAYS_INLINE constexpr uint8_t num_encoded_tail_symbols(uint8_t num_bytes) + { + return (num_bytes == 1) ? 2 // 2 symbols, 2 padding characters + : (num_bytes == 2) ? 3 // 3 symbols, 1 padding character + : throw std::domain_error("invalid number of bytes in a tail block"); + } + + template + static CPPCODEC_ALWAYS_INLINE constexpr uint8_t index( + const uint8_t* b /*binary block*/) noexcept + { + static_assert(I >= 0 && I < encoded_block_size(), + "invalid encoding symbol index in a block"); + + return (I == 0) ? (b[0] >> 2) // first 6 bits + : (I == 1) ? (((b[0] & 0x3) << 4) | (b[1] >> 4)) + : (I == 2) ? (((b[1] & 0xF) << 2) | (b[2] >> 6)) + : /*I == 3*/ (b[2] & 0x3F); // last 6 bits + } + + template + using uint8_if = typename std::enable_if::type; + + template + static CPPCODEC_ALWAYS_INLINE constexpr uint8_if index_last( + const uint8_t* b /*binary block*/) noexcept + { + return (I == 1) ? ((b[0] & 0x3) << 4) // abbreviated 2nd symbol + : /*I == 2*/ ((b[1] & 0xF) << 2); // abbreviated 3rd symbol + } + + template + static CPPCODEC_ALWAYS_INLINE uint8_if index_last( + const uint8_t* /*binary block*/) + { + throw std::domain_error("invalid last encoding symbol index in a tail"); + } + + template + static CPPCODEC_ALWAYS_INLINE void decode_block( + Result& decoded, ResultState&, const alphabet_index_t* idx); + + template + static CPPCODEC_ALWAYS_INLINE void decode_tail( + Result& decoded, ResultState&, const alphabet_index_t* idx, size_t idx_len); +}; + + +template +template +CPPCODEC_ALWAYS_INLINE void base64::decode_block( + Result& decoded, ResultState& state, const alphabet_index_t* idx) +{ + uint_fast32_t dec = (idx[0] << 18) | (idx[1] << 12) | (idx[2] << 6) | idx[3]; + data::put(decoded, state, static_cast(dec >> 16)); + data::put(decoded, state, static_cast((dec >> 8) & 0xFF)); + data::put(decoded, state, static_cast(dec & 0xFF)); +} + +template +template +CPPCODEC_ALWAYS_INLINE void base64::decode_tail( + Result& decoded, ResultState& state, const alphabet_index_t* idx, size_t idx_len) +{ + if (idx_len == 1) { + throw invalid_input_length( + "invalid number of symbols in last base64 block: found 1, expected 2 or 3"); + } + + // idx_len == 2: decoded size 1 + data::put(decoded, state, static_cast((idx[0] << 2) + ((idx[1] & 0x30) >> 4))); + if (idx_len == 2) { + return; + } + + // idx_len == 3: decoded size 2 + data::put(decoded, state, static_cast(((idx[1] & 0xF) << 4) + ((idx[2] & 0x3C) >> 2))); +} + +} // namespace detail +} // namespace cppcodec + +#endif // CPPCODEC_DETAIL_BASE64 diff --git a/external/cppcodec/detail/codec.hpp b/external/cppcodec/detail/codec.hpp new file mode 100644 index 0000000..47d9802 --- /dev/null +++ b/external/cppcodec/detail/codec.hpp @@ -0,0 +1,327 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_DETAIL_CODEC +#define CPPCODEC_DETAIL_CODEC + +#include +#include +#include +#include + +#include "../data/access.hpp" +#include "../data/raw_result_buffer.hpp" + +namespace cppcodec { +namespace detail { + +// SFINAE: Templates sometimes beat sensible overloads - make sure we don't call the wrong one. +template +struct non_numeric : std::enable_if::value> { }; + + +/** + * Public interface for all the codecs. For API documentation, see README.md. + */ +template +class codec +{ +public: + // + // Encoding + + // Convenient version, returns an std::string. + static std::string encode(const uint8_t* binary, size_t binary_size); + static std::string encode(const char* binary, size_t binary_size); + // static std::string encode(const T& binary); -> provided by template below + + // Convenient version with templated result type. + template static Result encode(const uint8_t* binary, size_t binary_size); + template static Result encode(const char* binary, size_t binary_size); + template > + static Result encode(const T& binary); + + // Reused result container version. Resizes encoded_result before writing to it. + template + static void encode(Result& encoded_result, const uint8_t* binary, size_t binary_size); + template + static void encode(Result& encoded_result, const char* binary, size_t binary_size); + template ::type* = nullptr> + static void encode(Result& encoded_result, const T& binary); + + // Raw pointer output, assumes pre-allocated memory with size > encoded_size(binary_size). + static size_t encode( + char* encoded_result, size_t encoded_buffer_size, + const uint8_t* binary, size_t binary_size) noexcept; + static size_t encode( + char* encoded_result, size_t encoded_buffer_size, + const char* binary, size_t binary_size) noexcept; + template + static size_t encode( + char* encoded_result, size_t encoded_buffer_size, + const T& binary) noexcept; + + // Calculate the exact length of the encoded string based on binary size. + static constexpr size_t encoded_size(size_t binary_size) noexcept; + + // + // Decoding + + // Convenient version, returns an std::vector. + static std::vector decode(const char* encoded, size_t encoded_size); + // static std::vector decode(const T& encoded); -> provided by template below + + // Convenient version with templated result type. + template static Result decode(const char* encoded, size_t encoded_size); + template , typename T = std::string> + static Result decode(const T& encoded); + + // Reused result container version. Resizes binary_result before writing to it. + template + static void decode(Result& binary_result, const char* encoded, size_t encoded_size); + template ::type* = nullptr> + static void decode(Result& binary_result, const T& encoded); + + // Raw pointer output, assumes pre-allocated memory with size > decoded_max_size(encoded_size). + static size_t decode( + uint8_t* binary_result, size_t binary_buffer_size, + const char* encoded, size_t encoded_size); + static size_t decode( + char* binary_result, size_t binary_buffer_size, + const char* encoded, size_t encoded_size); + template static size_t decode( + uint8_t* binary_result, size_t binary_buffer_size, const T& encoded); + template static size_t decode( + char* binary_result, size_t binary_buffer_size, const T& encoded); + + // Calculate the maximum size of the decoded binary buffer based on the encoded string length. + static constexpr size_t decoded_max_size(size_t encoded_size) noexcept; +}; + + +// +// Inline definitions of the above functions, using CRTP to call into CodecImpl +// + +// +// Encoding + +template +inline std::string codec::encode(const uint8_t* binary, size_t binary_size) +{ + return encode(binary, binary_size); +} + +template +inline std::string codec::encode(const char* binary, size_t binary_size) +{ + return encode(reinterpret_cast(binary), binary_size); +} + +template +template +inline Result codec::encode(const uint8_t* binary, size_t binary_size) +{ + Result encoded_result; + encode(encoded_result, binary, binary_size); + return encoded_result; +} + +template +template +inline Result codec::encode(const char* binary, size_t binary_size) +{ + return encode(reinterpret_cast(binary), binary_size); +} + +template +template +inline Result codec::encode(const T& binary) +{ + return encode(data::uchar_data(binary), data::size(binary)); +} + +template +template +inline void codec::encode( + Result& encoded_result, const uint8_t* binary, size_t binary_size) +{ + // This overload is where we reserve buffer capacity and call into CodecImpl. + size_t encoded_buffer_size = encoded_size(binary_size); + auto state = data::create_state(encoded_result, data::specific_t()); + data::init(encoded_result, state, encoded_buffer_size); + + CodecImpl::encode(encoded_result, state, binary, binary_size); + data::finish(encoded_result, state); + assert(data::size(encoded_result) == encoded_buffer_size); +} + +template +template +inline void codec::encode( + Result& encoded_result, const char* binary, size_t binary_size) +{ + encode(encoded_result, reinterpret_cast(binary), binary_size); +} + +template +template ::type*> +inline void codec::encode(Result& encoded_result, const T& binary) +{ + encode(encoded_result, data::uchar_data(binary), data::size(binary)); +} + +template +inline size_t codec::encode( + char* encoded_result, size_t encoded_buffer_size, + const uint8_t* binary, size_t binary_size) noexcept +{ + // This overload is where we wrap the result pointer & size. + data::raw_result_buffer encoded(encoded_result, encoded_buffer_size); + encode(encoded, binary, binary_size); + + size_t encoded_size = data::size(encoded); + if (encoded_size < encoded_buffer_size) { + encoded_result[encoded_size] = '\0'; + } + return encoded_size; +} + +template +inline size_t codec::encode( + char* encoded_result, size_t encoded_buffer_size, + const char* binary, size_t binary_size) noexcept +{ + // This overload is where we wrap the result pointer & size. + return encode(encoded_result, encoded_buffer_size, + reinterpret_cast(binary), binary_size); +} + +template +template +inline size_t codec::encode( + char* encoded_result, size_t encoded_buffer_size, + const T& binary) noexcept +{ + return encode(encoded_result, encoded_buffer_size, data::uchar_data(binary), data::size(binary)); +} + +template +inline constexpr size_t codec::encoded_size(size_t binary_size) noexcept +{ + return CodecImpl::encoded_size(binary_size); +} + + +// +// Decoding + +template +inline std::vector codec::decode(const char* encoded, size_t encoded_size) +{ + return decode>(encoded, encoded_size); +} + +template +template +inline Result codec::decode(const char* encoded, size_t encoded_size) +{ + Result result; + decode(result, encoded, encoded_size); + return result; +} + +template +template +inline Result codec::decode(const T& encoded) +{ + return decode(data::char_data(encoded), data::size(encoded)); +} + +template +template +inline void codec::decode(Result& binary_result, const char* encoded, size_t encoded_size) +{ + // This overload is where we reserve buffer capacity and call into CodecImpl. + size_t binary_buffer_size = decoded_max_size(encoded_size); + auto state = data::create_state(binary_result, data::specific_t()); + data::init(binary_result, state, binary_buffer_size); + + CodecImpl::decode(binary_result, state, encoded, encoded_size); + data::finish(binary_result, state); + assert(data::size(binary_result) <= binary_buffer_size); +} + + +template +template ::type*> +inline void codec::decode(Result& binary_result, const T& encoded) +{ + decode(binary_result, data::char_data(encoded), data::size(encoded)); +} + +template +inline size_t codec::decode( + uint8_t* binary_result, size_t binary_buffer_size, + const char* encoded, size_t encoded_size) +{ + return decode(reinterpret_cast(binary_result), binary_buffer_size, encoded, encoded_size); +} + +template +inline size_t codec::decode( + char* binary_result, size_t binary_buffer_size, + const char* encoded, size_t encoded_size) +{ + // This overload is where we wrap the result pointer & size. + data::raw_result_buffer binary(binary_result, binary_buffer_size); + decode(binary, encoded, encoded_size); + return data::size(binary); +} + +template +template +inline size_t codec::decode( + uint8_t* binary_result, size_t binary_buffer_size, const T& encoded) +{ + return decode(reinterpret_cast(binary_result), binary_buffer_size, encoded); +} + +template +template +inline size_t codec::decode(char* binary_result, size_t binary_buffer_size, const T& encoded) +{ + return decode(binary_result, binary_buffer_size, data::char_data(encoded), data::size(encoded)); +} + +template +inline constexpr size_t codec::decoded_max_size(size_t encoded_size) noexcept +{ + return CodecImpl::decoded_max_size(encoded_size); +} + + +} // namespace detail +} // namespace cppcodec + +#endif diff --git a/external/cppcodec/detail/config.hpp b/external/cppcodec/detail/config.hpp new file mode 100644 index 0000000..dc66f8f --- /dev/null +++ b/external/cppcodec/detail/config.hpp @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_DETAIL_CONFIG_HPP +#define CPPCODEC_DETAIL_CONFIG_HPP + +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#if __GNUC__ || __has_attribute(always_inline) +#define CPPCODEC_ALWAYS_INLINE inline __attribute__((always_inline)) +#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#define CPPCODEC_ALWAYS_INLINE inline __forceinline +#else +#define CPPCODEC_ALWAYS_INLINE inline +#endif + +#endif // CPPCODEC_DETAIL_CONFIG_HPP + diff --git a/external/cppcodec/detail/hex.hpp b/external/cppcodec/detail/hex.hpp new file mode 100644 index 0000000..f86be93 --- /dev/null +++ b/external/cppcodec/detail/hex.hpp @@ -0,0 +1,114 @@ +/** + * Copyright (C) 2015 Topology LP + * Copyright (C) 2018 Jakob Petsovits + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_DETAIL_HEX +#define CPPCODEC_DETAIL_HEX + +#include +#include // for abort() + +#include "../data/access.hpp" +#include "../parse_error.hpp" +#include "stream_codec.hpp" + +namespace cppcodec { +namespace detail { + +template +class hex : public CodecVariant::template codec_impl> +{ +public: + static inline constexpr uint8_t binary_block_size() { return 1; } + static inline constexpr uint8_t encoded_block_size() { return 2; } + + static CPPCODEC_ALWAYS_INLINE constexpr uint8_t num_encoded_tail_symbols(uint8_t /*num_bytes*/) noexcept + { + // Hex encoding only works on full bytes so there are no tails, + // no padding characters, and this function should (must) never be called. + return 0; + } + + template + static CPPCODEC_ALWAYS_INLINE constexpr uint8_t index( + const uint8_t* b /*binary block*/) noexcept + { + static_assert(I >= 0 && I < encoded_block_size(), + "invalid encoding symbol index in a block"); + + return (I == 0) ? (b[0] >> 4) // first 4 bits + : /*I == 1*/ (b[0] & 0xF); // last 4 bits + } + + // With only 2 bytes, enc<1> will always result in a full index() call and + // enc<0> will be protected by a not-reached assertion, so we don't actually + // care about index_last() except optimizing it out as good as possible. + template + using uint8_if = typename std::enable_if::type; + + template + static CPPCODEC_ALWAYS_INLINE constexpr uint8_if index_last( + const uint8_t* /*binary block*/) noexcept + { + return 0; + } + + template + static CPPCODEC_ALWAYS_INLINE uint8_if index_last( + const uint8_t* /*binary block*/) + { + throw std::domain_error("invalid last encoding symbol index in a tail"); + } + + template + static CPPCODEC_ALWAYS_INLINE void decode_block( + Result& decoded, ResultState&, const alphabet_index_t* idx); + + template + static CPPCODEC_ALWAYS_INLINE void decode_tail( + Result& decoded, ResultState&, const alphabet_index_t* idx, size_t idx_len); +}; + + +template +template +CPPCODEC_ALWAYS_INLINE void hex::decode_block( + Result& decoded, ResultState& state, const alphabet_index_t* idx) +{ + data::put(decoded, state, static_cast((idx[0] << 4) | idx[1])); +} + +template +template +CPPCODEC_ALWAYS_INLINE void hex::decode_tail( + Result&, ResultState&, const alphabet_index_t*, size_t) +{ + throw invalid_input_length( + "odd-length hex input is not supported by the streaming octet decoder, " + "use a place-based number decoder instead"); +} + +} // namespace detail +} // namespace cppcodec + +#endif // CPPCODEC_DETAIL_HEX diff --git a/external/cppcodec/detail/stream_codec.hpp b/external/cppcodec/detail/stream_codec.hpp new file mode 100644 index 0000000..ddc52e3 --- /dev/null +++ b/external/cppcodec/detail/stream_codec.hpp @@ -0,0 +1,439 @@ +/** + * Copyright (C) 2015 Topology LP + * Copyright (C) 2018 Jakob Petsovits + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_DETAIL_STREAM_CODEC +#define CPPCODEC_DETAIL_STREAM_CODEC + +#include +#include // for abort() +#include + +#include "../parse_error.hpp" +#include "config.hpp" + +namespace cppcodec { +namespace detail { + +using alphabet_index_t = uint_fast16_t; + +template +class stream_codec +{ +public: + template static void encode( + Result& encoded_result, ResultState&, const uint8_t* binary, size_t binary_size); + + template static void decode( + Result& binary_result, ResultState&, const char* encoded, size_t encoded_size); + + static constexpr size_t encoded_size(size_t binary_size) noexcept; + static constexpr size_t decoded_max_size(size_t encoded_size) noexcept; +}; + +template // default for CodecVariant::generates_padding() == false +struct padder { + template + static CPPCODEC_ALWAYS_INLINE void pad(Result&, ResultState&, SizeT) { } +}; + +template<> // specialization for CodecVariant::generates_padding() == true +struct padder { + template + static CPPCODEC_ALWAYS_INLINE void pad( + Result& encoded, ResultState& state, SizeT num_padding_characters) + { + for (SizeT i = 0; i < num_padding_characters; ++i) { + data::put(encoded, state, CodecVariant::padding_symbol()); + } + } +}; + +template +struct enc { + // Block encoding: Go from 0 to (block size - 1), append a symbol for each iteration unconditionally. + template + static CPPCODEC_ALWAYS_INLINE void block(Result& encoded, ResultState& state, const uint8_t* src) + { + using EncodedBlockSizeT = decltype(Codec::encoded_block_size()); + constexpr static const EncodedBlockSizeT SymbolIndex = static_cast(I - 1); + + enc().template block(encoded, state, src); + data::put(encoded, state, CodecVariant::symbol(Codec::template index(src))); + } + + // Tail encoding: Go from 0 until (runtime) num_symbols, append a symbol for each iteration. + template + static CPPCODEC_ALWAYS_INLINE void tail( + Result& encoded, ResultState& state, const uint8_t* src, EncodedBlockSizeT num_symbols) + { + constexpr static const EncodedBlockSizeT SymbolIndex = Codec::encoded_block_size() - I; + constexpr static const EncodedBlockSizeT NumSymbols = SymbolIndex + static_cast(1); + + if (num_symbols == NumSymbols) { + data::put(encoded, state, CodecVariant::symbol(Codec::template index_last(src))); + return; + } + data::put(encoded, state, CodecVariant::symbol(Codec::template index(src))); + enc().template tail(encoded, state, src, num_symbols); + } +}; + +template<> // terminating specialization +struct enc<0> { + template + static CPPCODEC_ALWAYS_INLINE void block(Result&, ResultState&, const uint8_t*) { } + + template + static CPPCODEC_ALWAYS_INLINE void tail(Result&, ResultState&, const uint8_t*, EncodedBlockSizeT) + { + abort(); // Not reached: block() should be called if num_symbols == block size, not tail(). + } +}; + +template +template +inline void stream_codec::encode( + Result& encoded_result, ResultState& state, + const uint8_t* src, size_t src_size) +{ + using encoder = enc; + + const uint8_t* src_end = src + src_size; + + if (src_size >= Codec::binary_block_size()) { + src_end -= Codec::binary_block_size(); + + for (; src <= src_end; src += Codec::binary_block_size()) { + encoder::template block(encoded_result, state, src); + } + src_end += Codec::binary_block_size(); + } + + if (src_end > src) { + auto remaining_src_len = src_end - src; + if (!remaining_src_len || remaining_src_len >= Codec::binary_block_size()) { + abort(); + return; + } + + auto num_symbols = Codec::num_encoded_tail_symbols( + static_cast(remaining_src_len)); + + encoder::template tail(encoded_result, state, src, num_symbols); + + padder::template pad( + encoded_result, state, Codec::encoded_block_size() - num_symbols); + } +} + +// Range & lookup table generation, see +// http://stackoverflow.com/questions/13313980/populate-an-array-using-constexpr-at-compile-time +// and http://cplusadd.blogspot.ca/2013/02/c11-compile-time-lookup-tablearray-with.html + +template struct seq {}; + +template +struct gen_seq : gen_seq { + // Clang up to 3.6 has a limit of 256 for template recursion, + // so pass a few more symbols at once to make it work. + static_assert(N % 4 == 0, "I must be divisible by 4 to eventually end at 0"); +}; +template +struct gen_seq<0, Is...> : seq {}; + +template +struct lookup_table_t { + alphabet_index_t lookup[N]; + static constexpr size_t size = N; +}; + +template +constexpr lookup_table_t make_lookup_table(seq, LambdaType value_for_index) { + return { { value_for_index(Is)... } }; +} + +template +constexpr lookup_table_t make_lookup_table(LambdaType evalFunc) { + return make_lookup_table(gen_seq(), evalFunc); +} + +// CodecVariant::symbol() provides a symbol for an index. +// Use recursive templates to get the inverse lookup table for fast decoding. + +template +static CPPCODEC_ALWAYS_INLINE constexpr size_t num_possible_values() +{ + return static_cast( + static_cast((std::numeric_limits::max)()) + - static_cast((std::numeric_limits::min)()) + 1); +} + +template +struct index_if_in_alphabet { + static CPPCODEC_ALWAYS_INLINE constexpr alphabet_index_t for_symbol(char symbol) + { + return (CodecVariant::symbol( + static_cast(CodecVariant::alphabet_size() - I)) == symbol) + ? static_cast(CodecVariant::alphabet_size() - I) + : index_if_in_alphabet::for_symbol(symbol); + } +}; +template +struct index_if_in_alphabet { // terminating specialization + static CPPCODEC_ALWAYS_INLINE constexpr alphabet_index_t for_symbol(char) + { + return InvalidIdx; + } +}; + +template +struct padding_searcher { + static CPPCODEC_ALWAYS_INLINE constexpr bool exists_padding_symbol() + { + // Clang up to 3.6 has a limit of 256 for template recursion, + // so pass a few more symbols at once to make it work. + static_assert(I % 4 == 0, "I must be divisible by 4 to eventually end at 0"); + + return CodecVariant::is_padding_symbol( + static_cast(num_possible_values() - I - 4)) + || CodecVariant::is_padding_symbol( + static_cast(num_possible_values() - I - 3)) + || CodecVariant::is_padding_symbol( + static_cast(num_possible_values() - I - 2)) + || CodecVariant::is_padding_symbol( + static_cast(num_possible_values() - I - 1)) + || padding_searcher::exists_padding_symbol(); + } +}; +template +struct padding_searcher { // terminating specialization + static CPPCODEC_ALWAYS_INLINE constexpr bool exists_padding_symbol() { return false; } +}; + +template +struct alphabet_index_info +{ + static constexpr const size_t num_possible_symbols = num_possible_values(); + + static constexpr const alphabet_index_t padding_idx = 1 << 8; + static constexpr const alphabet_index_t invalid_idx = 1 << 9; + static constexpr const alphabet_index_t eof_idx = 1 << 10; + static constexpr const alphabet_index_t stop_character_mask = static_cast(~0xFFu); + + static constexpr const bool padding_allowed = padding_searcher< + CodecVariant, num_possible_symbols>::exists_padding_symbol(); + + static CPPCODEC_ALWAYS_INLINE constexpr bool allows_padding() + { + return padding_allowed; + } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding(alphabet_index_t idx) + { + return allows_padding() ? (idx == padding_idx) : false; + } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_invalid(alphabet_index_t idx) { return idx == invalid_idx; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof(alphabet_index_t idx) { return idx == eof_idx; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_stop_character(alphabet_index_t idx) + { + return (idx & stop_character_mask) != 0; + } + +private: + static CPPCODEC_ALWAYS_INLINE constexpr + alphabet_index_t valid_index_or(alphabet_index_t a, alphabet_index_t b) + { + return a == invalid_idx ? b : a; + } + + using idx_if_in_alphabet = index_if_in_alphabet< + CodecVariant, invalid_idx, CodecVariant::alphabet_size()>; + + static CPPCODEC_ALWAYS_INLINE constexpr alphabet_index_t index_of(char symbol) + { + return valid_index_or(idx_if_in_alphabet::for_symbol(symbol), + CodecVariant::is_eof_symbol(symbol) ? eof_idx + : CodecVariant::is_padding_symbol(symbol) ? padding_idx + : invalid_idx); + } + + // GCC <= 4.9 has a bug with retaining constexpr when passing a function pointer. + // To get around this, we'll create a callable with operator() and pass that one. + // Unfortunately, MSVC prior to VS 2017 (for MinSizeRel or Release builds) + // chokes on this by compiling the project in 20 minutes instead of seconds. + // So let's define two separate variants and remove the old GCC one whenever we + // decide not to support GCC < 5.0 anymore. +#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5 + struct index_at { + CPPCODEC_ALWAYS_INLINE constexpr alphabet_index_t operator()(size_t symbol) const { + return index_of(CodecVariant::normalized_symbol(static_cast(symbol))); + } + }; +#else + static CPPCODEC_ALWAYS_INLINE constexpr alphabet_index_t index_at(size_t symbol) + { + return index_of(CodecVariant::normalized_symbol(static_cast(symbol))); + } +#endif + +public: + struct lookup { + static CPPCODEC_ALWAYS_INLINE alphabet_index_t for_symbol(char symbol) + { +#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5 + static constexpr const auto t = make_lookup_table(index_at()); +#else + static constexpr const auto t = make_lookup_table(&index_at); +#endif + static_assert(t.size == num_possible_symbols, + "lookup table must cover each possible (character) symbol"); + return t.lookup[static_cast(symbol)]; + } + }; +}; + +// +// At long last! The actual decode/encode functions. + +template +template +inline void stream_codec::decode( + Result& binary_result, ResultState& state, + const char* src_encoded, size_t src_size) +{ + using alphabet_index_lookup = typename alphabet_index_info::lookup; + const char* src = src_encoded; + const char* src_end = src + src_size; + + alphabet_index_t alphabet_indexes[Codec::encoded_block_size()] = {}; + alphabet_indexes[0] = alphabet_index_info::eof_idx; + + alphabet_index_t* const alphabet_index_start = &alphabet_indexes[0]; + alphabet_index_t* const alphabet_index_end = &alphabet_indexes[Codec::encoded_block_size()]; + alphabet_index_t* alphabet_index_ptr = &alphabet_indexes[0]; + + while (src < src_end) { + if (CodecVariant::should_ignore(*src)) { + ++src; + continue; + } + *alphabet_index_ptr = alphabet_index_lookup::for_symbol(*src); + if (alphabet_index_info::is_stop_character(*alphabet_index_ptr)) { + break; + } + ++src; + ++alphabet_index_ptr; + + if (alphabet_index_ptr == alphabet_index_end) { + Codec::decode_block(binary_result, state, alphabet_indexes); + alphabet_index_ptr = alphabet_index_start; + } + } + + if (alphabet_index_info::is_invalid(*alphabet_index_ptr)) { + throw symbol_error(*src); + } + ++src; + + alphabet_index_t* last_index_ptr = alphabet_index_ptr; + if (alphabet_index_info::is_padding(*last_index_ptr)) { + if (last_index_ptr == alphabet_index_start) { + // Don't accept padding at the start of a block. + // The encoder should have omitted that padding altogether. + throw padding_error(); + } + // We're in here because we just read a (first) padding character. Try to read more. + // Count with last_index_ptr, but store in alphabet_index_ptr so we don't + // overflow the array in case the input data is too long. + ++last_index_ptr; + while (src < src_end) { + *alphabet_index_ptr = alphabet_index_lookup::for_symbol(*(src++)); + + if (alphabet_index_info::is_eof(*alphabet_index_ptr)) { + *alphabet_index_ptr = alphabet_index_info::padding_idx; + break; + } + if (!alphabet_index_info::is_padding(*alphabet_index_ptr)) { + throw padding_error(); + } + + ++last_index_ptr; + if (last_index_ptr > alphabet_index_end) { + throw padding_error(); + } + } + } + + if (last_index_ptr != alphabet_index_start) { + if ((CodecVariant::requires_padding() + || alphabet_index_info::is_padding(*alphabet_index_ptr) + ) && last_index_ptr != alphabet_index_end) + { + // If the input is not a multiple of the block size then the input is incorrect. + throw padding_error(); + } + if (alphabet_index_ptr >= alphabet_index_end) { + abort(); + return; + } + Codec::decode_tail(binary_result, state, alphabet_indexes, + static_cast(alphabet_index_ptr - alphabet_index_start)); + } +} + +template +inline constexpr size_t stream_codec::encoded_size(size_t binary_size) noexcept +{ + using C = Codec; + + // constexpr rules make this a lot harder to read than it actually is. + return CodecVariant::generates_padding() + // With padding, the encoded size is a multiple of the encoded block size. + // To calculate that, round the binary size up to multiple of the binary block size, + // then convert to encoded by multiplying with { base32: 8/5, base64: 4/3 }. + ? (binary_size + (C::binary_block_size() - 1) + - ((binary_size + (C::binary_block_size() - 1)) % C::binary_block_size())) + * C::encoded_block_size() / C::binary_block_size() + // No padding: only pad to the next multiple of 5 bits, i.e. at most a single extra byte. + : (binary_size * C::encoded_block_size() / C::binary_block_size()) + + (((binary_size * C::encoded_block_size()) % C::binary_block_size()) ? 1 : 0); +} + +template +inline constexpr size_t stream_codec::decoded_max_size(size_t encoded_size) noexcept +{ + using C = Codec; + + return CodecVariant::requires_padding() + ? (encoded_size / C::encoded_block_size() * C::binary_block_size()) + : (encoded_size / C::encoded_block_size() * C::binary_block_size()) + + ((encoded_size % C::encoded_block_size()) + * C::binary_block_size() / C::encoded_block_size()); +} + +} // namespace detail +} // namespace cppcodec + +#endif // CPPCODEC_DETAIL_STREAM_CODEC diff --git a/external/cppcodec/hex_default_lower.hpp b/external/cppcodec/hex_default_lower.hpp new file mode 100644 index 0000000..3b10675 --- /dev/null +++ b/external/cppcodec/hex_default_lower.hpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_HEX_DEFAULT_LOWER +#define CPPCODEC_HEX_DEFAULT_LOWER + +#include "hex_lower.hpp" + +using hex = cppcodec::hex_lower; + +#endif // CPPCODEC_HEX_DEFAULT_LOWER diff --git a/external/cppcodec/hex_default_upper.hpp b/external/cppcodec/hex_default_upper.hpp new file mode 100644 index 0000000..a960f02 --- /dev/null +++ b/external/cppcodec/hex_default_upper.hpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_HEX_DEFAULT_UPPER +#define CPPCODEC_HEX_DEFAULT_UPPER + +#include "hex_upper.hpp" + +using hex = cppcodec::hex_upper; + +#endif // CPPCODEC_HEX_DEFAULT_UPPER diff --git a/external/cppcodec/hex_lower.hpp b/external/cppcodec/hex_lower.hpp new file mode 100644 index 0000000..36ad583 --- /dev/null +++ b/external/cppcodec/hex_lower.hpp @@ -0,0 +1,75 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_HEX_LOWER +#define CPPCODEC_HEX_LOWER + +#include "detail/codec.hpp" +#include "detail/hex.hpp" + +namespace cppcodec { + +namespace detail { + +static constexpr const char hex_lower_alphabet[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // at index 10 + 'a', 'b', 'c', 'd', 'e', 'f' +}; + +class hex_lower +{ +public: + template using codec_impl = stream_codec; + + static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() { + static_assert(sizeof(hex_lower_alphabet) == 16, "hex alphabet must have 16 values"); + return sizeof(hex_lower_alphabet); + } + static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t index) + { + return hex_lower_alphabet[index]; + } + static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c) + { + // Hex decoding is always case-insensitive (even in RFC 4648), the question + // is only for encoding whether to use upper-case or lower-case letters. + return (c >= 'A' && c <= 'F') ? (c - 'A' + 'a') : c; + } + + static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return false; } + // FIXME: doesn't require padding, but requires a multiple of the encoded block size (2) + static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return false; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char) { return false; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; } + + // Sometimes hex strings include whitespace, but this variant forbids it. + static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; } +}; + +} // namespace detail + +using hex_lower = detail::codec>; + +} // namespace cppcodec + +#endif // CPPCODEC_HEX_LOWER diff --git a/external/cppcodec/hex_upper.hpp b/external/cppcodec/hex_upper.hpp new file mode 100644 index 0000000..9b811c6 --- /dev/null +++ b/external/cppcodec/hex_upper.hpp @@ -0,0 +1,75 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_HEX_UPPER +#define CPPCODEC_HEX_UPPER + +#include "detail/codec.hpp" +#include "detail/hex.hpp" + +namespace cppcodec { + +namespace detail { + +static constexpr const char hex_upper_alphabet[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F' +}; + +class hex_upper +{ +public: + template using codec_impl = stream_codec; + + static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() { + static_assert(sizeof(hex_upper_alphabet) == 16, "hex alphabet must have 16 values"); + return sizeof(hex_upper_alphabet); + } + static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t index) + { + return hex_upper_alphabet[index]; + } + static CPPCODEC_ALWAYS_INLINE constexpr char normalized_symbol(char c) + { + // Hex decoding is always case-insensitive (even in RFC 4648), the question + // is only for encoding whether to use upper-case or lower-case letters. + return (c >= 'a' && c <= 'f') ? (c - 'a' + 'A') : c; + } + + static CPPCODEC_ALWAYS_INLINE constexpr bool generates_padding() { return false; } + // FIXME: doesn't require padding, but requires a multiple of the encoded block size (2) + static CPPCODEC_ALWAYS_INLINE constexpr bool requires_padding() { return false; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_padding_symbol(char) { return false; } + static CPPCODEC_ALWAYS_INLINE constexpr bool is_eof_symbol(char c) { return c == '\0'; } + + // Sometimes hex strings include whitespace, but this variant forbids it. + static CPPCODEC_ALWAYS_INLINE constexpr bool should_ignore(char) { return false; } +}; + +} // namespace detail + +using hex_upper = detail::codec>; + +} // namespace cppcodec + +#endif // CPPCODEC_HEX_UPPER diff --git a/external/cppcodec/meson.build b/external/cppcodec/meson.build new file mode 100644 index 0000000..4173aff --- /dev/null +++ b/external/cppcodec/meson.build @@ -0,0 +1,45 @@ +cppcodec_library_srcs = [ + 'base32_crockford.hpp', + 'base32_default_crockford.hpp', + 'base32_default_hex.hpp', + 'base32_default_rfc4648.hpp', + 'base32_hex.hpp', + 'base32_rfc4648.hpp', + 'base64_default_rfc4648.hpp', + 'base64_default_url.hpp', + 'base64_default_url_unpadded.hpp', + 'base64_rfc4648.hpp', + 'base64_url.hpp', + 'base64_url_unpadded.hpp', + 'hex_default_lower.hpp', + 'hex_default_upper.hpp', + 'hex_lower.hpp', + 'hex_upper.hpp', + 'parse_error.hpp', + 'data/access.hpp', + 'data/raw_result_buffer.hpp', + 'detail/base32.hpp', + 'detail/base64.hpp', + 'detail/codec.hpp', + 'detail/config.hpp', + 'detail/hex.hpp', + 'detail/stream_codec.hpp', + ] + +dlog_dep = dependency('dlog', method : 'pkg-config') + +cppcodec_deps = [ + dlog_dep, + ] + +cppcodec_include_dirs = include_directories( + '.', + ) + +cppcodec_library = library('cppcodec', + cppcodec_library_srcs, + include_directories : [ cppcodec_include_dirs ], + dependencies : [cppcodec_deps], + install_dir : mmi_prefix_plugindir, + install : true + ) diff --git a/external/cppcodec/parse_error.hpp b/external/cppcodec/parse_error.hpp new file mode 100644 index 0000000..97438ad --- /dev/null +++ b/external/cppcodec/parse_error.hpp @@ -0,0 +1,109 @@ +/** + * Copyright (C) 2015 Topology LP + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef CPPCODEC_PARSE_ERROR +#define CPPCODEC_PARSE_ERROR + +#include +#include + +namespace cppcodec { + +namespace detail { +// <*stream> headers include a lot of code and noticeably increase compile times. +// The only thing we want from them really is a char-to-string conversion. +// That's easy to implement with many less lines of code, so let's do it ourselves. +template +static void uctoa(unsigned char n, char (&s)[N]) +{ + static_assert(N >= 4, "need at least 4 bytes to convert an unsigned char to string safely"); + int i = sizeof(s) - 1; + int num_chars = 1; + s[i--] = '\0'; + do { // generate digits in reverse order + s[i--] = n % 10 + '0'; // get next digit + ++num_chars; + } while ((n /= 10) > 0); // delete it + + if (num_chars == sizeof(s)) { + return; + } + for (i = 0; i < num_chars; ++i) { // move chars to front of string + s[i] = s[i + (sizeof(s) - num_chars)]; + } +} +} // end namespace detail + + +class parse_error : public std::domain_error +{ +public: + using std::domain_error::domain_error; +}; + +// Avoids memory allocation, so it can be used in constexpr functions. +class symbol_error : public parse_error +{ +public: + symbol_error(char c) + : parse_error(symbol_error::make_error_message(c)) + , m_symbol(c) + { + } + + symbol_error(const symbol_error&) = default; + + char symbol() const noexcept { return m_symbol; } + +private: + static std::string make_error_message(char c) + { + char s[4]; + detail::uctoa(*reinterpret_cast(&c), s); + return std::string("parse error: character [") + &(s[0]) + " '" + c + "'] out of bounds"; + } + +private: + char m_symbol; +}; + +class invalid_input_length : public parse_error +{ +public: + using parse_error::parse_error; +}; + +class padding_error : public invalid_input_length +{ +public: + padding_error() + : invalid_input_length("parse error: codec expects padded input string but padding was invalid") + { + } + + padding_error(const padding_error&) = default; +}; + +} // namespace cppcodec + +#endif // CPPCODEC_PARSE_ERROR diff --git a/guide/custom-node-en.md b/guide/custom-node-en.md new file mode 100644 index 0000000..45aaa32 --- /dev/null +++ b/guide/custom-node-en.md @@ -0,0 +1,216 @@ +# Custom Node Development Guide + +## The Basics of Node Development: Standard Node Development Method + +Nodes that can be commonly used across various Tizen devices are managed as Standard Nodes, +and they can easily be added to a Workflow by specifying their enumeration values. + +An example using one of these Standard Nodes, the `Fixed String Match` Node, is shown below. +The `Fixed String Match` Node checks if any data coming into its input port named `TEXT` +matches with any of the elements within the string array type attribute named `CANDIDATES`. +If there's a match, the matched data will be outputted from the port named `MATCHED_CANDIDATE`. +Since this function can be commonly utilized across different Tizen devices, +it is being managed as a Standard Node. + +To use this Node in your Workflow, either write code like this: + +```c++ + mmi_workflow_h workflow = nullptr; + mmi_workflow_create(&workflow); + + mmi_node_h node_match = nullptr; + mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match); + mmi_workflow_node_add(workflow, "MATCH", node_match); + + mmi_node_destroy(node_match); + + mmi_workflow_destroy(workflow); +``` + +or create a Workflow script like so: + +``` +@node-list +[Logic] FIXED_STRING_MATCH as MATCH +``` + +In order to utilize a Node as a Standard Node, it must be declared as one of the +Node Enumeration values provided by the MMI Framework, such as: + +```c++ +enum mmi_node_logic_type_e { + /* Other enumeration types ... */ + MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, +``` + +When developing a Node Plugin, the above declared Node Enumeration value +should be used to provide Node information to the MMI Framework. + +```c++ +static int node_initialized_cb(mmi_node_instance_h instance) +{ + /* Node Callback function implementation */ + /* ... */ +} + +/* Function called by the MMI Framework to query the list of Nodes */ +EXPORT_API void mmi_plugin_module_get_node_list() +{ + mmi_node_callbacks_s node_callbacks { + node_initialized_cb, + node_deinitialized_cb, + /* Etc ... */ + }; + + mmi_port_callbacks_s text_port_callbacks { + port_output_format_requested_cb, + port_input_data_received_cb + }; + + mmi_port_h match_text_port = nullptr; + mmi_port_create(&match_text_port); + /* Additional port related configurations ... */ + + mmi_port_h match_candidate_port = nullptr; + mmi_port_create(&match_candidate_port); + /* Additional port related configurations ... */ + + mmi_node_h match_node = nullptr; + mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &match_node); + mmi_node_add_port(match_node, match_text_port); + mmi_node_add_port(match_node, match_candidate_port); + mmi_node_set_callbacks(match_node, node_callbacks); + mmi_node_register(match_node); +} +``` + +## The Need for Developing Custom Nodes + +Although we have explored how to develop Standard Nodes, there may be cases where some nodes +are only needed for specific products or scenarios among the available nodes. In such cases, +the MMI Framework cannot provide the declaration of Node Enumeration values. + +Therefore, registration as a Custom Node rather than a Standard Node is necessary in +these situations. Each Workflow can make use of them by assigning free-form string +identifiers instead of relying on enumeration values. + +Since free-form string identifiers might clash with other nodes, it is recommended to +follow a non-overlapping format similar to the Java Package Naming Convention, +such as "affiliation.organization.projectName". + +Reference URL : https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html + +## Custom Node Development Method + +To register a Custom Node with the MMI Framework, the code should be written in a manner similar +to the Standard Node development described earlier. However, when actually creating the Node, +the `mmi_node_create_custom()` function needs to be used. + +```c++ +/* Function called by the MMI Framework to query the list of Nodes */ +EXPORT_API void mmi_plugin_module_get_node_list() +{ + /* Callback / Port related declarations are the same as in the previous example */ + + mmi_node_h test_node = nullptr; + mmi_node_create_custom("com.samsung.tizen.test-node", &test_node); + mmi_node_set_callbacks(test_node, node_callbacks); + mmi_node_register(test_node); +} +``` + +## Verifying the Normal Operation of Developed Custom Nodes + +The MMI Framework provides a program called `mmi-cli-node-tester` to check whether +Nodes are operating correctly. By utilizing this program, each Node callback can be +tested for functionality. + +```console +[root@localhost ~]# dlogutil MMI-MODULE-TEST-NODE & + +[root@localhost ~]# mmi-cli-node-tester /usr/share/mmi/plugins/libmmi_module_test_node.so +tester> load + +tester> create +D/MMI-MODULE-TEST-NODE(160438): mmi-module-test-node.cpp: node_initialized_cb(16) > Node initialize callback is called for 0x557c1abdb0 + +tester> activate +D/MMI-MODULE-TEST-NODE(160438): mmi-module-test-node.cpp: node_activated_cb(35) > Node activate callback is called for 0x557c1abdb0 + +tester> help +Commands available: + - help + This help message + - exit + Quit the session + - loop + Start ecore main loop + - load + Load the node module that needs to be tested + - unload + Unload the currently loaded node module + - create + Create a new node instance + - destroy + Destroy the node instance with the given index + - activate + Activate the node instance with the given index + - deactivate + Dectivate the node instance with the given index + - set_attribute + (menu) + - push_data + (menu) + +tester> push_data + +push_data> help +Commands available: + - help + This help message + - exit + Quit the session + - int + Push an integer data + - text + Push a text data + - screen_info + Push a screen info data + - user_recognition + Push a user recognition info data + - audio + Push audio data from file + - video + Push video data from file + - tester + (menu) + +push_data> exit +``` + + +## Using Custom Nodes in a Workflow + +After completing the development and installation of a Custom Node, it can be used +by calling the `mmi_node_create_custom()` function in the code: +```c++ + mmi_workflow_h workflow = nullptr; + mmi_workflow_create(&workflow); + + mmi_node_h node_test = nullptr; + mmi_node_create_custom("com.samsung.tizen.test-node", &node_test); + mmi_workflow_node_add(workflow, "TEST_NODE", node_test); + + mmi_node_destroy(node_test); + + mmi_workflow_destroy(workflow); +``` + +Alternatively, a Workflow Script can be created like so: +``` +@node-list +[Custom] com.samsung.tizen.test-node as TEST +``` + +For testing a Custom Workflow containing a Custom Node, +refer to the [Custom Workflow Development Guide](custom-workflow-en.md). diff --git a/guide/custom-node-kr.md b/guide/custom-node-kr.md new file mode 100644 index 0000000..eea0143 --- /dev/null +++ b/guide/custom-node-kr.md @@ -0,0 +1,215 @@ +# Custom Node 개발 가이드 + +## Node 개발의 기본 : Standard Node 개발 방법 + +다양한 Tizen 기기들에서 공통적으로 사용이 가능한 Node 는 Standard Node 로 관리되고 있으며, +이들은 enumeration 을 통해 손쉽게 Workflow 에 추가가 가능하다. + +아래는 Standard Node 중 하나인 `Fixed String Match Node` 를 사용하는 예제를 보여주고 있다. +`Fixed String Match Node` 는 INPUT PORT 인 `TEXT` 라는 이름의 Port 로 들어온 데이터가, +`CANDIDATES` 라는 이름을 가진 String Array 타입의 Attribute 중 하나라도 일치하는 경우 +일치하는 데이터를 `MATCHED_CANDIDATE` 라는 이름의 OUTPUT PORT 로 출력해 주는 역할을 수행하며, +이러한 기능은 다양한 Tizen 기기들에서 공통적으로 사용될 수 있는 기능이기에 +Standard Node 로 관리되고 있다. + +해당 Node 를 Workflow 에서 사용하기 위해서는 아래와 같이 Code 를 작성하거나, + +```c++ + mmi_workflow_h workflow = nullptr; + mmi_workflow_create(&workflow); + + mmi_node_h node_match = nullptr; + mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match); + mmi_workflow_node_add(workflow, "MATCH", node_match); + + mmi_node_destroy(node_match); + + mmi_workflow_destroy(workflow); +``` + +혹은 다음과 같이 Workflow Script 를 작성하는 방식으로 사용할 수 있다. + +``` +@node-list +[Logic] FIXED_STRING_MATCH as MATCH +``` + +이렇듯 Standard Node 로 사용하기 위해서는, 아래와 같이 MMI Framework 에서 제공하는 +Node Enumeration 값 중 하나로 선언되어 있어야 하며, + +```c++ +enum mmi_node_logic_type_e { + /* Other enumeration types ... */ + MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, +``` + +Node Plugin 개발 시 위 선언된 Node Enumeration 값을 사용하여 MMI Framework 에 +Node 정보를 제공하여야 한다. + +```c++ +static int node_initialized_cb(mmi_node_instance_h instance) +{ + /* Node Callback 함수 구현부 */ + /* ... */ +} + +/* MMI Framework 이 Node 목록을 Query 하기 위해 부르는 함수 */ +EXPORT_API void mmi_plugin_module_get_node_list() +{ + mmi_node_callbacks_s node_callbacks { + node_initialized_cb, + node_deinitialized_cb, + /* 기타 등등 ... */ + }; + + mmi_port_callbacks_s text_port_callbacks { + port_output_format_requested_cb, + port_input_data_received_cb + }; + + mmi_port_h match_text_port = nullptr; + mmi_port_create(&match_text_port); + /* 기타 포트 관련 설정 ... */ + + mmi_port_h match_candidate_port = nullptr; + mmi_port_create(&match_candidate_port); + /* 기타 포트 관련 설정 ... */ + + mmi_node_h match_node = nullptr; + mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &match_node); + mmi_node_add_port(match_node, match_text_port); + mmi_node_add_port(match_node, match_candidate_port); + mmi_node_set_callbacks(match_node, node_callbacks); + mmi_node_register(match_node); +} +``` + +## Custom Node 개발의 필요성 + +위에서 Standard Node 를 개발하기 위한 방법에 대해 알아보았으나, 경우에 따라 +Node 들 중 각 Product 혹은 특정 시나리오에만 필요한 Node 도 있을 수 있으며, +이러한 Node 들은 Framework 차원에서 Node Enumeration 값 선언을 제공할 수가 없다. + +따라서, 이러한 경우에는 Standard Node 가 아닌 Custom Node 로의 등록이 필요하며, +Enumeration 기반이 아닌 Free-form string identifier 를 부여하여 +각 Workflow 에서 이를 사용할 수 있다. + +Free-form string identifier 는 다른 Node 와 중복될 가능성이 있으므로, +가급적 "소속기관.소속조직.프로젝트이름" 과 같이 Java Package Naming Convention +과 유사하게 중복되지 않는 형식을 따라 지정하는 것을 권장한다. + +참고 : https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html + +## Custom Node 개발 방법 + +Custom Node 를 MMI Framework 에 등록하기 위해서는, 위에서 설명한 +Standard Node 개발과 동일하게 코드를 작성하되, 실제 Node 생성시에 +`mmi_node_create_custom()` 함수를 사용하면 된다. + +```c++ +/* MMI Framework 이 Node 목록을 Query 하기 위해 부르는 함수 */ +EXPORT_API void mmi_plugin_module_get_node_list() +{ + /* 콜백 / 포트 관련 선언 부분은 상단 예제와 동일 */ + + mmi_node_h test_node = nullptr; + mmi_node_create_custom("com.samsung.tizen.test-node", &test_node); + mmi_node_set_callbacks(test_node, node_callbacks); + mmi_node_register(test_node); +} +``` + +## 개발된 Custom Node 정상 동작 여부 확인하기 + +MMI Framework 에서는 Node 의 정상 동작 여부를 확인할 수 있는 +`mmi-cli-node-tester` 라는 프로그램을 제공한다. +이 프로그램을 활용하여 각 Node Callback 들이 동작을 테스트해볼 수 있다. + +```console +[root@localhost ~]# dlogutil MMI-MODULE-TEST-NODE & + +[root@localhost ~]# mmi-cli-node-tester /usr/share/mmi/plugins/libmmi_module_test_node.so +tester> load + +tester> create +D/MMI-MODULE-TEST-NODE(160438): mmi-module-test-node.cpp: node_initialized_cb(16) > Node initialize callback is called for 0x557c1abdb0 + +tester> activate +D/MMI-MODULE-TEST-NODE(160438): mmi-module-test-node.cpp: node_activated_cb(35) > Node activate callback is called for 0x557c1abdb0 + +tester> help +Commands available: + - help + This help message + - exit + Quit the session + - loop + Start ecore main loop + - load + Load the node module that needs to be tested + - unload + Unload the currently loaded node module + - create + Create a new node instance + - destroy + Destroy the node instance with the given index + - activate + Activate the node instance with the given index + - deactivate + Dectivate the node instance with the given index + - set_attribute + (menu) + - push_data + (menu) + +tester> push_data + +push_data> help +Commands available: + - help + This help message + - exit + Quit the session + - int + Push an integer data + - text + Push a text data + - screen_info + Push a screen info data + - user_recognition + Push a user recognition info data + - audio + Push audio data from file + - video + Push video data from file + - tester + (menu) + +push_data> exit +``` + + +## Custom Node 를 Workflow 에서 사용하기 + +개발 및 설치가 완료된 Custom Node 는 `mmi_node_create_custom()` 함수를 Code 에서 호출하거나 +```c++ + mmi_workflow_h workflow = nullptr; + mmi_workflow_create(&workflow); + + mmi_node_h node_test = nullptr; + mmi_node_create_custom("com.samsung.tizen.test-node", &node_test); + mmi_workflow_node_add(workflow, "TEST_NODE", node_test); + + mmi_node_destroy(node_test); + + mmi_workflow_destroy(workflow); +``` + +혹은 다음과 같이 Workflow Script 를 작성하는 방식으로 사용할 수 있다. +``` +@node-list +[Custom] com.samsung.tizen.test-node as TEST +``` + +Custom Node 를 포함시킨 Custom Workflow 를 테스트하는 방법은 +[Custom Workflow 개발 가이드](custom-workflow-kr.md) 를 참고한다. diff --git a/guide/custom-workflow-kr.md b/guide/custom-workflow-kr.md new file mode 100644 index 0000000..58e1672 --- /dev/null +++ b/guide/custom-workflow-kr.md @@ -0,0 +1,165 @@ +# Custom Workflow 개발 가이드 + +## Standard Workflow 소개 + +MMI Framework 에서는 사용자에게 유용한 기능을 제공하는 +Standard Workflow 를 제공하고 있으며, 각 App 개발자들은 +해당 Standard Workflow 를 사용 요청하기만 하면 다양한 +Modality 들로부터 수집된 데이터를 해석한 결과를 손쉽게 +받아볼 수 있다. + +다음은 호출어 없이도 등록된 음성 명령어를 상시 검출하는 +기능을 제공하는 Wakeupless Command 라는 Workflow 를 +Application 에서 사용하는 예제를 보여주고 있다. + +```c++ +mmi_workflow_instance_h instance; +mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND, &instance); +mmi_workflow_instance_activate(instance); +``` + +## Custom Workflow 개발의 필요성 + +위에서 Standard Workflow 를 개발하기 위한 방법에 대해 알아보았으나, 경우에 따라 +Application 개발자가 다양한 Node 들로 이루어진 Workflow 를 +특정 시나리오에 맞추어 직접 구성하고 싶은 경우가 있을 수 있다. + +이러한 경우, Custom Workflow 를 생성하여 자유롭게 원하는 +Workflow 를 구성하여 실행시킬 수 있다. + +## Custom Workflow 생성 방법 + +Custom Workflow 를 생성하는 방법에는 크게 세가지가 있을 수 있다. + +첫번째는, Workflow Script 파일을 작성하고 이를 불러들이는 방법이다. + +다음과 같은 Workflow Script 를 "test.mws" 라는 이름으로 저장했다면, +``` +@workflow + +@node-list +[Source] MIC_AMBIENT as MIC +[Processor] ASR as ASR +[Logic] FIXED_STRING_MATCH as MATCH + +@link-list +MIC.AUDIO -> ASR.AUDIO +ASR.FINAL_ASR -> MATCH.TEXT + +@attribute-list +MATCH.CANDIDATES as COMMANDS + +@output-list +MATCH.COMMAND as MATCHED_CANDIDATE +``` +Application 에서 다음과 같이 해당 파일을 읽어들여 Workflow Instance 를 생성할 수 있다. + +```c++ +mmi_workflow_h workflow; +mmi_workflow_create_from_script_file("./test.mws", &workflow); + +mmi_workflow_instance_h instance; +mmi_custom_workflow_instance_create(workflow, &instance); +mmi_workflow_instance_activate(instance); +``` + +두번째는, 첫번째와 유사하지만 Workflow Script 를 파일이 아닌, Parameter 로 +직접 전달하여 Workflow Instance 를 생성하는 방법이다. + +```c++ +std::string script = R"( +@workflow + +@node-list +[Source] MIC_AMBIENT as MIC +[Processor] ASR as ASR +[Logic] FIXED_STRING_MATCH as MATCH + +@link-list +MIC.AUDIO -> ASR.AUDIO +ASR.FINAL_ASR -> MATCH.TEXT + +@attribute-list +MATCH.CANDIDATES as COMMANDS + +@output-list +MATCH.COMMAND as MATCHED_CANDIDATE +)"; + +mmi_workflow_h workflow; +mmi_workflow_create_from_script(script.c_str(), &workflow); + +mmi_workflow_instance_h instance; +mmi_custom_workflow_instance_create(workflow, &instance); +mmi_workflow_instance_activate(instance); +``` + +마지막으로는, API 를 통하여 Workflow Prototype 을 생성하는 방법이다. + +Code 를 작성하여야 하기에, 위에서 설명한 Workflow Script 작성 방식에 비해 +개발이 까다롭고 유연성이 떨어지지만, Script 에서 지원하지 않는 +다양한 기능을 사용할 수 있다는 장점이 있다. + +다음은 이러한 방법을 사용하여 Custom Workflow 를 정의하고 +이 Workflow 의 Instance 를 생성하는 Application 예제 코드이다. + +```c++ +mmi_workflow_h workflow; +mmi_workflow_create(&workflow); + +mmi_node_h node_mic = nullptr; +mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &node_mic); +mmi_workflow_node_add(workflow, "MIC", node_mic); + +mmi_node_h node_asr = nullptr; +mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &node_asr); +mmi_workflow_node_add(workflow, "ASR", node_asr); + +mmi_node_h node_match = nullptr; +mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match); +mmi_workflow_node_add(workflow, "MATCH", node_match); + +mmi_workflow_link_nodes_by_names(workflow, "MIC", "AUDIO", "ASR", "AUDIO"); +mmi_workflow_link_nodes_by_names(workflow, "ASR", "FINAL_ASR", "MATCH", "TEXT"); + +mmi_workflow_attribute_assign(workflow, "COMMANDS", "MATCH", "CANDIDATES"); + +mmi_workflow_output_assign(workflow, "COMMAND", "MATCH", "MATCHED_CANDIDATE"); + +mmi_workflow_instance_h instance; +mmi_custom_workflow_instance_create(workflow, &instance); +mmi_workflow_instance_activate(instance); +``` + +## Custom Workflow Script 동작 테스트하기 +MMI Framework 에서는 별도의 Client App 을 만들지 않고도 Custom Workflow Script 의 +정상 동작 여부를 확인할 수 있는 `mmi-cli` 라는 프로그램을 제공한다. + +```console +[root@localhost ~]# dlogutil MMIMGR & + +[root@localhost ~]# mmi-cli + +I/MMIMGR (179925): mmi-ipc-tidl.cpp: on_create(160) > Client(beb68b10-0a83-462f-beef-7960a7e7e2c5@) has been connected ! +I/MMIMGR (179925): mmi-client.cpp: add_client(67) > Add client(beb68b10-0a83-462f-beef-7960a7e7e2c5@) +D/MMIMGR (179925): mmi-workflow-instance-manager.cpp: handle_client_connected(148) > beb68b10-0a83-462f-beef-7960a7e7e2c5@ connected +State changed to 1 + +cli> create_from_file /tmp/test.mws + +Creating instance of script with path : /tmp/test.mws +D/MMIMGR (179925): mmi-plugin-module-registry.cpp: get_plugin_module_proxy(141) > Create plugin module proxy: -1379940944 +D/MMIMGR (179925): mmi-node-instance.cpp: NodeInstance(35) > Node instance is created : MMI_NODE_TYPE_SOURCE MMI_NODE_SOURCE_TYPE_MIC_AMBIENT +D/MMIMGR (179925): mmi-plugin-module-registry.cpp: get_plugin_module_proxy(130) > Plugin module proxy is expired: 1 /usr/share/mmi/plugins/libmmi_module_mic.so +D/MMIMGR (179925): mmi-plugin-module-registry.cpp: get_plugin_module_proxy(141) > Create plugin module proxy: 1 /usr/share/mmi/plugins/libmmi_module_mic.so +D/MMIMGR (179925): mmi-plugin-module-proxy.cpp: load_node_prototypes(109) > node_list.count: 1 +D/MMIMGR (179925): mmi-plugin-module-proxy.cpp: load_node_prototypes(117) > node_info[0].type: 1 +... + +cli> activate + +Activating instance +D/MMIMGR (179925): mmi-workflow-instance.cpp: activate(235) > Activating node instance : ASR(0x560499a8b0) +D/MMIMGR (179925): mmi-workflow-instance.cpp: activate(235) > Activating node instance : MATCH(0x560499d880) +D/MMIMGR (179925): mmi-workflow-instance.cpp: activate(235) > Activating node instance : MIC(0x5603c95a50) +``` diff --git a/mmi-config.xml b/mmi-config.xml deleted file mode 100644 index d211970..0000000 --- a/mmi-config.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - 0.5f - diff --git a/packaging/mmi.spec b/packaging/mmi.spec index 75ee998..4c6e39c 100644 --- a/packaging/mmi.spec +++ b/packaging/mmi.spec @@ -1,5 +1,5 @@ Name: mmi -Version: 2.1.0 +Version: 2.1.1 Release: 0 Summary: Multi-modal Interaction Framework License: MIT @@ -9,7 +9,6 @@ Source1004: %{name}.manifest BuildRequires: meson BuildRequires: tidl -BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(bundle) BuildRequires: pkgconfig(gio-2.0) BuildRequires: pkgconfig(glib-2.0) @@ -18,6 +17,7 @@ BuildRequires: pkgconfig(rpc-port) BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: pkgconfig(json-glib-1.0) #Build dependencies for tests BuildRequires: pkgconfig(gmock) @@ -79,6 +79,12 @@ CFLAGS+=" -fprofile-arcs -ftest-coverage -DTIZEN_TEST_GCOV" CXXFLAGS+=" -fprofile-arcs -ftest-coverage -DTIZEN_TEST_GCOV" LDFLAGS+=" -lgcov" %endif +%if 0%{?debug:1} +CFLAGS=$(echo $CFLAGS | sed 's/-O[1-3]/-Og/') +CXXFLAGS=$(echo $CXXFLAGS | sed 's/-O[1-3]/-Og/') +CFLAGS=$(echo $CFLAGS | sed 's/-D_FORTIFY_SOURCE=[1-9]/-D_FORTIFY_SOURCE=0/g') +CXXFLAGS=$(echo $CXXFLAGS | sed 's/-D_FORTIFY_SOURCE=[1-9]/-D_FORTIFY_SOURCE=0/g') +%endif meson setup --prefix=/usr \ --bindir %{_bindir} \ @@ -141,7 +147,6 @@ chsmack -e "System" %{_bindir}/mmi-manager %defattr(-,root,root,-) %license COPYING %{_datadir}/mmi/plugins/*.so* -%{_datadir}/mmi/scripts/*.mws %files cli %manifest %{name}.manifest @@ -155,7 +160,7 @@ chsmack -e "System" %{_bindir}/mmi-manager %manifest %{name}.manifest %defattr(-,root,root,-) %license COPYING -%{_includedir}/mmi*.h +%{_includedir}/mmi/mmi*.h %{_libdir}/pkgconfig/* %if 0%{?gcov:1} diff --git a/platform/linux/meson.build b/platform/linux/meson.build index 15842f3..34270e1 100644 --- a/platform/linux/meson.build +++ b/platform/linux/meson.build @@ -7,5 +7,7 @@ mmi_platform_specific_sub_directories = [] mmi_platform_specific_include_directory = 'platform/linux' install_headers( - 'mmi-platform-config.h' + 'mmi-platform-config.h', + 'tizen_error.h', + subdir : 'mmi' ) diff --git a/platform/linux/mmi-platform-config.h b/platform/linux/mmi-platform-config.h index f69b29d..dec7aad 100644 --- a/platform/linux/mmi-platform-config.h +++ b/platform/linux/mmi-platform-config.h @@ -6,8 +6,6 @@ #define EXPORT_API [[maybe_unused]] static const char *get_error_message(int err) { return "Unknown"; } -#define MMI_DEFAULT_CONFIG "/usr/local/mmi/configs/mmi-config.xml" - #define MMI_LOG(fmt, ...) \ do { \ printf("%s: %s(%d) > " fmt "\n", \ @@ -49,7 +47,9 @@ #define LOGW MMI_LOG #endif +#ifndef TIZEN_ERROR_MMI #define PLATFORM_ERROR_MMI -0x030F0000 +#endif #define PLATFORM_ERROR_NONE (0) #define PLATFORM_ERROR_OUT_OF_MEMORY (-1) diff --git a/platform/linux/tizen_error.h b/platform/linux/tizen_error.h new file mode 100644 index 0000000..c639111 --- /dev/null +++ b/platform/linux/tizen_error.h @@ -0,0 +1,10 @@ +#pragma once + +#define TIZEN_ERROR_NONE (0) +#define TIZEN_ERROR_OUT_OF_MEMORY (-1) +#define TIZEN_ERROR_IO_ERROR (-2) +#define TIZEN_ERROR_INVALID_PARAMETER (-3) +#define TIZEN_ERROR_OUT_OF_NETWORK (-4) +#define TIZEN_ERROR_TIMED_OUT (-5) +#define TIZEN_ERROR_PERMISSION_DENIED (-6) +#define TIZEN_ERROR_NOT_SUPPORTED (-7) diff --git a/platform/tizen/meson.build b/platform/tizen/meson.build index 9f08faf..ebf3ecf 100644 --- a/platform/tizen/meson.build +++ b/platform/tizen/meson.build @@ -1,11 +1,12 @@ mmi_platform = 'tizen' -mmi_platform_specific_dependencies = ['bundle', 'rpc-port', 'dlog', 'libtzplatform-config'] +mmi_platform_specific_dependencies = ['bundle', 'rpc-port', 'dlog'] mmi_platform_specific_client_files = ['mmi_proxy.c', 'mmi-ipc-tidl.cpp'] mmi_platform_specific_manager_files = ['mmi_stub.c', 'mmi-ipc-tidl.cpp'] mmi_platform_specific_sub_directories = [] mmi_platform_specific_include_directory = 'platform/tizen' install_headers( - 'mmi-platform-config.h' + 'mmi-platform-config.h', + subdir : 'mmi' ) diff --git a/platform/tizen/mmi-platform-config.h b/platform/tizen/mmi-platform-config.h index 8c0bc9a..a610a28 100644 --- a/platform/tizen/mmi-platform-config.h +++ b/platform/tizen/mmi-platform-config.h @@ -3,22 +3,6 @@ #include #include #include -#include - -#define MMI_DEFAULT_CONFIG tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "/mmi/configs/mmi-config.xml") - -#define TIZEN_ERROR_MMI -0x030F0000 - -#define PLATFORM_ERROR_NONE (TIZEN_ERROR_NONE) -#define PLATFORM_ERROR_OUT_OF_MEMORY (TIZEN_ERROR_OUT_OF_MEMORY) -#define PLATFORM_ERROR_IO_ERROR (TIZEN_ERROR_IO_ERROR) -#define PLATFORM_ERROR_INVALID_PARAMETER (TIZEN_ERROR_INVALID_PARAMETER) -#define PLATFORM_ERROR_OUT_OF_NETWORK (TIZEN_ERROR_NETWORK_DOWN) -#define PLATFORM_ERROR_TIMED_OUT (TIZEN_ERROR_TIMED_OUT) -#define PLATFORM_ERROR_PERMISSION_DENIED (TIZEN_ERROR_PERMISSION_DENIED) -#define PLATFORM_ERROR_NOT_SUPPORTED (TIZEN_ERROR_NOT_SUPPORTED) -#define PLATFORM_ERROR_OPERATION_FAILED (TIZEN_ERROR_MMI | 0x01) -#define PLATFORM_ERROR_RESOURCE_BUSY (TIZEN_ERROR_MMI | 0x02) #ifndef _E #define _E LOGE @@ -34,5 +18,4 @@ #ifndef _W #define _W LOGW -#endif - +#endif \ No newline at end of file diff --git a/plugins/workflows/meson.build b/plugins/workflows/meson.build index 952a1b0..d8a29e4 100644 --- a/plugins/workflows/meson.build +++ b/plugins/workflows/meson.build @@ -1,4 +1 @@ subdir('script-parser') -subdir('wakeupless-command') -subdir('voice-touch') -subdir('user-recognition') diff --git a/plugins/workflows/script-parser/meson.build b/plugins/workflows/script-parser/meson.build index 6da0280..132521c 100644 --- a/plugins/workflows/script-parser/meson.build +++ b/plugins/workflows/script-parser/meson.build @@ -12,6 +12,9 @@ mmi_module_script_parser_deps = [ mmi_module_script_parser_include_dirs = include_directories( '.', '../../../capi/', + '../../../capi/common', + '../../../capi/workflow', + '../../../capi/node', ) mmi_module_script_parser_library = library('mmi_module_script_parser', diff --git a/plugins/workflows/script-parser/mmi-module-script-parser.cpp b/plugins/workflows/script-parser/mmi-module-script-parser.cpp index 337d996..731ab32 100644 --- a/plugins/workflows/script-parser/mmi-module-script-parser.cpp +++ b/plugins/workflows/script-parser/mmi-module-script-parser.cpp @@ -5,6 +5,7 @@ #include "mmi-log.h" #include +#include #include #include @@ -21,7 +22,11 @@ extern "C" { auto const ext = entry.path().string().substr(pos + 1); if (ext == "mws") { mmi_workflow_h workflow = nullptr; - mmi_workflow_create_from_script_file(entry.path().string().c_str(), &workflow); + std::ifstream ifs(entry.path()); + std::string content((std::istreambuf_iterator(ifs)), + (std::istreambuf_iterator())); + + mmi_workflow_create_from_script(content.c_str(), &workflow); mmi_standard_workflow_register(workflow); mmi_workflow_destroy(workflow); } diff --git a/plugins/workflows/user-recognition/meson.build b/plugins/workflows/user-recognition/meson.build deleted file mode 100644 index 85328db..0000000 --- a/plugins/workflows/user-recognition/meson.build +++ /dev/null @@ -1 +0,0 @@ -install_data('user-recognition.mws', install_dir : mmi_prefix_scriptdir) diff --git a/plugins/workflows/user-recognition/user-recognition.mws b/plugins/workflows/user-recognition/user-recognition.mws deleted file mode 100644 index 9e7b5ec..0000000 --- a/plugins/workflows/user-recognition/user-recognition.mws +++ /dev/null @@ -1,23 +0,0 @@ -@workflow -name : USER_RECOGNITION - -@node-list -[Source] MIC_AMBIENT as MIC -[Source] CAMERA as CAMERA -[Processor] VIDEO_CONVERTER as VIDEO_CONVERTER -[Processor] FACE_RECOGNITION as FACE_RECOGNITION -[Processor] SPEAKER_RECOGNITION as SPEAKER_RECOGNITION -[Logic] USER_COMPARISON as USER_COMPARISON - -@link-list -CAMERA.VIDEO -> VIDEO_CONVERTER.VIDEO_IN -VIDEO_CONVERTER.VIDEO_OUT -> FACE_RECOGNITION.VIDEO -FACE_RECOGNITION.MATCHED_FACES -> USER_COMPARISON.PORT1 -MIC.AUDIO -> SPEAKER_RECOGNITION.AUDIO -SPEAKER_RECOGNITION.MATCHED_SPEAKERS -> USER_COMPARISON.PORT2 - -@attribute-list - -@output-list -USER_COMPARISON.BYPASS_RESULT as SINGLE_MODAL_USER_ID -USER_COMPARISON.COMPARISON_RESULT as MULTI_MODAL_USER_ID diff --git a/plugins/workflows/voice-touch/meson.build b/plugins/workflows/voice-touch/meson.build deleted file mode 100644 index 6bc11da..0000000 --- a/plugins/workflows/voice-touch/meson.build +++ /dev/null @@ -1,23 +0,0 @@ -mmi_module_voice_touch_library_srcs = [ - 'mmi-module-voice-touch.cpp', - ] - -ecore_dep = dependency('ecore', method : 'pkg-config') - -mmi_module_voice_touch_deps = [ - mmi_declared_dep, - ecore_dep, - ] - -mmi_module_voice_touch_include_dirs = include_directories( - '.', - '../../../capi/', - ) - -mmi_module_voice_touch_library = library('mmi_module_voice_touch', - mmi_module_voice_touch_library_srcs, - include_directories : [ mmi_module_voice_touch_include_dirs ], - dependencies : [mmi_module_voice_touch_deps], - install_dir : mmi_prefix_plugindir, - install : true - ) diff --git a/plugins/workflows/voice-touch/mmi-module-voice-touch.cpp b/plugins/workflows/voice-touch/mmi-module-voice-touch.cpp deleted file mode 100644 index 61fd242..0000000 --- a/plugins/workflows/voice-touch/mmi-module-voice-touch.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -#include - -#include "mmi-log.h" - -#include -#include - -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif -#define LOG_TAG "MMI-MODULE-VOICE-TOUCH" - -#define ENABLE_TEMP_RESCAN - -extern "C" { - - EXPORT_API void mmi_plugin_module_get_workflow_list() - { - const char *NODE_NAME_MIC = "MIC"; - const char *NODE_NAME_ASR = "ASR"; - const char *NODE_NAME_MATCH_MODE_COMMANDS = "MATCH_MODE_COMMANDS"; - const char *NODE_NAME_MATCH_PREDEFINED_COMMANDS = "MATCH_PREDEFINED_COMMANDS"; - const char *NODE_NAME_VOICE_TOUCH_PROCESSOR = "VOICE_TOUCH_PROCESSOR"; - const char *NODE_NAME_SCREEN_ANALYZER = "SCREEN_ANALYZER"; - - mmi_workflow_h workflow = nullptr; - mmi_workflow_create(&workflow); - - mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_VOICE_TOUCH); - - mmi_node_h node_mic = nullptr; - mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &node_mic); - mmi_workflow_node_add(workflow, NODE_NAME_MIC, node_mic); - - mmi_node_h node_asr = nullptr; - mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &node_asr); - mmi_workflow_node_add(workflow, NODE_NAME_ASR, node_asr); - - mmi_node_h node_match_mode_commands = nullptr; - mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match_mode_commands); - mmi_workflow_node_add(workflow, NODE_NAME_MATCH_MODE_COMMANDS, node_match_mode_commands); - - mmi_node_h node_match_predefined_commands = nullptr; - mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match_predefined_commands); - mmi_workflow_node_add(workflow, NODE_NAME_MATCH_PREDEFINED_COMMANDS, node_match_predefined_commands); - - mmi_node_h node_voice_touch = nullptr; - mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_VOICE_TOUCH, &node_voice_touch); - mmi_workflow_node_add(workflow, NODE_NAME_VOICE_TOUCH_PROCESSOR, node_voice_touch); - - mmi_node_h node_screen_analyzer = nullptr; - mmi_node_create_source(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER, &node_screen_analyzer); - mmi_workflow_node_add(workflow, NODE_NAME_SCREEN_ANALYZER, node_screen_analyzer); - -#ifdef ENABLE_TEMP_RESCAN - /* This is a temporary node for rescanning the screen, it will be removed when the signal mechanism is ready */ - mmi_node_h temp_node_match_rescan_command = nullptr; - mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &temp_node_match_rescan_command); - mmi_workflow_node_add(workflow, "TEMP_RESCAN", temp_node_match_rescan_command); -#endif - - mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_MIC, "AUDIO", NODE_NAME_ASR, "AUDIO"); - -#ifdef ENABLE_TEMP_RESCAN - mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_ASR, "FINAL_ASR", "TEMP_RESCAN", "TEXT"); - mmi_workflow_link_nodes_by_names(workflow, "TEMP_RESCAN", "REJECTED", NODE_NAME_MATCH_MODE_COMMANDS, "TEXT"); -#elif - mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_ASR, "FINAL_ASR", NODE_NAME_MATCH_MODE_COMMANDS, "TEXT"); -#endif - - mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_MATCH_MODE_COMMANDS, "MATCHED_CANDIDATE", NODE_NAME_VOICE_TOUCH_PROCESSOR, "MODE_COMMANDS"); - mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_MATCH_MODE_COMMANDS, "REJECTED", NODE_NAME_MATCH_PREDEFINED_COMMANDS, "TEXT"); - - mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_MATCH_PREDEFINED_COMMANDS, "REJECTED", NODE_NAME_VOICE_TOUCH_PROCESSOR, "UTTERANCE"); - - mmi_workflow_link_nodes_by_names(workflow, NODE_NAME_SCREEN_ANALYZER, "SCREEN_INFO", NODE_NAME_VOICE_TOUCH_PROCESSOR, "SCREEN_INFO"); - -#ifdef ENABLE_TEMP_RESCAN - /* These are temporary links for rescanning the screen, it will be removed when the signal mechanism is ready */ - mmi_workflow_link_nodes_by_names(workflow, "TEMP_RESCAN", "MATCHED_CANDIDATE", NODE_NAME_SCREEN_ANALYZER, "RESCAN"); -#endif - - // INFO: Attribute assigning - mmi_workflow_attribute_assign(workflow, "PREDEFINED_COMMANDS", NODE_NAME_MATCH_PREDEFINED_COMMANDS, "CANDIDATES"); - mmi_workflow_attribute_assign(workflow, "__MODE_COMMANDS", NODE_NAME_MATCH_MODE_COMMANDS, "CANDIDATES"); - mmi_workflow_attribute_assign(workflow, "GRID_CONFIGURATION", NODE_NAME_VOICE_TOUCH_PROCESSOR, "GRID_CONFIGURATION"); - mmi_workflow_attribute_assign(workflow, "ASR_STOP_METHOD", NODE_NAME_ASR, "STOP_METHOD"); - -#ifdef ENABLE_TEMP_RESCAN - /* These are temporary attributes for rescanning the screen, it will be removed when the signal mechanism is ready */ - mmi_workflow_attribute_assign(workflow, "REFRESH", NODE_NAME_SCREEN_ANALYZER, "RESCANNING"); - mmi_workflow_attribute_assign(workflow, "TEMP_RESCAN_COMMAND", "TEMP_RESCAN", "CANDIDATES"); -#endif - - mmi_workflow_output_assign(workflow, "PARTIAL_RESULT", NODE_NAME_ASR, "PARTIAL_ASR"); - mmi_workflow_output_assign(workflow, "FINAL_RESULT", NODE_NAME_ASR, "FINAL_ASR"); - - mmi_workflow_output_assign(workflow, "MATCHED_COMMAND", NODE_NAME_MATCH_PREDEFINED_COMMANDS, "MATCHED_CANDIDATE"); - - mmi_workflow_output_assign(workflow, "REJECTED", NODE_NAME_VOICE_TOUCH_PROCESSOR, "REJECTED"); - mmi_workflow_output_assign(workflow, "CANDIDATES", NODE_NAME_VOICE_TOUCH_PROCESSOR, "CANDIDATES"); - mmi_workflow_output_assign(workflow, "MATCHED_RESULT", NODE_NAME_VOICE_TOUCH_PROCESSOR, "MATCHED_RESULT"); - - const char *modes[] = { - "숫자 보여줘", - "텍스트 보여줘", - "그리드 보여줘", - }; - - mmi_attribute_h attribute = nullptr; - mmi_attribute_create_string_array("__MODE_COMMANDS", modes, sizeof(modes) / sizeof(const char *), &attribute); - mmi_workflow_attribute_set_default_value(workflow, attribute); - mmi_attribute_destroy(attribute); - -#ifdef ENABLE_TEMP_RESCAN - /* This is a temporary attribute for rescanning the screen, it will be removed when the signal mechanism is ready */ - const char *rescans[] = { - "새로고침", - "새로 고침", - }; - - mmi_attribute_h temp_attribute = nullptr; - mmi_attribute_create_string_array("TEMP_RESCAN_COMMAND", rescans, sizeof(rescans) / sizeof(const char *), &temp_attribute); - mmi_workflow_attribute_set_default_value(workflow, temp_attribute); - mmi_attribute_destroy(temp_attribute); -#endif - - mmi_standard_workflow_register(workflow); - -#ifdef ENABLE_TEMP_RESCAN - /* This is a temporary node for rescanning the screen, it will be removed when the signal mechanism is ready */ - mmi_node_destroy(temp_node_match_rescan_command); -#endif - - mmi_node_destroy(node_mic); - mmi_node_destroy(node_asr); - mmi_node_destroy(node_match_mode_commands); - mmi_node_destroy(node_match_predefined_commands); - mmi_node_destroy(node_voice_touch); - mmi_node_destroy(node_screen_analyzer); - - mmi_workflow_destroy(workflow); - } - -} // extern "C" diff --git a/plugins/workflows/wakeupless-command/meson.build b/plugins/workflows/wakeupless-command/meson.build deleted file mode 100644 index 2fc5a2a..0000000 --- a/plugins/workflows/wakeupless-command/meson.build +++ /dev/null @@ -1,23 +0,0 @@ -mmi_module_wakeupless_command_library_srcs = [ - 'mmi-module-wakeupless-command.cpp', - ] - -ecore_dep = dependency('ecore', method : 'pkg-config') - -mmi_module_wakeupless_command_deps = [ - mmi_declared_dep, - ecore_dep, - ] - -mmi_module_wakeupless_command_include_dirs = include_directories( - '.', - '../../../capi/', - ) - -mmi_module_wakeupless_command_library = library('mmi_module_wakeupless_command', - mmi_module_wakeupless_command_library_srcs, - include_directories : [ mmi_module_wakeupless_command_include_dirs ], - dependencies : [mmi_module_wakeupless_command_deps], - install_dir : mmi_prefix_plugindir, - install : true - ) diff --git a/plugins/workflows/wakeupless-command/mmi-module-wakeupless-command.cpp b/plugins/workflows/wakeupless-command/mmi-module-wakeupless-command.cpp deleted file mode 100644 index bf642cb..0000000 --- a/plugins/workflows/wakeupless-command/mmi-module-wakeupless-command.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif -#define LOG_TAG "MMI-MODULE-WAKEUPLESS-COMMAND" - -extern "C" { - - EXPORT_API void mmi_plugin_module_get_workflow_list() - { - mmi_workflow_h workflow = nullptr; - mmi_workflow_create(&workflow); - - mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); - - mmi_node_h node_mic = nullptr; - /* FIXME: node should be 'found' instead of 'created' */ - mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &node_mic); - mmi_workflow_node_add(workflow, "MIC", node_mic); - - mmi_node_h node_asr = nullptr; - mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &node_asr); - mmi_workflow_node_add(workflow, "ASR", node_asr); - - mmi_node_h node_match = nullptr; - mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match); - mmi_workflow_node_add(workflow, "MATCH", node_match); - - mmi_workflow_link_nodes_by_names(workflow, "MIC", "AUDIO", "ASR", "AUDIO"); - mmi_workflow_link_nodes_by_names(workflow, "ASR", "FINAL_ASR", "MATCH", "TEXT"); - - mmi_workflow_attribute_assign(workflow, "COMMANDS", "MATCH", "CANDIDATES"); - mmi_workflow_attribute_assign(workflow, "LANGUAGE", "ASR", "LANGUAGE"); - mmi_workflow_attribute_assign(workflow, "STOP_METHOD", "ASR", "STOP_METHOD"); - mmi_workflow_attribute_assign(workflow, "ASR_START", "ASR", "ASR_START"); - - mmi_workflow_output_assign(workflow, "COMMAND", "MATCH", "MATCHED_CANDIDATE"); - mmi_workflow_output_assign(workflow, "UTTERANCE", "ASR", "PARTIAL_ASR"); - mmi_workflow_output_assign(workflow, "UTTERANCE", "ASR", "FINAL_ASR"); - - mmi_workflow_signal_assign(workflow, "CONTROL", "ASR", "CONTROL"); - - mmi_standard_workflow_register(workflow); - - mmi_node_destroy(node_mic); - mmi_node_destroy(node_asr); - mmi_node_destroy(node_match); - - mmi_workflow_destroy(workflow); - } - -} // extern "C" diff --git a/src/common/mmi-common.h b/src/common/mmi-common.h new file mode 100644 index 0000000..75ccd38 --- /dev/null +++ b/src/common/mmi-common.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 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. + * + */ + +#ifndef __MMI_COMMON_H__ +#define __MMI_COMMON_H__ + +#include "mmi-log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MMI_API __attribute__ ((visibility("default"))) + +#ifdef __cplusplus +} +#endif + + +#endif //__MMI_COMMON_H__ diff --git a/src/common/mmi-plugin-module.h b/src/common/mmi-plugin-module.h new file mode 100644 index 0000000..7581a15 --- /dev/null +++ b/src/common/mmi-plugin-module.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 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. + * + */ + + +#ifndef __TIZEN_UIX_MMI_PLUGIN_MODULE_H__ +#define __TIZEN_UIX_MMI_PLUGIN_MODULE_H__ + + +#include + +/** +* @file mmi-plugin-module.h +*/ + + +/** +* @addtogroup CAPI_UIX_MMI_MODULE +* @{ +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +/* If a plugin module wants to provide Nodes to mmi framework, + * it should implement a function named "mmi_plugin_module_get_node_list", + * with the following prototype. */ +#define MMI_PLUGIN_MODULE_GET_NODE_LIST_FUNC_NAME "mmi_plugin_module_get_node_list" +typedef void (*mmi_plugin_module_get_node_list_func)(); + +/* If a plugin module wants to provide Workflows to mmi framework, + * it should implement a function named "mmi_plugin_module_get_workflow_list", + * with the following prototype. */ +#define MMI_PLUGIN_MODULE_GET_WORKFLOW_LIST_FUNC_NAME "mmi_plugin_module_get_workflow_list" +typedef void (*mmi_plugin_module_get_workflow_list_func)(); + +#ifdef __cplusplus +} +#endif + + +/** + * @} + */ + + +#endif /* __TIZEN_UIX_MMI_PLUGIN_MODULE_H__ */ diff --git a/src/common/mmi-plugin-storage.h b/src/common/mmi-plugin-storage.h new file mode 100644 index 0000000..9c73d7f --- /dev/null +++ b/src/common/mmi-plugin-storage.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2023 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. + * + */ + + +#ifndef __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__ +#define __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__ + + +#include +#include +#include +#include +#include + +/** +* @file mmi-plugin-storage.h +*/ + + +/** +* @addtogroup CAPI_UIX_MMI_MODULE +* @{ +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +/* The functions and structs below are used by MMI framework */ + +typedef struct { + mmi_node_h *nodes; + size_t node_count; +} mmi_plugin_module_node_list_s; + +typedef struct { + mmi_workflow_h *workflows; + size_t workflow_count; +} mmi_plugin_module_workflow_list_s; + + +typedef struct { + char name[MMI_NAME_MAX_LENGTH]; + mmi_port_instance_h port; +} mmi_plugin_module_port_instance_info_s; + +typedef struct { + mmi_node_instance_h node; + mmi_plugin_module_port_instance_info_s port_infos[MMI_PORT_MAX_COUNT]; + size_t port_info_count; +} mmi_plugin_module_node_instance_info_s; + +typedef void (*mmi_plugin_module_port_instance_output_handler_func)( + mmi_port_instance_h port, mmi_data_h data, void *user_data); + +typedef void (*mmi_plugin_module_switch_node_event_handler_func)( + mmi_node_instance_h node, const char *controllee, bool state, void *user_data); + +typedef struct { + mmi_plugin_module_port_instance_output_handler_func port_instance_output_handler; + mmi_plugin_module_switch_node_event_handler_func switch_node_event_handler; +} mmi_plugin_module_event_handler_info_s; + +/* MMI Manager will invoke this function to set the current identifier of the plugin module. */ +void mmi_plugin_storage_set_current_module_identifier(const char *identifier); + +/* Each plugin modules will call this functino to get the current identifier of the plugin module. */ +const char* mmi_plugin_storage_get_current_module_identifier(); + +/* Each plugin modules will call these functions to register their nodes and workflows. */ +void mmi_plugin_storage_set_node_list(mmi_plugin_module_node_list_s node_list); +void mmi_plugin_storage_set_workflow_list(mmi_plugin_module_workflow_list_s workflow_list); + +/* MMI Manager will invoke these functions to get the node list of the plugin module. */ +mmi_plugin_module_node_list_s mmi_plugin_storage_get_node_list(const char *identifier); +mmi_plugin_module_workflow_list_s mmi_plugin_storage_get_workflow_list(const char *identifier); + +/* MMI Manager will invoke these function to notify the node instance addition and removal. */ +void mmi_plugin_storage_add_node_instance_info(mmi_plugin_module_node_instance_info_s *info); +void mmi_plugin_storage_remove_node_instance_info(mmi_node_instance_h node_instance); + +/* Each plugin modules will call this function to find appropriate port instance */ +mmi_port_instance_h mmi_plugin_storage_find_port_instance( + mmi_node_instance_h node_instance, const char *port_name); +mmi_node_instance_h mmi_plugin_storage_find_node_instance_by_port_instance(mmi_port_instance_h port_instance); + +/* MMI Manager will invoke these function to register / unregister the event handlers */ +void mmi_plugin_storage_set_plugin_module_event_handler( + mmi_plugin_module_event_handler_info_s handler_info, void *user_data); +void mmi_plugin_storage_unset_plugin_module_event_handler(); + +/* Each plugin modules will call this function to notify the plugin module events */ +mmi_plugin_module_event_handler_info_s mmi_plugin_storage_get_plugin_module_event_handler(); +void* mmi_plugin_storage_get_plugin_module_event_handler_user_data(); + +#ifdef __cplusplus +} +#endif + + +/** + * @} + */ + + +#endif /* __TIZEN_UIX_MMI_PLUGIN_STORAGE_H__ */ diff --git a/src/mmi-cli/meson.build b/src/mmi-cli/meson.build index e90d46e..5557db1 100644 --- a/src/mmi-cli/meson.build +++ b/src/mmi-cli/meson.build @@ -1,10 +1,12 @@ ecore_dep = dependency('ecore', method : 'pkg-config') dl_dep = meson.get_compiler('c').find_library('dl', required : true) +json_dep = dependency('json-glib-1.0', method : 'pkg-config') mmi_cli_deps = [ mmi_declared_dep, ecore_dep, dl_dep, + json_dep, ] foreach platform_specific_dependency : mmi_platform_specific_dependencies @@ -18,6 +20,9 @@ mmi_cli_include_dirs = include_directories( '.', '../common/', '../../capi/', + '../../capi/common', + '../../capi/workflow', + '../../capi/node', '../../external/', mmi_extra_include_dir, ) diff --git a/src/mmi-cli/mmi-cli-node-tester.cpp b/src/mmi-cli/mmi-cli-node-tester.cpp index b6cabd3..39c71ee 100644 --- a/src/mmi-cli/mmi-cli-node-tester.cpp +++ b/src/mmi-cli/mmi-cli-node-tester.cpp @@ -11,6 +11,7 @@ #include "cli/cli.h" #include "mmi.h" +#include "mmi-defines.h" #include "mmi-plugin-module.h" #include "mmi-plugin-storage.h" @@ -26,14 +27,14 @@ struct PortInstance std::string m_name; mmi_port_type_e m_port_type; mmi_data_type_e m_data_type; - mmi_port_callbacks m_callbacks{{nullptr}, {nullptr}}; + mmi_port_callbacks_s m_callbacks{{nullptr}, {nullptr}}; }; struct NodeInstance { mmi_node_type_e m_node_type; - mmi_node_callbacks m_callbacks{{nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}}; + mmi_node_callbacks_s m_callbacks{{nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}}; std::vector m_ports; }; @@ -118,10 +119,10 @@ AttributeTestEntry g_attribute_test_entries[] = { try { value = std::stoi(input); } catch (std::invalid_argument& e) { - _E("Invalid argument: %s", e.what()); + MMI_CLI_LOG_("Invalid argument: %s", e.what()); return; } catch (std::out_of_range& e) { - _E("Out of range: %s", e.what()); + MMI_CLI_LOG_("Out of range: %s", e.what()); return; } mmi_primitive_value_h primitive_value = nullptr; @@ -158,10 +159,10 @@ AttributeTestEntry g_attribute_test_entries[] = { try { value = std::stoi(input); } catch (std::invalid_argument& e) { - _E("Invalid argument: %s", e.what()); + MMI_CLI_LOG_("Invalid argument: %s", e.what()); return; } catch (std::out_of_range& e) { - _E("Out of range: %s", e.what()); + MMI_CLI_LOG_("Out of range: %s", e.what()); return; } mmi_primitive_value_h primitive_value = nullptr; @@ -196,7 +197,7 @@ DataTestEntry g_data_test_entries[] = { int value = program->read_int_value("Enter data value: "); mmi_data_create_int(value, &data); if (data) { - port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data); + port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data, nullptr); mmi_data_destroy(data); } } @@ -210,7 +211,7 @@ DataTestEntry g_data_test_entries[] = { std::string value = program->read_string_value("Enter data value: "); mmi_data_create_text(value.c_str(), &data); if (data) { - port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data); + port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data, nullptr); mmi_data_destroy(data); } } @@ -261,7 +262,7 @@ DataTestEntry g_data_test_entries[] = { mmi_data_add_array_element(data, struct_data); } if (data) { - port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data); + port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data, nullptr); mmi_data_destroy(data); } } @@ -305,7 +306,7 @@ DataTestEntry g_data_test_entries[] = { mmi_data_set_struct_element(data, "recognizedCandidates", candidates); if (data) { - port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data); + port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data, nullptr); mmi_data_destroy(data); } } @@ -325,13 +326,13 @@ DataTestEntry g_data_test_entries[] = { mmi_data_h data = nullptr; mmi_data_create_audio(frame_buf, size, &data); if (data) { - port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data); + port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data, nullptr); mmi_data_destroy(data); } } fclose(fp); } else { - _E("Failed to open file %s", value.c_str()); + MMI_CLI_LOG_("Failed to open file %s", value.c_str()); } } }, @@ -350,13 +351,13 @@ DataTestEntry g_data_test_entries[] = { mmi_data_h data = nullptr; mmi_data_create_video(frame_buf, size, &data); if (data) { - port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data); + port_instance->m_callbacks.input_data_received_cb(static_cast(port_instance), data, nullptr); mmi_data_destroy(data); } } fclose(fp); } else { - _E("Failed to open file %s", value.c_str()); + MMI_CLI_LOG_("Failed to open file %s", value.c_str()); } } }, @@ -377,28 +378,28 @@ void Program::log_mmi_data(PortInstance *port_instance, mmi_data_h data) { { bool value; mmi_data_get_bool(data, &value); - _D("Port %s generated data type %d (BOOLEAN), value %d", port_instance->m_name.c_str(), type, value); + MMI_CLI_LOG_("Port %s generated data type %d (BOOLEAN), value %d", port_instance->m_name.c_str(), type, value); } break; case MMI_DATA_TYPE_INTEGER: { int value; mmi_data_get_int(data, &value); - _D("Port %s generated data type %d (INTEGER), value %d", port_instance->m_name.c_str(), type, value); + MMI_CLI_LOG_("Port %s generated data type %d (INTEGER), value %d", port_instance->m_name.c_str(), type, value); } break; case MMI_DATA_TYPE_FLOAT: { float value; mmi_data_get_float(data, &value); - _D("Port %s generated data type %d (FLOAT), value %f", port_instance->m_name.c_str(), type, value); + MMI_CLI_LOG_("Port %s generated data type %d (FLOAT), value %f", port_instance->m_name.c_str(), type, value); } break; case MMI_DATA_TYPE_TEXT: { const char *value = nullptr; mmi_data_get_text(data, &value); - _D("Port %s generated data type %d (TEXT), value %s", port_instance->m_name.c_str(), type, value); + MMI_CLI_LOG_("Port %s generated data type %d (TEXT), value %s", port_instance->m_name.c_str(), type, value); } break; case MMI_DATA_TYPE_USER_IDENTIFICATION: @@ -412,7 +413,7 @@ void Program::log_mmi_data(PortInstance *port_instance, mmi_data_h data) { snprintf(buf, sizeof(buf), "%02x", ((unsigned char*)ptr)[i]); hex_string += buf; } - _D("Port %s generated data type %d (USER_IDENTIFICATION), size %zu, hex %s", + MMI_CLI_LOG_("Port %s generated data type %d (USER_IDENTIFICATION), size %zu, hex %s", port_instance->m_name.c_str(), type, len, hex_string.c_str()); } break; @@ -424,7 +425,7 @@ void Program::log_mmi_data(PortInstance *port_instance, mmi_data_h data) { for (size_t i = 0; i < count; i++) { mmi_data_h element = nullptr; mmi_data_get_array_element(data, i, &element); - _D("Array Element %zu", i); + MMI_CLI_LOG_("Array Element %zu", i); log_mmi_data(port_instance, element); } } @@ -437,7 +438,7 @@ void Program::log_mmi_data(PortInstance *port_instance, mmi_data_h data) { for (size_t i = 0; i < count; i++) { const char *element_name = nullptr; mmi_data_get_struct_element_name(data, i, &element_name); - _D("Struct Element %zu : %s", i, element_name); + MMI_CLI_LOG_("Struct Element %zu : %s", i, element_name); mmi_data_h element_value = nullptr; mmi_data_get_struct_element_value(data, i, &element_value); log_mmi_data(port_instance, element_value); @@ -445,14 +446,14 @@ void Program::log_mmi_data(PortInstance *port_instance, mmi_data_h data) { } break; default: - _D("Port %s generated data type %d", port_instance->m_name.c_str(), type); + MMI_CLI_LOG_("Port %s generated data type %d", port_instance->m_name.c_str(), type); break; } } void Program::port_instance_output_handler(mmi_port_instance_h port, mmi_data_h data, void *user_data) { if (port == nullptr || data == nullptr) { - _E("Invalid parameter : port(%p), data(%p)", port, data); + MMI_CLI_LOG_("Invalid parameter : port(%p), data(%p)", port, data); return; } @@ -468,7 +469,7 @@ void Program::load_module(std::string path) { m_handle = dlopen(path.c_str(), RTLD_NOW); if (!m_handle) { - _E("Failed to load plugin module: %s", dlerror()); + MMI_CLI_LOG_("Failed to load plugin module: %s", dlerror()); return; } @@ -476,7 +477,7 @@ void Program::load_module(std::string path) { auto prepare_node_list = reinterpret_cast( dlsym(m_handle, MMI_PLUGIN_MODULE_GET_NODE_LIST_FUNC_NAME)); if (!prepare_node_list) { - _E("Failed to find symbol: %s", dlerror()); + MMI_CLI_LOG_("Failed to find symbol: %s", dlerror()); return; } @@ -485,16 +486,16 @@ void Program::load_module(std::string path) { m_node_list = mmi_plugin_storage_get_node_list(path.c_str()); /* Dump node_list */ - _D("node_list.count: %zu", m_node_list.node_count); + MMI_CLI_LOG_("node_list.count: %zu", m_node_list.node_count); for (size_t i = 0;i < m_node_list.node_count;i++) { mmi_node_h node = m_node_list.nodes[i]; mmi_node_type_e type; mmi_node_get_type(node, &type); - mmi_node_callbacks callbacks; + mmi_node_callbacks_s callbacks; mmi_node_get_callbacks(node, &callbacks); size_t port_count; - _D("node_info[%zu].type: %d", i, type); - _D("node_info[%zu].callbacks : %p %p %p %p %p %p", i, + MMI_CLI_LOG_("node_info[%zu].type: %d", i, type); + MMI_CLI_LOG_("node_info[%zu].callbacks : %p %p %p %p %p %p", i, callbacks.initialized_cb, callbacks.deinitialized_cb, callbacks.attribute_set_cb, @@ -502,7 +503,7 @@ void Program::load_module(std::string path) { callbacks.deactivated_cb, callbacks.signal_received_cb); mmi_node_get_port_count(node, &port_count); - _D("node_info[%zu].port_list.count: %zu", i, port_count); + MMI_CLI_LOG_("node_info[%zu].port_list.count: %zu", i, port_count); for (size_t j = 0;j < port_count;j++) { mmi_port_h port; mmi_node_get_port(node, j, &port); @@ -513,12 +514,12 @@ void Program::load_module(std::string path) { mmi_port_get_type(port, &port_type); mmi_data_type_e data_type; mmi_port_get_data_type(port, &data_type); - mmi_port_callbacks port_callbacks; + mmi_port_callbacks_s port_callbacks; mmi_port_get_callbacks(port, &port_callbacks); - _D("node_info[%zu].port_info[%zu].name: %s", i, j, name); - _D("node_info[%zu].port_info[%zu].type: %d", i, j, port_type); - _D("node_info[%zu].port_info[%zu].data_type: %d", i, j, data_type); - _D("node_info[%zu].port_info[%zu].callbacks: %p %p", i, j, + MMI_CLI_LOG_("node_info[%zu].port_info[%zu].name: %s", i, j, name); + MMI_CLI_LOG_("node_info[%zu].port_info[%zu].type: %d", i, j, port_type); + MMI_CLI_LOG_("node_info[%zu].port_info[%zu].data_type: %d", i, j, data_type); + MMI_CLI_LOG_("node_info[%zu].port_info[%zu].callbacks: %p %p", i, j, port_callbacks.output_format_requested_cb, port_callbacks.input_data_received_cb); } @@ -532,7 +533,7 @@ void Program::unload_module() { std::string Program::read_string_value(std::string prompt) { if (!m_session) { - _E("Session is not created"); + MMI_CLI_LOG_("Session is not created"); return ""; } std::cout << prompt; @@ -547,10 +548,10 @@ int Program::read_int_value(std::string prompt) { try { value = std::stoi(string_value); } catch (std::invalid_argument& e) { - _E("Invalid argument: %s", e.what()); + MMI_CLI_LOG_("Invalid argument: %s", e.what()); return -1; } catch (std::out_of_range& e) { - _E("Out of range: %s", e.what()); + MMI_CLI_LOG_("Out of range: %s", e.what()); return -1; } return value; @@ -563,7 +564,7 @@ void Program::create_node_instance() { mmi_node_h node = m_node_list.nodes[0]; mmi_node_type_e type; mmi_node_get_type(node, &type); - mmi_node_callbacks callbacks; + mmi_node_callbacks_s callbacks; mmi_node_get_callbacks(node, &callbacks); node_instance->m_node_type = type; @@ -585,7 +586,7 @@ void Program::create_node_instance() { mmi_port_get_type(port, &port_type); mmi_data_type_e data_type; mmi_port_get_data_type(port, &data_type); - mmi_port_callbacks port_callbacks; + mmi_port_callbacks_s port_callbacks; mmi_port_get_callbacks(port, &port_callbacks); PortInstance *port_instance = new PortInstance(); @@ -606,9 +607,9 @@ void Program::create_node_instance() { mmi_plugin_storage_add_node_instance_info(&node_instance_info); m_node_instance_map[m_node_instance_index] = node_instance; - node_instance->m_callbacks.initialized_cb(static_cast(node_instance)); + node_instance->m_callbacks.initialized_cb(static_cast(node_instance), nullptr); - _D("Created node instance: %zu", m_node_instance_index); + MMI_CLI_LOG_("Created node instance: %zu", m_node_instance_index); m_node_instance_index++; } @@ -621,7 +622,7 @@ NodeInstance* Program::get_node_instance() { int index = read_int_value("Enter instance id: "); auto it = m_node_instance_map.find(index); if (it == m_node_instance_map.end()) { - _E("Failed to find node instance: %d", index); + MMI_CLI_LOG_("Failed to find node instance: %d", index); return nullptr; } node_instance = it->second; @@ -633,7 +634,7 @@ void Program::destroy_node_instance() { NodeInstance *node_instance = get_node_instance(); if (!node_instance) return; - node_instance->m_callbacks.deinitialized_cb(static_cast(node_instance)); + node_instance->m_callbacks.deinitialized_cb(static_cast(node_instance), nullptr); mmi_plugin_storage_remove_node_instance_info(static_cast(node_instance)); for (auto port_instance : node_instance->m_ports) { delete port_instance; @@ -653,14 +654,14 @@ void Program::activate_node_instance() { NodeInstance *node_instance = get_node_instance(); if (!node_instance) return; - node_instance->m_callbacks.activated_cb(static_cast(node_instance)); + node_instance->m_callbacks.activated_cb(static_cast(node_instance), nullptr); } void Program::deactivate_node_instance() { NodeInstance *node_instance = get_node_instance(); if (!node_instance) return; - node_instance->m_callbacks.deactivated_cb(static_cast(node_instance)); + node_instance->m_callbacks.deactivated_cb(static_cast(node_instance), nullptr); } void Program::set_attribute(AttributeTestType type) { @@ -670,7 +671,7 @@ void Program::set_attribute(AttributeTestType type) { mmi_attribute_h attribute = nullptr; if (type >= AttributeTestType::MaxCount) { - _E("Invalid attribute type"); + MMI_CLI_LOG_("Invalid attribute type"); return; } @@ -682,12 +683,12 @@ void Program::set_attribute(AttributeTestType type) { } } if (entry_index == static_cast(AttributeTestType::MaxCount)) { - _E("Failed to find attribute type: %zu", static_cast(type)); + MMI_CLI_LOG_("Failed to find attribute type: %zu", static_cast(type)); return; } g_attribute_test_entries[entry_index].attribute_generator(this, &attribute); - node_instance->m_callbacks.attribute_set_cb(static_cast(node_instance), attribute); + node_instance->m_callbacks.attribute_set_cb(static_cast(node_instance), attribute, nullptr); mmi_attribute_destroy(attribute); } @@ -696,7 +697,7 @@ void Program::push_data(DataTestType type) { if (!node_instance) return; if (type >= DataTestType::MaxCount) { - _E("Invalid data type"); + MMI_CLI_LOG_("Invalid data type"); return; } @@ -711,7 +712,7 @@ void Program::push_data(DataTestType type) { } } if (entry_index == static_cast(DataTestType::MaxCount)) { - _E("Failed to find data type"); + MMI_CLI_LOG_("Failed to find data type"); return; } g_data_test_entries[entry_index].data_generator(this, port_instance); diff --git a/src/mmi-cli/mmi-cli.cpp b/src/mmi-cli/mmi-cli.cpp index c0b137f..26b50a8 100644 --- a/src/mmi-cli/mmi-cli.cpp +++ b/src/mmi-cli/mmi-cli.cpp @@ -1,12 +1,205 @@ +#include #include #include +#include "adishavit/argh.h" +#include "magic_enum/magic_enum.hpp" + #include "cliecoresession.h" #include "cli/cli.h" #include "mmi.h" +#ifdef USE_VOICE_TOUCH_TV +#include +#include "cppcodec/base64_rfc4648.hpp" + +using base64 = cppcodec::base64_rfc4648; + +std::string convert(std::string &input) +{ + std::string upperCaseInput = input; + transform(upperCaseInput.begin(), upperCaseInput.end(), upperCaseInput.begin(), ::toupper); + + switch (upperCaseInput[0]) { + case 'U': + return "MoveUpCommand"; + case 'D': + return "MoveDownCommand"; + case 'R': + return "MoveRightCommand"; + case 'L': + return "MoveLeftCommand"; + default: + break; + } + + return ""; +} + +static char *get_title_viv_response(std::string &value) +{ + JsonBuilder *builder = json_builder_new(); + JsonNode *node = NULL; + JsonGenerator *generator = NULL; + gsize length = 0; + gchar *data = NULL; + std::string uri = "bixby://com.samsung.tv.vif/tvVoiceInteraction.SendContentTitle/punchOut?titles="; + uri += value; + + json_builder_begin_object(builder); + json_builder_set_member_name(builder, "type"); + json_builder_add_int_value(builder, 14); + + json_builder_set_member_name(builder, "viv"); + json_builder_begin_object(builder); + json_builder_set_member_name(builder, "ClientFunctionCall"); + json_builder_begin_object(builder); + + json_builder_set_member_name(builder, "argumentsJson"); + json_builder_begin_object(builder); + json_builder_set_member_name(builder, "uri"); + + json_builder_add_string_value(builder, uri.c_str()); + json_builder_end_object(builder); + json_builder_end_object(builder); + json_builder_end_object(builder); + json_builder_end_object(builder); + + node = json_builder_get_root(builder); + g_object_unref(builder); + + generator = json_generator_new(); + json_generator_set_root(generator, node); + + // convert json data into string + data = json_generator_to_data(generator, &length); + + json_node_free(node); + g_object_unref(generator); + return data; +} + +static char *get_ordinal_viv_response(std::string value) +{ + JsonBuilder *builder = json_builder_new(); + JsonNode *node = NULL; + JsonGenerator *generator = NULL; + gsize length = 0; + gchar *data = NULL; + std::string uri = "bixby://com.samsung.tv.vif/tvVoiceInteraction.SendOrdinalNumber/punchOut?OrdinalNumber="; + uri += value; + + json_builder_begin_object(builder); + json_builder_set_member_name(builder, "type"); + json_builder_add_int_value(builder, 14); + + json_builder_set_member_name(builder, "viv"); + json_builder_begin_object(builder); + json_builder_set_member_name(builder, "ClientFunctionCall"); + json_builder_begin_object(builder); + + json_builder_set_member_name(builder, "serviceCallId"); + json_builder_add_string_value(builder, "199ba17e-6a4b-4302-9a0a-59cf13562133"); + + json_builder_set_member_name(builder, "actionId"); + json_builder_add_string_value(builder, "1.0.109-samsung.tvVoiceInteraction.SendOrdinalNumber"); + + json_builder_set_member_name(builder, "argumentsJson"); + json_builder_begin_object(builder); + json_builder_set_member_name(builder, "uri"); + + json_builder_add_string_value(builder, uri.c_str()); + json_builder_end_object(builder); + json_builder_end_object(builder); + json_builder_end_object(builder); + json_builder_end_object(builder); + + node = json_builder_get_root(builder); + g_object_unref(builder); + + generator = json_generator_new(); + json_generator_set_root(generator, node); + + // convert json data into string + data = json_generator_to_data(generator, &length); + + json_node_free(node); + g_object_unref(generator); + return data; +} + +static char *get_navigation_viv_response(std::string direction, std::string repeat) +{ + JsonBuilder *builder = json_builder_new(); + JsonNode *node = NULL; + JsonGenerator *generator = NULL; + gsize length = 0; + gchar *data = NULL; + std::string uri = "bixby://com.samsung.tv.vif/tvVoiceInteraction.SendNavCommand/punchOut?NavCommand="; + uri += convert(direction); + uri += "&NavUnit=Focus&RepeatCnt="; + uri += repeat; + + json_builder_begin_object(builder); + json_builder_set_member_name(builder, "type"); + json_builder_add_int_value(builder, 23); + + json_builder_set_member_name(builder, "viv"); + json_builder_begin_object(builder); + json_builder_set_member_name(builder, "AppLaunch"); + json_builder_begin_object(builder); + + json_builder_set_member_name(builder, "uri"); + json_builder_add_string_value(builder, uri.c_str()); + + json_builder_set_member_name(builder, "text"); + json_builder_add_string_value(builder, "{}"); + + json_builder_end_object(builder); + json_builder_end_object(builder); + json_builder_end_object(builder); + + node = json_builder_get_root(builder); + g_object_unref(builder); + + generator = json_generator_new(); + json_generator_set_root(generator, node); + + // convert json data into string + data = json_generator_to_data(generator, &length); + + json_node_free(node); + g_object_unref(generator); + return data; +} +#endif + +static std::string to_string(mmi_data_h data) +{ + mmi_data_type_e type; + mmi_data_get_type(data, &type); + if (type == MMI_DATA_TYPE_TEXT) { + const char *value = nullptr; + mmi_data_get_text(data, &value); + return std::string(value ? value : "NULL"); + } else if (type == MMI_DATA_TYPE_FLOAT) { + float value; + mmi_data_get_float(data, &value); + return std::to_string(value); + } else if (type == MMI_DATA_TYPE_BOOLEAN) { + bool value; + mmi_data_get_bool(data, &value); + return std::string(value ? "TRUE" : "FALSE"); + } else if (type == MMI_DATA_TYPE_INTEGER) { + int value; + mmi_data_get_int(data, &value); + return std::to_string(value); + } + return std::string("Unknown"); +} + class Program { public: @@ -28,12 +221,19 @@ public: std::cout << "Creating instance of type " << type << std::endl; mmi_standard_workflow_instance_create( static_cast(type), &m_instance); - mmi_workflow_instance_set_output_callback(m_instance, "COMMAND", + mmi_workflow_instance_set_output_cb(m_instance, "COMMAND", [](mmi_workflow_instance_h instance, const char *name, mmi_data_h data, void *user_data) { - std::cout << "OUTPUT data received : " << std::string(name ? name : "") << std::endl; + mmi_data_type_e type; + mmi_data_get_type(data, &type); + std::cout << + "OUTPUT data received : " << + "[Name:" << std::string(name ? name : "") << "]" << + "[Type:" << std::string(magic_enum::enum_name(type)) << "]" << + "[Value:" << to_string(data) << "]" << + std::endl; }, nullptr); - mmi_workflow_instance_set_output_callback(m_instance, "UTTERANCE", + mmi_workflow_instance_set_output_cb(m_instance, "UTTERANCE", [](mmi_workflow_instance_h instance, const char *name, mmi_data_h data, void *user_data) { const char *value = nullptr; mmi_data_get_text(data, &value); @@ -69,7 +269,7 @@ MATCH.COMMAND as MATCHED_CANDIDATE mmi_workflow_h workflow; mmi_workflow_create_from_script(script.c_str(), &workflow); mmi_custom_workflow_instance_create(workflow, &m_instance); - mmi_workflow_instance_set_output_callback(m_instance, "COMMAND", + mmi_workflow_instance_set_output_cb(m_instance, "COMMAND", [](mmi_workflow_instance_h instance, const char *name, mmi_data_h data, void *user_data) { std::cout << "OUTPUT data received : " << std::string(name ? name : "") << std::endl; }, @@ -82,12 +282,21 @@ MATCH.COMMAND as MATCHED_CANDIDATE } std::cout << "Creating instance of script with path : " << path << std::endl; - //mmi_custom_workflow_instance_create_from_script_file(path.c_str(), &m_instance); - mmi_workflow_instance_set_output_callback(m_instance, "COMMAND", - [](mmi_workflow_instance_h instance, const char *name, mmi_data_h data, void *user_data) { - std::cout << "OUTPUT data received : " << std::string(name ? name : "") << std::endl; - }, - nullptr); + std::ifstream script_file(path); + if (!script_file.is_open()) { + std::cout << "Could not open file : " << path << std::endl; + return; + } + + std::string script; + std::string line; + while(std::getline(script_file, line)) { + script += line; + script += '\n'; + } + mmi_workflow_h workflow; + mmi_workflow_create_from_script(script.c_str(), &workflow); + mmi_custom_workflow_instance_create(workflow, &m_instance); } void destroy_instance() { if (!m_instance) { @@ -169,7 +378,7 @@ MATCH.COMMAND as MATCHED_CANDIDATE mmi_attribute_destroy(attribute); } } - void emit_signal() { + void emit_signal(std::string signal_name) { if (!m_instance) { std::cout << "No instance to set attribute" << std::endl; return; @@ -177,26 +386,10 @@ MATCH.COMMAND as MATCHED_CANDIDATE std::cout << "Emitting signal " << std::endl; - mmi_primitive_value_h signal_parameter_value_1 = nullptr; - mmi_signal_parameter_h signal_parameter_1 = nullptr; - mmi_primitive_value_h signal_parameter_value_2 = nullptr; - mmi_signal_parameter_h signal_parameter_2 = nullptr; mmi_signal_h signal = nullptr; - mmi_primitive_value_create_int(6, &signal_parameter_value_1); - mmi_signal_parameter_create(signal_parameter_value_1, - "signal_parameter_1", &signal_parameter_1); - mmi_primitive_value_create_int(3, &signal_parameter_value_2); - mmi_signal_parameter_create(signal_parameter_value_2, - "signal_parameter_2", &signal_parameter_2); - mmi_signal_create("CONTROL", &signal); - mmi_signal_add_parameter(signal, signal_parameter_1); - mmi_signal_add_parameter(signal, signal_parameter_2); + mmi_signal_create(signal_name.c_str(), &signal); mmi_workflow_instance_emit_signal(m_instance, signal); mmi_signal_destroy(signal); - mmi_signal_parameter_destroy(signal_parameter_1); - mmi_primitive_value_destroy(signal_parameter_value_1); - mmi_signal_parameter_destroy(signal_parameter_2); - mmi_primitive_value_destroy(signal_parameter_value_2); } void feed_data(std::string node_name, std::string port_name, std::string type, std::string value) { if (!m_instance) { @@ -216,7 +409,76 @@ MATCH.COMMAND as MATCHED_CANDIDATE mmi_data_destroy(data); } + void feed_data(std::string node_name, std::string port_name, std::string type, std::string value1, std::string value2) { + if (!m_instance) { + std::cout << "No instance to feed data" << std::endl; + return; + } + + std::cout << "Feeding data " << std::endl; + + mmi_data_h data = nullptr; + if (type.compare("coord") == 0) { + mmi_data_create_coordinate(std::stoi(value1), std::stoi(value2), &data); + } + mmi_workflow_instance_feed_data(m_instance, node_name.c_str(), port_name.c_str(), data); + mmi_data_destroy(data); + } + +#ifdef USE_VOICE_TOUCH_TV + void title_selection(std::string value) { + if (!m_instance) { + std::cout << "No instance to select title" << std::endl; + return; + } + + std::cout << "Title Selection" << std::endl; + + std::string encoded = base64::encode(value); + + char *json = get_title_viv_response(encoded); + std::cout << "json :" << json << std::endl; + + mmi_data_h data = nullptr; + mmi_data_create_text(json, &data); + + mmi_workflow_instance_feed_data(m_instance, "PARSER", "COMMAND", data); + mmi_data_destroy(data); + free(json); + } + + void ordinal_selection(int value) { + if (!m_instance) { + std::cout << "No instance to select ordinal" << std::endl; + return; + } + mmi_data_h data = nullptr; + char *json = get_ordinal_viv_response(std::to_string(value).c_str()); + std::cout << "json :" << json << std::endl; + mmi_data_create_text(json, &data); + + mmi_workflow_instance_feed_data(m_instance, "PARSER", "COMMAND", data); + mmi_data_destroy(data); + free(json); + } + + void navigation(std::string direction, int repeat) { + if (!m_instance) { + std::cout << "No instance to run navigation" << std::endl; + return; + } + + mmi_data_h data = nullptr; + char *json = get_navigation_viv_response(direction, std::to_string(repeat).c_str()); + std::cout << "json :" << json << std::endl; + mmi_data_create_text(json, &data); + + mmi_workflow_instance_feed_data(m_instance, "PARSER", "COMMAND", data); + mmi_data_destroy(data); + free(json); + } +#endif static int state_changed_cb(mmi_state_e state, void *user_data) { Program *program = static_cast(user_data); program->m_state = state; @@ -230,8 +492,75 @@ private: static Program g_program; -int main(void) +void process_file(std::string filename) { + std::ifstream file(filename); + if (!file.is_open()) { + std::cout << "Failed to open file: " << filename << std::endl; + return; + } + + std::vector lines; + std::string line; + while (std::getline(file, line)) { + std::string token; + std::istringstream stream(line); + + std::cout << "Processing line : " << line << std::endl; + + if (std::getline(stream, token, ' ')) { + std::string command = token; + std::vector parameters; + while (std::getline(stream, token, ' ')) { + parameters.push_back(token); + } + try { + if (command.compare("sleep") == 0) { + sleep(std::stoi(parameters.at(0))); + } else if (command.compare("create") == 0) { + g_program.create_instance(std::stoi(parameters.at(0))); + } else if (command.compare("create_from_script") == 0) { + g_program.create_instance_from_script(); + } else if (command.compare("create_from_file") == 0) { + g_program.create_instance_from_file(parameters.at(0)); + } else if (command.compare("destroy") == 0) { + g_program.destroy_instance(); + } else if (command.compare("set_attribute") == 0) { + g_program.set_attribute( + parameters.at(0), parameters.at(1), parameters.at(2)); + } else if (command.compare("feed_data") == 0) { + if (parameters.size() == 5) { + g_program.feed_data( + parameters.at(0), parameters.at(1), parameters.at(2), parameters.at(3), parameters.at(4)); + } else { + g_program.feed_data( + parameters.at(0), parameters.at(1), parameters.at(2), parameters.at(3)); + } + } else if (command.compare("emit_signal") == 0) { + g_program.emit_signal(parameters.at(0)); + } else if (command.compare("activate") == 0) { + g_program.activate_instance(); + } else if (command.compare("deactivate") == 0) { + g_program.deactivate_instance(); + } + } catch (std::out_of_range &e) { + std::cout << e.what() << std::endl; + } + } + + } +} + +int main(int argc, char *argv[]) +{ + argh::parser cmdl(argv); + + std::string filename; + if (cmdl("file") >> filename) { + process_file(filename); + return 0; + } + try { cli::SetColor(); @@ -275,8 +604,13 @@ int main(void) }, "Set attributes for the current workflow instance"); - rootMenu->Insert("emit_signal", [](std::ostream& out) { - g_program.emit_signal(); + rootMenu->Insert("feed_data", [](std::ostream& out, std::string node_name, std::string port_name, std::string type, std::string value1, std::string value2) { + g_program.feed_data(node_name, port_name, type, value1, value2); + }, + "Set attributes for the current workflow instance"); + + rootMenu->Insert("emit_signal", [](std::ostream& out, std::string signal_name) { + g_program.emit_signal(signal_name); }, "Set attributes for the current workflow instance"); @@ -290,6 +624,22 @@ int main(void) }, "Deactivates the current workflow instance"); +#ifdef USE_VOICE_TOUCH_TV + rootMenu->Insert("title_selection", [](std::ostream& out, std::string value) { + g_program.title_selection(value); + }, + "Find and execute the selected title on the screen"); + + rootMenu->Insert("ordinal_selection", [](std::ostream& out, int value) { + g_program.ordinal_selection(value); + }, + "Select an item with the input value at the focused point on the screen"); + + rootMenu->Insert("navigation", [](std::ostream& out, std::string direction, int repeat) { + g_program.navigation(direction, repeat); + }, + "Move in the input direction as many times as specified"); +#endif cli::Cli cli(std::move(rootMenu)); cli::CliEcoreSession session(cli); diff --git a/src/mmi-manager/meson.build b/src/mmi-manager/meson.build index 30310c2..8a2ae8c 100644 --- a/src/mmi-manager/meson.build +++ b/src/mmi-manager/meson.build @@ -45,6 +45,9 @@ mmi_manager_include_dirs = include_directories( '.', '../common/', '../../capi/', + '../../capi/common', + '../../capi/workflow', + '../../capi/node', '../../external/', mmi_extra_include_dir, ) diff --git a/src/mmi-manager/mmi-common.h b/src/mmi-manager/mmi-common.h deleted file mode 100644 index 08cb1d7..0000000 --- a/src/mmi-manager/mmi-common.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* Copyright © 2021 Samsung Electronics co., Ltd. All Rights Reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a -* copy of this software and associated documentation files (the "Software"), -* to deal in the Software without restriction, including without limitation -* the rights to use, copy, modify, merge, publish, distribute, sublicense, -* and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice (including the next -* paragraph) shall be included in all copies or substantial portions of the -* Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -* DEALINGS IN THE SOFTWARE. -*/ - -#ifndef __MMI_COMMON_H__ -#define __MMI_COMMON_H__ - -#include -#include "mmi-platform-config.h" - -#ifndef MMI_API -#define MMI_API __attribute__ ((visibility("default"))) -#endif - -#endif //__MMI_COMMON_H__ diff --git a/src/mmi-manager/mmi-node-instance.cpp b/src/mmi-manager/mmi-node-instance.cpp index 73ae100..3e68136 100644 --- a/src/mmi-manager/mmi-node-instance.cpp +++ b/src/mmi-manager/mmi-node-instance.cpp @@ -157,7 +157,7 @@ bool NodeInstance::initialize() { size_t name_length = 0; mmi_port_get_name(port, &name, &name_length); - mmi_port_callbacks callbacks; + mmi_port_callbacks_s callbacks; mmi_port_get_callbacks(port, &callbacks); if (strncmp(name, port_info.name.c_str(), name_length) == 0) { @@ -184,7 +184,7 @@ bool NodeInstance::initialize() { m_plugin_module_proxy->add_node_instance_info(&plugin_module_node_instance_info); if (m_callbacks.initialized_cb != nullptr) { - m_callbacks.initialized_cb(static_cast(this)); + m_callbacks.initialized_cb(static_cast(this), nullptr); } // LCOV_EXCL_STOP @@ -193,7 +193,7 @@ bool NodeInstance::initialize() { bool NodeInstance::deinitialize() { if (m_callbacks.deinitialized_cb != nullptr) { - m_callbacks.deinitialized_cb(static_cast(this)); + m_callbacks.deinitialized_cb(static_cast(this), nullptr); } if (m_plugin_module_proxy) { @@ -244,7 +244,7 @@ bool NodeInstance::activate() { _E("Activate callback is not set"); return false; } - m_callbacks.activated_cb(static_cast(this)); + m_callbacks.activated_cb(static_cast(this), nullptr); return true; } @@ -257,7 +257,7 @@ bool NodeInstance::deactivate() { _E("Deactivate callback is not set"); return false; } - m_callbacks.deactivated_cb(static_cast(this)); + m_callbacks.deactivated_cb(static_cast(this), nullptr); return true; } @@ -265,7 +265,7 @@ bool NodeInstance::suspend() { m_suspended = true; if (m_activated) { if (m_callbacks.deactivated_cb != nullptr) { - m_callbacks.deactivated_cb(static_cast(this)); + m_callbacks.deactivated_cb(static_cast(this), nullptr); } } return true; @@ -275,7 +275,7 @@ bool NodeInstance::resume() { m_suspended = false; if (m_activated) { if (m_callbacks.activated_cb != nullptr) { - m_callbacks.activated_cb(static_cast(this)); + m_callbacks.activated_cb(static_cast(this), nullptr); } } return true; @@ -307,7 +307,7 @@ bool NodeInstance::set_attribute(mmi_attribute_h attribute) _E("Set attribute callback is not set"); return false; } - m_callbacks.attribute_set_cb(static_cast(this), attribute); + m_callbacks.attribute_set_cb(static_cast(this), attribute, nullptr); return true; } // LCOV_EXCL_STOP @@ -323,7 +323,7 @@ bool NodeInstance::handle_signal(mmi_signal_h signal) _E("Set signal callback is not set"); return false; } - m_callbacks.signal_received_cb(static_cast(this), signal); + m_callbacks.signal_received_cb(static_cast(this), signal, nullptr); return true; } diff --git a/src/mmi-manager/mmi-node-instance.h b/src/mmi-manager/mmi-node-instance.h index 6e4ee01..31be821 100644 --- a/src/mmi-manager/mmi-node-instance.h +++ b/src/mmi-manager/mmi-node-instance.h @@ -80,7 +80,7 @@ protected: mmi_node_type_e m_node_type; mmi_node_sub_type_e m_node_sub_type; - mmi_node_callbacks m_callbacks{{nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}}; + mmi_node_callbacks_s m_callbacks{{nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}, {nullptr}}; bool m_suspended{false}; bool m_activated{false}; diff --git a/src/mmi-manager/mmi-node-prototype.h b/src/mmi-manager/mmi-node-prototype.h index 2a001ef..2739f63 100644 --- a/src/mmi-manager/mmi-node-prototype.h +++ b/src/mmi-manager/mmi-node-prototype.h @@ -26,12 +26,7 @@ #include "mmi-common.h" #include "mmi-node.h" -#include "mmi-node-source.h" -#include "mmi-node-processor.h" -#include "mmi-node-logic.h" -#include "mmi-node-controller.h" -#include "mmi-node-action.h" -#include "mmi-node-custom.h" +#include "mmi-node-types.h" #include "mmi-plugin-module-proxy.h" #include "mmi-manager-log.h" diff --git a/src/mmi-manager/mmi-plugin-module-proxy.cpp b/src/mmi-manager/mmi-plugin-module-proxy.cpp index 05c65aa..a73396a 100644 --- a/src/mmi-manager/mmi-plugin-module-proxy.cpp +++ b/src/mmi-manager/mmi-plugin-module-proxy.cpp @@ -22,10 +22,12 @@ */ #include "mmi-plugin-module-proxy.h" -#include "mmi-manager-log.h" #include +#include "mmi-manager-log.h" +#include "mmi-workflow-internal.h" + namespace mmi { // LCOV_EXCL_START @@ -111,7 +113,7 @@ mmi_plugin_module_node_list_s PluginModuleProxySharedLibrary::load_node_prototyp mmi_node_h node = node_list.nodes[i]; mmi_node_type_e type; mmi_node_get_type(node, &type); - mmi_node_callbacks callbacks; + mmi_node_callbacks_s callbacks; mmi_node_get_callbacks(node, &callbacks); size_t port_count; _D("node_info[%zu].type: %d", i, type); @@ -134,7 +136,7 @@ mmi_plugin_module_node_list_s PluginModuleProxySharedLibrary::load_node_prototyp mmi_port_get_type(port, &port_type); mmi_data_type_e data_type; mmi_port_get_data_type(port, &data_type); - mmi_port_callbacks port_callbacks; + mmi_port_callbacks_s port_callbacks; mmi_port_get_callbacks(port, &port_callbacks); _D("node_info[%zu].port_info[%zu].name: %s", i, j, name); _D("node_info[%zu].port_info[%zu].type: %d", i, j, port_type); diff --git a/src/mmi-manager/mmi-port-instance.cpp b/src/mmi-manager/mmi-port-instance.cpp index 44c771c..b6c423d 100644 --- a/src/mmi-manager/mmi-port-instance.cpp +++ b/src/mmi-manager/mmi-port-instance.cpp @@ -34,7 +34,7 @@ PortInstance::PortInstance() { PortInstance::~PortInstance() { } -void PortInstance::set_port_callbacks(mmi_port_callbacks callbacks) { +void PortInstance::set_port_callbacks(mmi_port_callbacks_s callbacks) { _D("PortInstance[%p] set_port_callbacks : %p %p", this, callbacks.output_format_requested_cb, callbacks.input_data_received_cb); m_callbacks = callbacks; @@ -61,7 +61,7 @@ void PortInstance::on_output_data_generated(mmi_data_h data) { void PortInstance::on_output_data_received(mmi_data_h data) { if (m_callbacks.input_data_received_cb) { - m_callbacks.input_data_received_cb(static_cast(this), data); + m_callbacks.input_data_received_cb(static_cast(this), data, nullptr); } } diff --git a/src/mmi-manager/mmi-port-instance.h b/src/mmi-manager/mmi-port-instance.h index f270b08..7a27a44 100644 --- a/src/mmi-manager/mmi-port-instance.h +++ b/src/mmi-manager/mmi-port-instance.h @@ -39,7 +39,7 @@ public: PortInstance(); virtual ~PortInstance(); - void set_port_callbacks(mmi_port_callbacks callbacks); + void set_port_callbacks(mmi_port_callbacks_s callbacks); void add_linked_port_instance(std::shared_ptr port_instance); void add_data_gateway(std::shared_ptr gateway); @@ -51,7 +51,7 @@ public: void on_output_data_received(mmi_data_h data); private: std::string m_name; - mmi_port_callbacks m_callbacks{{nullptr}, {nullptr}}; + mmi_port_callbacks_s m_callbacks{{nullptr}, {nullptr}}; std::vector> m_linked_port_instances; std::vector> m_data_gateways; diff --git a/src/mmi-manager/mmi-self-container.cpp b/src/mmi-manager/mmi-self-container.cpp index 14afa30..02359f5 100644 --- a/src/mmi-manager/mmi-self-container.cpp +++ b/src/mmi-manager/mmi-self-container.cpp @@ -46,52 +46,52 @@ TestNodePluginModule::TestNodePluginModule() { TestNodePluginModule::~TestNodePluginModule() { } -int TestNodePluginModule::node_initialized_cb(mmi_node_instance_h instance) { +int TestNodePluginModule::node_initialized_cb(mmi_node_instance_h instance, void *user_data) { _D("Node initialize callback is called for %p", instance); return MMI_ERROR_NONE; } -int TestNodePluginModule::node_deinitialized_cb(mmi_node_instance_h instance) { +int TestNodePluginModule::node_deinitialized_cb(mmi_node_instance_h instance, void *user_data) { _D("Node deinitialize callback is called for %p", instance); return MMI_ERROR_NONE; } -int TestNodePluginModule::node_attribute_set_cb(mmi_node_instance_h instance, mmi_attribute_h attribute) { +int TestNodePluginModule::node_attribute_set_cb(mmi_node_instance_h instance, mmi_attribute_h attribute, void *user_data) { _D("Node attribute set callback is called for %p", instance); return MMI_ERROR_NONE; } -int TestNodePluginModule::node_activated_cb(mmi_node_instance_h instance) { +int TestNodePluginModule::node_activated_cb(mmi_node_instance_h instance, void *user_data) { _D("Node activate callback is called for %p", instance); return MMI_ERROR_NONE; } -int TestNodePluginModule::node_deactivated_cb(mmi_node_instance_h instance) { +int TestNodePluginModule::node_deactivated_cb(mmi_node_instance_h instance, void *user_data) { _D("Node deactivate callback is called for %p", instance); return MMI_ERROR_NONE; } -int TestNodePluginModule::node_signal_received_cb(mmi_node_instance_h instance, mmi_signal_h signal) { +int TestNodePluginModule::node_signal_received_cb(mmi_node_instance_h instance, mmi_signal_h signal, void *user_data) { _D("Node signal received callback is called for %p", instance); return MMI_ERROR_NONE; } -int TestNodePluginModule::port_output_format_requested_cb(mmi_port_instance_h instance, const char *format) { +int TestNodePluginModule::port_output_format_requested_cb(mmi_port_instance_h instance, const char **format, void *user_data) { _D("Port output format request callback is called for %p", instance); return MMI_ERROR_NONE; } -int TestNodePluginModule::port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data) { +int TestNodePluginModule::port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data) { _D("Port input data callback is called for %p", instance); return MMI_ERROR_NONE; } -TestNodePluginModuleMIC::TestNodePluginModuleMIC() { +TestNodePluginModuleScreenAnalyzer::TestNodePluginModuleScreenAnalyzer() { m_node_callbacks = default_node_callbacks; m_node_callbacks.activated_cb = node_activated_cb; - m_audio_port_callbacks = default_port_callbacks; + m_screen_info_port_callbacks = default_port_callbacks; } -int TestNodePluginModuleMIC::node_activated_cb(mmi_node_instance_h instance) { +int TestNodePluginModuleScreenAnalyzer::node_activated_cb(mmi_node_instance_h instance, void *user_data) { _D("[MIC] Node activate callback is called for %p", instance); /* In shared object plugin module, the output data can be generated using the API @@ -100,14 +100,14 @@ int TestNodePluginModuleMIC::node_activated_cb(mmi_node_instance_h instance) { mmi library API is not allowed. So, we have to find the output port using the port instance map. */ - std::string output_port_name{"AUDIO"}; + std::string output_port_name{"SCREEN_INFO"}; mmi_port_instance_h output_port = nullptr; for (const auto &elem : g_node_instance_info_map) { const mmi_plugin_module_node_instance_info_s &node_instance_info = elem.second; if (node_instance_info.node == instance) { for (size_t i = 0; i < node_instance_info.port_info_count; ++i) { if (output_port_name.compare(std::string(node_instance_info.port_infos[i].name)) == 0) { - _D("[MIC] Found output port %p", node_instance_info.port_infos[i].port); + _D("[SCREEN_INFO] Found output port %p", node_instance_info.port_infos[i].port); output_port = node_instance_info.port_infos[i].port; break; } @@ -120,25 +120,26 @@ int TestNodePluginModuleMIC::node_activated_cb(mmi_node_instance_h instance) { PortInstance *port_instance = reinterpret_cast(output_port); if (port_instance) { - _D("[MIC] Generating an output %d to %p", value, port_instance); + _D("[SCREEN_INFO] Generating an output %d to %p", value, port_instance); port_instance->on_output_data_generated(output_data); } return MMI_ERROR_NONE; } -TestNodePluginModuleASR::TestNodePluginModuleASR() { +TestNodePluginModuleMatch::TestNodePluginModuleMatch() { m_node_callbacks = default_node_callbacks; - m_audio_port_callbacks = default_port_callbacks; - m_audio_port_callbacks.input_data_received_cb = audio_port_input_data_received_cb; + m_text_port_callbacks = default_port_callbacks; + m_text_port_callbacks.input_data_received_cb = text_port_input_data_received_cb; } -int TestNodePluginModuleASR::audio_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data) { +int TestNodePluginModuleMatch::text_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data) { /* In shared object plugin module, the output port can be found using the API mmi_node_instance_sibling_port_find() function. However, in this test plugin module, calling mmi library API is not allowed. So, we have to find the output port using the node instance info map. */ - std::string output_port_name{"FINAL_RESULT"}; + + std::string output_port_name{"MATCHED_CANDIDATE"}; mmi_port_instance_h output_port = nullptr; const mmi_plugin_module_node_instance_info_s &node_instance_info = g_node_instance_info_map[instance]; for (size_t i = 0; i < node_instance_info.port_info_count; ++i) { @@ -152,7 +153,7 @@ int TestNodePluginModuleASR::audio_port_input_data_received_cb(mmi_port_instance int *ptr = reinterpret_cast(data); if (ptr) value = *ptr; - _D("[ASR] Audio input data callback is called: %p %d", instance, value); + _D("[Match] Text input data callback is called: %p %d", instance, value); value++; ptr = &value; @@ -166,60 +167,29 @@ int TestNodePluginModuleASR::audio_port_input_data_received_cb(mmi_port_instance PortInstance *port_instance = reinterpret_cast(output_port); if (port_instance) { - _D("[ASR] Generating an output %d to %p", value, port_instance); + _D("[Match] Generating an output %d to %p", value, port_instance); port_instance->on_output_data_generated(output_data); } return MMI_ERROR_NONE; } -int TestNodePluginModuleMatch::text_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data) { - /* In shared object plugin module, the output port can be found using the API - mmi_node_instance_sibling_port_find() function. However, in this test - plugin module, calling mmi library API is not allowed. So, we have to find the - output port using the node instance info map. */ - - std::string output_port_name{"MATCHED_CANDIDATE"}; - mmi_port_instance_h output_port = nullptr; - const mmi_plugin_module_node_instance_info_s &node_instance_info = g_node_instance_info_map[instance]; - for (size_t i = 0; i < node_instance_info.port_info_count; ++i) { - if (output_port_name.compare(std::string(node_instance_info.port_infos[i].name)) == 0) { - output_port = node_instance_info.port_infos[i].port; - break; - } - } +TestNodePluginModuleKeyEvent::TestNodePluginModuleKeyEvent() { + m_node_callbacks = default_node_callbacks; + m_key_event_port_callbacks = default_port_callbacks; + m_key_event_port_callbacks.input_data_received_cb = key_event_port_input_data_received_cb; +} +int TestNodePluginModuleKeyEvent::key_event_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data) { int value = -1; int *ptr = reinterpret_cast(data); if (ptr) value = *ptr; - _D("[Match] Text input data callback is called: %p %d", instance, value); - - value++; - ptr = &value; - - mmi_data_h output_data = reinterpret_cast(ptr); - - /* In shared object plugin module, the output data can be generated using the API - mmi_port_instance_output_generate() function. However, in this test plugin module, - calling mmi library API is not allowed. So, we have to generate the output - using the port instance handle directly. */ - - PortInstance *port_instance = reinterpret_cast(output_port); - if (port_instance) { - _D("[Match] Generating an output %d to %p", value, port_instance); - port_instance->on_output_data_generated(output_data); - } + _D("[KEY_EVENT] key event input data callback is called: %p %d", instance, value); return MMI_ERROR_NONE; } -TestNodePluginModuleMatch::TestNodePluginModuleMatch() { - m_node_callbacks = default_node_callbacks; - m_text_port_callbacks = default_port_callbacks; - m_text_port_callbacks.input_data_received_cb = text_port_input_data_received_cb; -} - PluginModuleProxySelfContainerTest::PluginModuleProxySelfContainerTest() { } @@ -235,75 +205,59 @@ mmi_plugin_module_node_list_s PluginModuleProxySelfContainerTest::load_node_prot /* Self-contained port information */ - mmi_port_h mic_audio_port = nullptr; - mmi_port_create(&mic_audio_port); - mmi_port_set_name(mic_audio_port, "AUDIO"); - mmi_port_set_type(mic_audio_port, MMI_PORT_TYPE_OUT); - mmi_port_set_data_type(mic_audio_port, MMI_DATA_TYPE_AUDIO); - mmi_port_set_callbacks(mic_audio_port, m_node_mic.m_audio_port_callbacks); - - mmi_node_h mic_node = nullptr; - mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &mic_node); - mmi_node_add_port(mic_node, mic_audio_port); - mmi_node_set_callbacks(mic_node, m_node_mic.m_node_callbacks); - mmi_node_register(mic_node); - - mmi_node_destroy(mic_node); - - mmi_port_h asr_audio_port = nullptr; - mmi_port_create(&asr_audio_port); - mmi_port_set_name(asr_audio_port, "AUDIO"); - mmi_port_set_type(asr_audio_port, MMI_PORT_TYPE_IN); - mmi_port_set_data_type(asr_audio_port, MMI_DATA_TYPE_AUDIO); - mmi_port_set_callbacks(asr_audio_port, m_node_asr.m_audio_port_callbacks); - - mmi_port_h asr_partial_result_port = nullptr; - mmi_port_create(&asr_partial_result_port); - mmi_port_set_name(asr_partial_result_port, "PARTIAL_RESULT"); - mmi_port_set_type(asr_partial_result_port, MMI_PORT_TYPE_OUT); - mmi_port_set_data_type(asr_partial_result_port, MMI_DATA_TYPE_TEXT); - mmi_port_set_callbacks(asr_partial_result_port, m_node_asr.m_audio_port_callbacks); - - mmi_port_h asr_final_result_port = nullptr; - mmi_port_create(&asr_final_result_port); - mmi_port_set_name(asr_final_result_port, "FINAL_RESULT"); - mmi_port_set_type(asr_final_result_port, MMI_PORT_TYPE_OUT); - mmi_port_set_data_type(asr_final_result_port, MMI_DATA_TYPE_TEXT); - mmi_port_set_callbacks(asr_final_result_port, m_node_asr.m_audio_port_callbacks); - - mmi_node_h asr_node = nullptr; - mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &asr_node); - mmi_node_add_port(asr_node, asr_audio_port); - mmi_node_add_port(asr_node, asr_partial_result_port); - mmi_node_add_port(asr_node, asr_final_result_port); - mmi_node_set_callbacks(asr_node, m_node_asr.m_node_callbacks); - mmi_node_register(asr_node); - - mmi_node_destroy(asr_node); + mmi_port_h screen_info_port = nullptr; + mmi_port_create(&screen_info_port); + mmi_port_set_name(screen_info_port, "SCREEN_INFO"); + mmi_port_set_type(screen_info_port, MMI_PORT_TYPE_OUT); + mmi_port_set_data_type(screen_info_port, MMI_DATA_TYPE_TEXT); + mmi_port_set_callbacks(screen_info_port, m_node_screen_analyzer.m_screen_info_port_callbacks, nullptr); + + mmi_node_h screen_anlayzer_node = nullptr; + mmi_node_create_source(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER, &screen_anlayzer_node); + mmi_node_add_port(screen_anlayzer_node, screen_info_port); + mmi_node_set_callbacks(screen_anlayzer_node, m_node_screen_analyzer.m_node_callbacks, nullptr); + mmi_node_register(screen_anlayzer_node); + + mmi_node_destroy(screen_anlayzer_node); mmi_port_h match_text_port = nullptr; mmi_port_create(&match_text_port); mmi_port_set_name(match_text_port, "TEXT"); mmi_port_set_type(match_text_port, MMI_PORT_TYPE_IN); mmi_port_set_data_type(match_text_port, MMI_DATA_TYPE_TEXT); - mmi_port_set_callbacks(match_text_port, m_node_match.m_text_port_callbacks); + mmi_port_set_callbacks(match_text_port, m_node_match.m_text_port_callbacks, nullptr); mmi_port_h match_candidate_port = nullptr; mmi_port_create(&match_candidate_port); mmi_port_set_name(match_candidate_port, "MATCHED_CANDIDATE"); mmi_port_set_type(match_candidate_port, MMI_PORT_TYPE_OUT); mmi_port_set_data_type(match_candidate_port, MMI_DATA_TYPE_TEXT); - mmi_port_set_callbacks(match_candidate_port, m_node_match.m_text_port_callbacks); + mmi_port_set_callbacks(match_candidate_port, m_node_match.m_text_port_callbacks, nullptr); mmi_node_h match_node = nullptr; mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &match_node); mmi_node_add_port(match_node, match_text_port); mmi_node_add_port(match_node, match_candidate_port); - mmi_node_set_callbacks(match_node, m_node_match.m_node_callbacks); + mmi_node_set_callbacks(match_node, m_node_match.m_node_callbacks, nullptr); mmi_node_register(match_node); mmi_node_destroy(match_node); + mmi_port_h key_event_port = nullptr; + mmi_port_create(&key_event_port); + mmi_port_set_name(key_event_port, "KEY_EVENT"); + mmi_port_set_type(key_event_port, MMI_PORT_TYPE_IN); + mmi_port_set_data_type(key_event_port, MMI_DATA_TYPE_TEXT); + mmi_port_set_callbacks(key_event_port, m_node_key_event.m_key_event_port_callbacks, nullptr); + + mmi_node_h key_event_node = nullptr; + mmi_node_create_action(MMI_NODE_ACTION_TYPE_KEY_EVENT, &key_event_node); + mmi_node_add_port(key_event_node, key_event_port); + mmi_node_set_callbacks(key_event_node, m_node_key_event.m_node_callbacks, nullptr); + mmi_node_register(key_event_node); + + mmi_node_destroy(key_event_node); + const char *identifier = mmi_plugin_storage_get_current_module_identifier(); mmi_plugin_module_node_list_s list = mmi_plugin_storage_get_node_list(identifier); @@ -316,30 +270,30 @@ mmi_plugin_module_workflow_list_s PluginModuleProxySelfContainerTest::load_workf mmi_workflow_h workflow = nullptr; mmi_workflow_create(&workflow); - mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); - - mmi_node_h node_mic = nullptr; - mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &node_mic); - mmi_workflow_node_add(workflow, "MIC", node_mic); + mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_VOICE_TOUCH); - mmi_node_h node_asr = nullptr; - mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &node_asr); - mmi_workflow_node_add(workflow, "ASR", node_asr); + mmi_node_h node_screen_analyzer = nullptr; + mmi_node_create_source(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER, &node_screen_analyzer); + mmi_workflow_node_add(workflow, "SCREEN_ANALYZER", node_screen_analyzer); mmi_node_h node_match = nullptr; mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match); mmi_workflow_node_add(workflow, "MATCH", node_match); - mmi_workflow_link_nodes_by_names(workflow, "MIC", "AUDIO", "ASR", "AUDIO"); - mmi_workflow_link_nodes_by_names(workflow, "ASR", "FINAL_RESULT", "MATCH", "TEXT"); + mmi_node_h node_key_event = nullptr; + mmi_node_create_action(MMI_NODE_ACTION_TYPE_KEY_EVENT, &node_key_event); + mmi_workflow_node_add(workflow, "KEY_EVENT", node_key_event); + + mmi_workflow_link_nodes_by_names(workflow, "SCREEN_ANALYZER", "SCREEN_INFO", "MATCH", "TEXT"); + mmi_workflow_link_nodes_by_names(workflow, "MATCH", "MATCHED_CANDIDATE", "KEY_EVENT", "KEY_EVENT"); mmi_workflow_output_assign(workflow, "OUTPUT", "MATCH", "MATCHED_CANDIDATE"); mmi_standard_workflow_register(workflow); + mmi_node_destroy(node_key_event); mmi_node_destroy(node_match); - mmi_node_destroy(node_asr); - mmi_node_destroy(node_mic); + mmi_node_destroy(node_screen_analyzer); mmi_workflow_destroy(workflow); @@ -353,9 +307,11 @@ void PluginModuleProxySelfContainerTest::add_node_instance_info(mmi_plugin_modul for (size_t i = 0; i < node_instance_info->port_info_count; i++) { g_node_instance_info_map[node_instance_info->port_infos[i].port] = *node_instance_info; } + mmi_plugin_storage_add_node_instance_info(node_instance_info); } void PluginModuleProxySelfContainerTest::remove_node_instance_info(mmi_node_instance_h node_instance) { + mmi_plugin_storage_remove_node_instance_info(node_instance); for (auto it = g_node_instance_info_map.begin(); it != g_node_instance_info_map.end();) { if (it->second.node == node_instance) { it = g_node_instance_info_map.erase(it); diff --git a/src/mmi-manager/mmi-self-container.h b/src/mmi-manager/mmi-self-container.h index 6daa1d1..6ebd823 100644 --- a/src/mmi-manager/mmi-self-container.h +++ b/src/mmi-manager/mmi-self-container.h @@ -45,50 +45,50 @@ public: TestNodePluginModule(); virtual ~TestNodePluginModule(); - static int node_initialized_cb(mmi_node_instance_h instance); - static int node_deinitialized_cb(mmi_node_instance_h instance); - static int node_attribute_set_cb(mmi_node_instance_h instance, mmi_attribute_h attribute); - static int node_activated_cb(mmi_node_instance_h instance); - static int node_deactivated_cb(mmi_node_instance_h instance); - static int node_signal_received_cb(mmi_node_instance_h instance, mmi_signal_h signal); - static int port_output_format_requested_cb(mmi_port_instance_h instance, const char *format); - static int port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data); - - mmi_node_callbacks default_node_callbacks; - mmi_port_callbacks default_port_callbacks; + static int node_initialized_cb(mmi_node_instance_h instance, void *user_data); + static int node_deinitialized_cb(mmi_node_instance_h instance, void *user_data); + static int node_attribute_set_cb(mmi_node_instance_h instance, mmi_attribute_h attribute, void *user_data); + static int node_activated_cb(mmi_node_instance_h instance, void *user_data); + static int node_deactivated_cb(mmi_node_instance_h instance, void *user_data); + static int node_signal_received_cb(mmi_node_instance_h instance, mmi_signal_h signal, void *user_data); + static int port_output_format_requested_cb(mmi_port_instance_h instance, const char **format, void *user_data); + static int port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data); + + mmi_node_callbacks_s default_node_callbacks; + mmi_port_callbacks_s default_port_callbacks; }; class TestWorkflowPluginModuleWakeuplessCommand : TestWorkflowPluginModule { }; -class TestNodePluginModuleMIC : public TestNodePluginModule { +class TestNodePluginModuleScreenAnalyzer : public TestNodePluginModule { public: - TestNodePluginModuleMIC(); - static int node_activated_cb(mmi_node_instance_h instance); + TestNodePluginModuleScreenAnalyzer(); + static int node_activated_cb(mmi_node_instance_h instance, void *user_data); - mmi_node_callbacks m_node_callbacks; - mmi_port_callbacks m_audio_port_callbacks; + mmi_node_callbacks_s m_node_callbacks; + mmi_port_callbacks_s m_screen_info_port_callbacks; }; -class TestNodePluginModuleASR : public TestNodePluginModule { +class TestNodePluginModuleMatch : public TestNodePluginModule { public: - TestNodePluginModuleASR(); + TestNodePluginModuleMatch(); - static int audio_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data); + static int text_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data); - mmi_node_callbacks m_node_callbacks; - mmi_port_callbacks m_audio_port_callbacks; + mmi_node_callbacks_s m_node_callbacks; + mmi_port_callbacks_s m_text_port_callbacks; }; -class TestNodePluginModuleMatch : public TestNodePluginModule { +class TestNodePluginModuleKeyEvent : public TestNodePluginModule { public: - TestNodePluginModuleMatch(); + TestNodePluginModuleKeyEvent(); - static int text_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data); + static int key_event_port_input_data_received_cb(mmi_port_instance_h instance, mmi_data_h data, void *user_data); - mmi_node_callbacks m_node_callbacks; - mmi_port_callbacks m_text_port_callbacks; + mmi_node_callbacks_s m_node_callbacks; + mmi_port_callbacks_s m_key_event_port_callbacks; }; class PluginModuleProxySelfContainerTest : public IPluginModuleProxy { @@ -106,9 +106,9 @@ public: private: TestWorkflowPluginModuleWakeuplessCommand m_workflow_wakeupless_command; - TestNodePluginModuleMIC m_node_mic; - TestNodePluginModuleASR m_node_asr; + TestNodePluginModuleScreenAnalyzer m_node_screen_analyzer; TestNodePluginModuleMatch m_node_match; + TestNodePluginModuleKeyEvent m_node_key_event; }; class PluginModuleProxyFactorySelfContainerTest : public IPluginModuleProxyFactory { diff --git a/src/mmi-manager/mmi-workflow-prototype-manager.h b/src/mmi-manager/mmi-workflow-prototype-manager.h index b8ede34..0895d72 100644 --- a/src/mmi-manager/mmi-workflow-prototype-manager.h +++ b/src/mmi-manager/mmi-workflow-prototype-manager.h @@ -25,6 +25,7 @@ #define __MMI_WORKFLOW_PROTOTYPE_MANAGER_H__ #include "mmi-workflow.h" +#include "mmi-workflow-internal.h" #include "mmi-workflow-prototype.h" #include diff --git a/src/mmi/meson.build b/src/mmi/meson.build index aee102e..e44cc8b 100644 --- a/src/mmi/meson.build +++ b/src/mmi/meson.build @@ -4,20 +4,15 @@ mmi_srcs = [ 'mmi-workflow-instance.cpp', 'mmi-workflow-script.cpp', 'mmi-log.h', + 'mmi-defines.h', 'mmi-primitive-value.cpp', 'mmi-data.cpp', 'mmi-attribute.cpp', 'mmi-node.cpp', - 'mmi-node-source.cpp', - 'mmi-node-processor.cpp', - 'mmi-node-logic.cpp', - 'mmi-node-controller.cpp', - 'mmi-node-action.cpp', - 'mmi-node-custom.cpp', + 'mmi-node-types.cpp', 'mmi-port.cpp', 'mmi-signal.cpp', 'mmi-plugin-storage.cpp', - 'mmi-config-parser.cpp', ] foreach platform_specific_client_file : mmi_platform_specific_client_files @@ -48,6 +43,9 @@ mmi_include_dirs = include_directories( '.', '../common', '../../capi', + '../../capi/common', + '../../capi/workflow', + '../../capi/node', '../../external', mmi_extra_include_dir, ) diff --git a/src/mmi/mmi-config-parser.cpp b/src/mmi/mmi-config-parser.cpp deleted file mode 100644 index 38c5ef6..0000000 --- a/src/mmi/mmi-config-parser.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright © 2023 Samsung Electronics co., Ltd. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include "mmi-config-parser.h" -#include "mmi-log.h" - - -#define MMI_TAG_CONFIG_BASE_TAG "mmi-config" -#define MMI_TAG_CONFIG_CONFIDENCE "confidence" - -static Ecore_Fd_Handler* g_config_fd_handler_noti = NULL; -static int g_config_fd_noti; -static int g_config_wd_noti; - -static xmlDocPtr g_config_doc = NULL; -static mmi_config_s* g_config_info = NULL; - - -static int mmi_parser_load_config(void) -{ - xmlDocPtr doc = NULL; - xmlNodePtr cur = NULL; - - /* For Thread safety */ - xmlInitParser(); - - if (0 == access(MMI_DEFAULT_CONFIG, F_OK)) { - doc = xmlParseFile(MMI_DEFAULT_CONFIG); - if (doc == NULL) { - LOGE("[ERROR] Fail to parse file error : %s", MMI_DEFAULT_CONFIG); - xmlCleanupParser(); - return -1; - } - } - - cur = xmlDocGetRootElement(doc); - if (cur == NULL) { - LOGE("[ERROR] Empty document(%p)", doc); - xmlFreeDoc(doc); - doc = NULL; - xmlCleanupParser(); - return -1; - } - - if (xmlStrcmp(cur->name, (const xmlChar *) MMI_TAG_CONFIG_BASE_TAG)) { - LOGE("[ERROR] The wrong type, root node is NOT %s. doc(%p)", MMI_TAG_CONFIG_BASE_TAG, doc); - xmlFreeDoc(doc); - doc = NULL; - xmlCleanupParser(); - return -1; - } - - cur = cur->xmlChildrenNode; - if (cur == NULL) { - LOGE("[ERROR] Empty document(%p)", doc); - xmlFreeDoc(doc); - doc = NULL; - xmlCleanupParser(); - return -1; - } - - mmi_config_s* temp; - temp = (mmi_config_s*)calloc(1, sizeof(mmi_config_s)); - if (NULL == temp) { - LOGE("[ERROR] Out of memory(%p)", doc); - xmlFreeDoc(doc); - doc = NULL; - xmlCleanupParser(); - return -1; - } - - while (cur != NULL) { - if (0 == xmlStrcmp(cur->name, (const xmlChar *)MMI_TAG_CONFIG_CONFIDENCE)) { - xmlChar *key = xmlNodeGetContent(cur); - if (NULL != key) { - temp->confidence = atof((char*)key); - xmlFree(key); - key = NULL; - } else { - LOGD("[ERROR] confidence is NULL"); - } - } - cur = cur->next; - } - - g_config_info = temp; - g_config_doc = doc; - - return 0; -} - -static int mmi_parser_unload_config(void) -{ - if (NULL != g_config_doc) { - LOGD("[DEBUG] Free g_config_doc(%p)", g_config_doc); - xmlFreeDoc(g_config_doc); - g_config_doc = NULL; - } - - if (NULL != g_config_info) { - LOGE("[DEBUG] Free config_info(%p)", g_config_info); - free(g_config_info); - g_config_info = NULL; - } - - xmlCleanupParser(); - return 0; -} - -static Eina_Bool mmi_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler) -{ - LOGD("into mmi_config_mgr_inotify_event_cb"); - - int length; - struct inotify_event event; - memset(&event, '\0', sizeof(struct inotify_event)); - - length = read(g_config_fd_noti, &event, sizeof(struct inotify_event)); - if (0 > length) { - LOGE("[ERROR] Empty Inotify event"); - return ECORE_CALLBACK_DONE; - } - - if (IN_CLOSE_WRITE == event.mask) { - /* check config changed state */ - if (0 != mmi_parser_load_config()) - return ECORE_CALLBACK_PASS_ON; - - } else if (IN_DELETE_SELF == event.mask) { - LOGE("[ERROR] IN_DELETE_SELF event"); - - mmi_parser_unload_config(); - mmi_parser_load_config(); - } else { - LOGE("[ERROR] Undefined event (0x%x)", event.mask); - } - - return ECORE_CALLBACK_PASS_ON; -} - -static int mmi_config_mgr_register_config_event() -{ - /* get file notification handler */ - int fd; - int wd; - - fd = inotify_init(); - if (fd < 0) { - LOGE("[ERROR] Fail get inotify fd"); - return -1; - } - g_config_fd_noti = fd; - - wd = inotify_add_watch(fd, MMI_DEFAULT_CONFIG, IN_CLOSE_WRITE|IN_DELETE_SELF); - g_config_wd_noti = wd; - - g_config_fd_handler_noti = ecore_main_fd_handler_add(fd, ECORE_FD_READ, - (Ecore_Fd_Cb)mmi_config_mgr_inotify_event_cb, NULL, NULL, NULL); - if (NULL == g_config_fd_handler_noti) { - LOGE("[ERROR] Fail to get handler_noti"); - return -1; - } - - /* Set non-blocking mode of file */ - int value; - value = fcntl(fd, F_GETFL, 0); - value |= O_NONBLOCK; - - if (0 > fcntl(fd, F_SETFL, value)) { - LOGE("[WARNING] Fail to set non-block mode"); - } - - return 0; -} - -static int mmi_config_mgr_unregister_config_event() -{ - /* delete inotify variable */ - ecore_main_fd_handler_del(g_config_fd_handler_noti); - inotify_rm_watch(g_config_fd_noti, g_config_wd_noti); - close(g_config_fd_noti); - - return 0; -} - -int mmi_parser_initialize(void) -{ - if (0 != mmi_config_mgr_register_config_event()) { - LOGE("Fail to mmi_config_mgr_register_config_event"); - } - - if (0 != mmi_parser_load_config()) { - LOGE("Fail to mmi_parser_load_config"); - } - return 0; -} - -int mmi_parser_deinitialize(void) -{ - if (0 != mmi_config_mgr_unregister_config_event()) { - LOGE("Fail to mmi_config_mgr_unregister_config_event"); - } - - if (0 != mmi_parser_unload_config()) { - LOGE("Fail to mmi_parser_unload_config"); - } - return 0; -} - -int mmi_parser_get_confidence(float *confidence) -{ - LOGD("[DEBUG] Get confidence"); - - if (g_config_info) { - *confidence = g_config_info->confidence; - } else { - LOGE("[ERROR] g_config_info is NULL"); - return -1; - } - - return 0; -} diff --git a/src/mmi/mmi-data.cpp b/src/mmi/mmi-data.cpp index 1f70892..e31f6dd 100644 --- a/src/mmi/mmi-data.cpp +++ b/src/mmi/mmi-data.cpp @@ -162,14 +162,14 @@ int mmi_data_create_text(const char *value, mmi_data_h *data) { } new_data->type = MMI_DATA_TYPE_TEXT; - new_data->data = reinterpret_cast(strdup(value)); + new_data->datalen = strlen(value) + 1; + new_data->data = reinterpret_cast(malloc(new_data->datalen)); if (nullptr == new_data->data) { _E("[ERROR] Fail to allocate memory for raw data"); free(new_data); return MMI_ERROR_OUT_OF_MEMORY; } - - new_data->datalen = strlen(value); + memcpy(new_data->data, value, new_data->datalen); *data = new_data; @@ -498,8 +498,8 @@ int mmi_data_get_float(mmi_data_h data, float *value) { } // LCOV_EXCL_STOP -int mmi_data_get_text(mmi_data_h data, const char **string) { - if (nullptr == data || nullptr == string) { +int mmi_data_get_text(mmi_data_h data, const char **text) { + if (nullptr == data || nullptr == text) { _E("[ERROR] Some parameters are invalid"); return MMI_ERROR_INVALID_PARAMETER; } @@ -509,7 +509,7 @@ int mmi_data_get_text(mmi_data_h data, const char **string) { return MMI_ERROR_INVALID_PARAMETER; } - *string = reinterpret_cast(data->data); + *text = reinterpret_cast(data->data); return MMI_ERROR_NONE; } @@ -776,34 +776,6 @@ int mmi_data_destroy(mmi_data_h data) { return MMI_ERROR_NONE; } -// LCOV_EXCL_START -int mmi_data_get_node_timestamp(mmi_data_h data, mmi_data_timestamp_h *timestamp) { - if (nullptr == data || nullptr == timestamp) { - return MMI_ERROR_INVALID_PARAMETER; - } - - *timestamp = (mmi_data_timestamp_s*)(data->data); - return MMI_ERROR_NONE; -} - -int mmi_data_get_source_timestamp(mmi_data_h data, mmi_data_timestamp_h *timestamp) { - if (nullptr == data || nullptr == timestamp) { - return MMI_ERROR_INVALID_PARAMETER; - } - - *timestamp = (mmi_data_timestamp_s*)(data->data); - return MMI_ERROR_NONE; -} - -int mmi_data_set_source_timestamp(mmi_data_h data, mmi_data_timestamp_h timestamp) { - if (nullptr == data || nullptr == timestamp) { - return MMI_ERROR_INVALID_PARAMETER; - } - - data->data = timestamp; - return MMI_ERROR_NONE; -} - int mmi_data_to_bytes(mmi_data_h data, unsigned char **bytes, size_t *length) { if (nullptr == data || nullptr == bytes || nullptr == length) { _E("[ERROR] Some parameters are invalid"); diff --git a/src/mmi/mmi-defines.h b/src/mmi/mmi-defines.h new file mode 100644 index 0000000..e8d26ad --- /dev/null +++ b/src/mmi/mmi-defines.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 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. + * + */ + + +#ifndef __TIZEN_UIX_MMI_DEFINES_H__ +#define __TIZEN_UIX_MMI_DEFINES_H__ + + +/** +* @file mmi-defines.h +*/ + + +/** +* @addtogroup CAPI_UIX_MMI_MODULE +* @{ +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define MMI_NAME_MAX_LENGTH 32 +#define MMI_PARAMETER_MAX_COUNT 32 +#define MMI_PORT_MAX_COUNT 32 +#define MMI_NODE_MAX_COUNT 128 +#define MMI_LINK_MAX_COUNT 128 +#define MMI_OUTPUT_MAX_COUNT 32 +#define MMI_WORKFLOW_MAX_COUNT 64 + + +#ifdef __cplusplus +} +#endif + + +/** + * @} + */ + + +#endif /* __TIZEN_UIX_MMI_DEFINES_H__ */ diff --git a/src/mmi/mmi-ipc-tidl.cpp b/src/mmi/mmi-ipc-tidl.cpp index c284226..de0610b 100644 --- a/src/mmi/mmi-ipc-tidl.cpp +++ b/src/mmi/mmi-ipc-tidl.cpp @@ -19,7 +19,6 @@ #include "mmi-log.h" #include "mmi-workflow-instance-manager.h" -#include #include #include #include diff --git a/src/mmi/mmi-node-action.cpp b/src/mmi/mmi-node-action.cpp deleted file mode 100644 index f5291cc..0000000 --- a/src/mmi/mmi-node-action.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2023 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 "mmi.h" -#include "mmi-node-action.h" - -#include "mmi-log.h" - -int mmi_node_create_action(mmi_node_action_type_e type, mmi_node_h *node) { - if (nullptr == node) { - return MMI_ERROR_INVALID_PARAMETER; - } - *node = new mmi_node_s; - (*node)->type = MMI_NODE_TYPE_ACTION; - (*node)->sub_type = (int)type; - (*node)->custom_type_id[0] = '\0'; - (*node)->ports = nullptr; - (*node)->port_count = 0; - memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks)); - return MMI_ERROR_NONE; -} - -int mmi_node_get_action_type(mmi_node_h node, mmi_node_action_type_e *type) { - if (nullptr == node || nullptr == type) { - return MMI_ERROR_INVALID_PARAMETER; - } - *type = (mmi_node_action_type_e)node->sub_type; - return MMI_ERROR_NONE; -} - diff --git a/src/mmi/mmi-node-controller.cpp b/src/mmi/mmi-node-controller.cpp deleted file mode 100644 index f9a7363..0000000 --- a/src/mmi/mmi-node-controller.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2023 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 "mmi.h" -#include "mmi-node-controller.h" - -#include "mmi-log.h" - -int mmi_node_create_controller(mmi_node_controller_type_e type, mmi_node_h *node) { - if (nullptr == node) { - return MMI_ERROR_INVALID_PARAMETER; - } - *node = new mmi_node_s; - (*node)->type = MMI_NODE_TYPE_CONTROLLER; - (*node)->sub_type = (int)type; - (*node)->custom_type_id[0] = '\0'; - (*node)->ports = nullptr; - (*node)->port_count = 0; - memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks)); - return MMI_ERROR_NONE; -} - -int mmi_node_get_controller_type(mmi_node_h node, mmi_node_controller_type_e *type) { - if (nullptr == node || nullptr == type) { - return MMI_ERROR_INVALID_PARAMETER; - } - *type = (mmi_node_controller_type_e)node->sub_type; - return MMI_ERROR_NONE; -} - diff --git a/src/mmi/mmi-node-custom.cpp b/src/mmi/mmi-node-custom.cpp deleted file mode 100644 index bd1420c..0000000 --- a/src/mmi/mmi-node-custom.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2023 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 "mmi.h" -#include "mmi-node-custom.h" - -#include "mmi-log.h" - - - -int mmi_node_create_custom(const char *custom_type_id, mmi_node_h *node) { - if (nullptr == node) { - return MMI_ERROR_INVALID_PARAMETER; - } - *node = new mmi_node_s; - (*node)->type = MMI_NODE_TYPE_CUSTOM; - (*node)->sub_type = 0; - strncpy((*node)->custom_type_id, custom_type_id, MMI_NAME_MAX_LENGTH); - (*node)->custom_type_id[MMI_NAME_MAX_LENGTH - 1] = '\0'; - (*node)->ports = nullptr; - (*node)->port_count = 0; - memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks)); - return MMI_ERROR_NONE; -} - -int mmi_node_get_custom_type(mmi_node_h node, const char **custom_type_id) { - if (nullptr == node || nullptr == custom_type_id) { - return MMI_ERROR_INVALID_PARAMETER; - } - *custom_type_id = node->custom_type_id; - return MMI_ERROR_NONE; -} - diff --git a/src/mmi/mmi-node-internal.h b/src/mmi/mmi-node-internal.h new file mode 100644 index 0000000..30292b2 --- /dev/null +++ b/src/mmi/mmi-node-internal.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 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. + * + */ + + +#ifndef __TIZEN_UIX_MMI_NODE_INTERNAL_H__ +#define __TIZEN_UIX_MMI_NODE_INTERNAL_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct mmi_node_s { + mmi_node_type_e type; + int sub_type; + char custom_type_id[MMI_NAME_MAX_LENGTH]; + mmi_port_h *ports; + size_t port_count; + mmi_node_callbacks_s callbacks; +}; + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __TIZEN_UIX_MMI_NODE_INTERNAL_H__ */ diff --git a/src/mmi/mmi-node-logic.cpp b/src/mmi/mmi-node-logic.cpp deleted file mode 100644 index 2ef2a80..0000000 --- a/src/mmi/mmi-node-logic.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2023 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 "mmi.h" -#include "mmi-node-logic.h" - -#include "mmi-log.h" - -int mmi_node_create_logic(mmi_node_logic_type_e type, mmi_node_h *node) { - if (nullptr == node) { - return MMI_ERROR_INVALID_PARAMETER; - } - *node = new mmi_node_s; - (*node)->type = MMI_NODE_TYPE_LOGIC; - (*node)->sub_type = (int)type; - (*node)->custom_type_id[0] = '\0'; - (*node)->ports = nullptr; - (*node)->port_count = 0; - memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks)); - return MMI_ERROR_NONE; -} - -int mmi_node_get_logic_type(mmi_node_h node, mmi_node_logic_type_e *type) { - if (nullptr == node) { - return MMI_ERROR_INVALID_PARAMETER; - } - *type = (mmi_node_logic_type_e)node->sub_type; - return MMI_ERROR_NONE; -} - diff --git a/src/mmi/mmi-node-processor.cpp b/src/mmi/mmi-node-processor.cpp deleted file mode 100644 index c3851dc..0000000 --- a/src/mmi/mmi-node-processor.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2023 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 "mmi.h" -#include "mmi-node-processor.h" - -#include "mmi-log.h" - -int mmi_node_create_processor(mmi_node_processor_type_e type, mmi_node_h *node) { - if (nullptr == node) { - return MMI_ERROR_INVALID_PARAMETER; - } - *node = new mmi_node_s; - (*node)->type = MMI_NODE_TYPE_PROCESSOR; - (*node)->sub_type = (int)type; - (*node)->custom_type_id[0] = '\0'; - (*node)->ports = nullptr; - (*node)->port_count = 0; - memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks)); - return MMI_ERROR_NONE; -} - -int mmi_node_get_processor_type(mmi_node_h node, mmi_node_processor_type_e *type) { - if (nullptr == node || nullptr == type) { - return MMI_ERROR_INVALID_PARAMETER; - } - *type = (mmi_node_processor_type_e)node->sub_type; - return MMI_ERROR_NONE; -} - diff --git a/src/mmi/mmi-node-source.cpp b/src/mmi/mmi-node-source.cpp deleted file mode 100644 index c2e455d..0000000 --- a/src/mmi/mmi-node-source.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2023 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 "mmi.h" -#include "mmi-node-source.h" - -#include "mmi-log.h" - -int mmi_node_create_source(mmi_node_source_type_e type, mmi_node_h *node) { - if (nullptr == node) { - return MMI_ERROR_INVALID_PARAMETER; - } - *node = new mmi_node_s; - (*node)->type = MMI_NODE_TYPE_SOURCE; - (*node)->sub_type = (int)type; - (*node)->custom_type_id[0] = '\0'; - (*node)->ports = nullptr; - (*node)->port_count = 0; - memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks)); - return MMI_ERROR_NONE; -} - -int mmi_node_get_source_type(mmi_node_h node, mmi_node_source_type_e *type) { - if (nullptr == type || nullptr == node) { - return MMI_ERROR_INVALID_PARAMETER; - } - *type = (mmi_node_source_type_e)node->sub_type; - return MMI_ERROR_NONE; -} - diff --git a/src/mmi/mmi-node-types.cpp b/src/mmi/mmi-node-types.cpp new file mode 100644 index 0000000..dbb1af8 --- /dev/null +++ b/src/mmi/mmi-node-types.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2023 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 "mmi.h" +#include "mmi-node-internal.h" +#include "mmi-node-types.h" + +#include "mmi-log.h" + +int mmi_node_create_source(mmi_node_source_type_e type, mmi_node_h *node) { + if (nullptr == node) { + return MMI_ERROR_INVALID_PARAMETER; + } + *node = new mmi_node_s; + (*node)->type = MMI_NODE_TYPE_SOURCE; + (*node)->sub_type = (int)type; + (*node)->custom_type_id[0] = '\0'; + (*node)->ports = nullptr; + (*node)->port_count = 0; + memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s)); + return MMI_ERROR_NONE; +} + +int mmi_node_get_source_type(mmi_node_h node, mmi_node_source_type_e *type) { + if (nullptr == type || nullptr == node) { + return MMI_ERROR_INVALID_PARAMETER; + } + *type = (mmi_node_source_type_e)node->sub_type; + return MMI_ERROR_NONE; +} + +int mmi_node_create_processor(mmi_node_processor_type_e type, mmi_node_h *node) { + if (nullptr == node) { + return MMI_ERROR_INVALID_PARAMETER; + } + *node = new mmi_node_s; + (*node)->type = MMI_NODE_TYPE_PROCESSOR; + (*node)->sub_type = (int)type; + (*node)->custom_type_id[0] = '\0'; + (*node)->ports = nullptr; + (*node)->port_count = 0; + memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s)); + return MMI_ERROR_NONE; +} + +int mmi_node_get_processor_type(mmi_node_h node, mmi_node_processor_type_e *type) { + if (nullptr == node || nullptr == type) { + return MMI_ERROR_INVALID_PARAMETER; + } + *type = (mmi_node_processor_type_e)node->sub_type; + return MMI_ERROR_NONE; +} + +int mmi_node_create_logic(mmi_node_logic_type_e type, mmi_node_h *node) { + if (nullptr == node) { + return MMI_ERROR_INVALID_PARAMETER; + } + *node = new mmi_node_s; + (*node)->type = MMI_NODE_TYPE_LOGIC; + (*node)->sub_type = (int)type; + (*node)->custom_type_id[0] = '\0'; + (*node)->ports = nullptr; + (*node)->port_count = 0; + memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s)); + return MMI_ERROR_NONE; +} + +int mmi_node_get_logic_type(mmi_node_h node, mmi_node_logic_type_e *type) { + if (nullptr == node) { + return MMI_ERROR_INVALID_PARAMETER; + } + *type = (mmi_node_logic_type_e)node->sub_type; + return MMI_ERROR_NONE; +} + +int mmi_node_create_controller(mmi_node_controller_type_e type, mmi_node_h *node) { + if (nullptr == node) { + return MMI_ERROR_INVALID_PARAMETER; + } + *node = new mmi_node_s; + (*node)->type = MMI_NODE_TYPE_CONTROLLER; + (*node)->sub_type = (int)type; + (*node)->custom_type_id[0] = '\0'; + (*node)->ports = nullptr; + (*node)->port_count = 0; + memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s)); + return MMI_ERROR_NONE; +} + +int mmi_node_get_controller_type(mmi_node_h node, mmi_node_controller_type_e *type) { + if (nullptr == node || nullptr == type) { + return MMI_ERROR_INVALID_PARAMETER; + } + *type = (mmi_node_controller_type_e)node->sub_type; + return MMI_ERROR_NONE; +} + +int mmi_node_create_action(mmi_node_action_type_e type, mmi_node_h *node) { + if (nullptr == node) { + return MMI_ERROR_INVALID_PARAMETER; + } + *node = new mmi_node_s; + (*node)->type = MMI_NODE_TYPE_ACTION; + (*node)->sub_type = (int)type; + (*node)->custom_type_id[0] = '\0'; + (*node)->ports = nullptr; + (*node)->port_count = 0; + memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s)); + return MMI_ERROR_NONE; +} + +int mmi_node_get_action_type(mmi_node_h node, mmi_node_action_type_e *type) { + if (nullptr == node || nullptr == type) { + return MMI_ERROR_INVALID_PARAMETER; + } + *type = (mmi_node_action_type_e)node->sub_type; + return MMI_ERROR_NONE; +} + +int mmi_node_create_custom(const char *custom_type_id, mmi_node_h *node) { + if (nullptr == node) { + return MMI_ERROR_INVALID_PARAMETER; + } + *node = new mmi_node_s; + (*node)->type = MMI_NODE_TYPE_CUSTOM; + (*node)->sub_type = 0; + strncpy((*node)->custom_type_id, custom_type_id, MMI_NAME_MAX_LENGTH); + (*node)->custom_type_id[MMI_NAME_MAX_LENGTH - 1] = '\0'; + (*node)->ports = nullptr; + (*node)->port_count = 0; + memset(&(*node)->callbacks, 0, sizeof(mmi_node_callbacks_s)); + return MMI_ERROR_NONE; +} + +int mmi_node_get_custom_type(mmi_node_h node, const char **custom_type_id) { + if (nullptr == node || nullptr == custom_type_id) { + return MMI_ERROR_INVALID_PARAMETER; + } + *custom_type_id = node->custom_type_id; + return MMI_ERROR_NONE; +} + diff --git a/src/mmi/mmi-node.cpp b/src/mmi/mmi-node.cpp index c5d0df6..7dfcc38 100644 --- a/src/mmi/mmi-node.cpp +++ b/src/mmi/mmi-node.cpp @@ -18,6 +18,7 @@ #include "mmi.h" #include "mmi-node.h" +#include "mmi-node-internal.h" #include "mmi-plugin-storage.h" #include "mmi-log.h" @@ -109,7 +110,7 @@ int mmi_node_get_port(mmi_node_h node, size_t index, mmi_port_h *port) { return MMI_ERROR_NONE; } -int mmi_node_get_callbacks(mmi_node_h node, mmi_node_callbacks *callbacks) { +int mmi_node_get_callbacks(mmi_node_h node, mmi_node_callbacks_s *callbacks) { if (nullptr == node || nullptr == callbacks) { LOGE("[ERROR] parameter is null"); return MMI_ERROR_INVALID_PARAMETER; @@ -118,7 +119,7 @@ int mmi_node_get_callbacks(mmi_node_h node, mmi_node_callbacks *callbacks) { return MMI_ERROR_NONE; } -int mmi_node_set_callbacks(mmi_node_h node, mmi_node_callbacks callbacks) { +int mmi_node_set_callbacks(mmi_node_h node, mmi_node_callbacks_s callbacks, void *user_data) { if (nullptr == node) { LOGE("[ERROR] parameter is null"); return MMI_ERROR_INVALID_PARAMETER; @@ -308,15 +309,23 @@ int mmi_node_instance_set_attribute(mmi_node_instance_h instance, mmi_attribute_ return MMI_ERROR_NONE; } -int mmi_node_instance_find_port(mmi_node_instance_h instance, mmi_port_type_e port_type, const char *port_name, mmi_port_instance_h *port) { - if (instance == NULL || port_name == NULL || port == NULL) { +int mmi_node_instance_find_port_instance(mmi_node_instance_h node_instance, mmi_port_type_e port_type, const char *port_name, mmi_port_instance_h *port_instance) { + if (node_instance == NULL || port_name == NULL || port_instance == NULL) { return MMI_ERROR_INVALID_PARAMETER; } - *port = mmi_plugin_storage_find_port_instance(instance, port_name); + *port_instance = mmi_plugin_storage_find_port_instance(node_instance, port_name); return MMI_ERROR_NONE; } -int mmi_node_instance_find_sibling_port(mmi_port_instance_h instance, const char *port_name, mmi_port_instance_h *sibling) { +int mmi_node_instance_find_by_port_instance(mmi_port_instance_h port_instance, mmi_node_instance_h *node_instance) { + if (port_instance == NULL || node_instance == NULL) { + return MMI_ERROR_INVALID_PARAMETER; + } + *node_instance = mmi_plugin_storage_find_node_instance_by_port_instance(port_instance); + return MMI_ERROR_NONE; +} + +int mmi_node_instance_find_sibling_port_instance(mmi_port_instance_h instance, const char *port_name, mmi_port_instance_h *sibling) { if (instance == NULL || port_name == NULL || sibling == NULL) { return MMI_ERROR_INVALID_PARAMETER; } diff --git a/src/mmi/mmi-port.cpp b/src/mmi/mmi-port.cpp index 9e3fc47..9635f4e 100644 --- a/src/mmi/mmi-port.cpp +++ b/src/mmi/mmi-port.cpp @@ -17,7 +17,7 @@ #include "mmi.h" -#include "mmi-log.h" +#include "mmi-common.h" #include "mmi-port.h" #include "mmi-plugin-storage.h" @@ -83,7 +83,7 @@ MMI_API int mmi_port_get_data_type(mmi_port_h port, mmi_data_type_e *data_type) } // LCOV_EXCL_START -MMI_API int mmi_port_get_callbacks(mmi_port_h port, mmi_port_callbacks *callbacks) { +MMI_API int mmi_port_get_callbacks(mmi_port_h port, mmi_port_callbacks_s *callbacks) { if (nullptr == port || nullptr == callbacks) { LOGE("[ERROR] parameter is null"); return MMI_ERROR_INVALID_PARAMETER; @@ -136,7 +136,7 @@ MMI_API int mmi_port_set_data_type(mmi_port_h port, mmi_data_type_e data_type) { return MMI_ERROR_NONE; } -MMI_API int mmi_port_set_callbacks(mmi_port_h port, mmi_port_callbacks callbacks) { +MMI_API int mmi_port_set_callbacks(mmi_port_h port, mmi_port_callbacks_s callbacks, void *user_data) { if (nullptr == port) { LOGE("[ERROR] parameter is null"); return MMI_ERROR_INVALID_PARAMETER; diff --git a/src/mmi/mmi-signal-internal.h b/src/mmi/mmi-signal-internal.h new file mode 100644 index 0000000..6d07818 --- /dev/null +++ b/src/mmi/mmi-signal-internal.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 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. + * + */ + + +#ifndef __TIZEN_UIX_MMI_SIGNAL_INTERNAL_H__ +#define __TIZEN_UIX_MMI_SIGNAL_INTERNAL_H__ + +#include +#include + +#include "mmi-defines.h" + +/** +* @file mmi-port-internal.h +*/ + + +/** +* @addtogroup CAPI_UIX_MMI_COMMON_MODULE +* @ingroup CAPI_UIX_MMI_MODULE +* @{ +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +struct mmi_signal_parameter_s { + char name[MMI_NAME_MAX_LENGTH]; + mmi_primitive_value_h value; +}; + +struct mmi_signal_s { + char name[MMI_NAME_MAX_LENGTH]; + mmi_signal_parameter_h parameters[MMI_PARAMETER_MAX_COUNT]; + int parameter_count; +}; + +#ifdef __cplusplus +} +#endif + + +/** + * @} + */ + + +#endif /* __TIZEN_UIX_MMI_SIGNAL_INTERNAL_H__ */ diff --git a/src/mmi/mmi-signal.cpp b/src/mmi/mmi-signal.cpp index c3540d0..a49903e 100644 --- a/src/mmi/mmi-signal.cpp +++ b/src/mmi/mmi-signal.cpp @@ -18,8 +18,9 @@ #include "mmi.h" #include "mmi-signal.h" +#include "mmi-signal-internal.h" -#include "mmi-log.h" +#include "mmi-common.h" #include diff --git a/src/mmi/mmi-workflow-instance.cpp b/src/mmi/mmi-workflow-instance.cpp index 2c97e35..c3da4bd 100644 --- a/src/mmi/mmi-workflow-instance.cpp +++ b/src/mmi/mmi-workflow-instance.cpp @@ -27,7 +27,7 @@ #include "mmi-plugin-storage.h" #include "mmi-client-manager.h" -#include "mmi-log.h" +#include "mmi-common.h" #include "mmi-workflow-instance-manager.h" #include "mmi-workflow-script-generator.h" @@ -252,7 +252,7 @@ MMI_API int mmi_workflow_instance_feed_data(mmi_workflow_instance_h instance, co } // LCOV_EXCL_START -MMI_API int mmi_workflow_instance_set_output_callback(mmi_workflow_instance_h instance, const char *name, mmi_workflow_output_cb callback, void *user_data) { +MMI_API int mmi_workflow_instance_set_output_cb(mmi_workflow_instance_h instance, const char *name, mmi_workflow_output_cb callback, void *user_data) { if (nullptr == instance) { LOGE("[ERROR] parameter is null"); return MMI_ERROR_INVALID_PARAMETER; diff --git a/src/mmi/mmi-workflow-internal.h b/src/mmi/mmi-workflow-internal.h new file mode 100644 index 0000000..24c6248 --- /dev/null +++ b/src/mmi/mmi-workflow-internal.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023 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. + * + */ + + +#ifndef __TIZEN_UIX_MMI_WORKFLOW_INTERNAL_H__ +#define __TIZEN_UIX_MMI_WORKFLOW_INTERNAL_H__ + + +#include +#include +#include "mmi-defines.h" + + +/** +* @file mmi-workflow.h +*/ + + +/** +* @addtogroup CAPI_UIX_MMI_MODULE +* @{ +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Functions to define a workflow prototype. Mostly used by workflow developers. */ + +struct mmi_workflow_node_info_s { + char name[MMI_NAME_MAX_LENGTH]; + mmi_node_h node; +}; + +struct mmi_workflow_link_info_s { + char from_node_name[MMI_NAME_MAX_LENGTH]; + char from_port_name[MMI_NAME_MAX_LENGTH]; + char to_node_name[MMI_NAME_MAX_LENGTH]; + char to_port_name[MMI_NAME_MAX_LENGTH]; +}; + +struct mmi_workflow_attribute_assignment_info_s { + char attribute_name[MMI_NAME_MAX_LENGTH]; + char target_node_name[MMI_NAME_MAX_LENGTH]; + char target_attribute_name[MMI_NAME_MAX_LENGTH]; +}; + +struct mmi_workflow_attribute_default_value_info_s { + size_t serialized_default_value_size; + unsigned char *serialized_default_value; +}; + +struct mmi_workflow_signal_assignment_info_s { + char signal_name[MMI_NAME_MAX_LENGTH]; + char target_node_name[MMI_NAME_MAX_LENGTH]; + char target_signal_name[MMI_NAME_MAX_LENGTH]; +}; + +struct mmi_workflow_output_assignment_info_s { + char output_name[MMI_NAME_MAX_LENGTH]; + char from_node_name[MMI_NAME_MAX_LENGTH]; + char from_port_name[MMI_NAME_MAX_LENGTH]; +}; + +struct mmi_workflow_s { + mmi_standard_workflow_type_e type; + mmi_workflow_node_info_s *node_infos; + size_t node_info_count; + mmi_workflow_link_info_s *link_infos; + size_t link_info_count; + mmi_workflow_attribute_assignment_info_s *attribute_assignment_infos; + size_t attribute_assignment_info_count; + mmi_workflow_attribute_default_value_info_s *attribute_default_value_infos; + size_t attribute_default_value_info_count; + mmi_workflow_signal_assignment_info_s *signal_assignment_infos; + size_t signal_assignment_info_count; + mmi_workflow_output_assignment_info_s *output_assignment_infos; + size_t output_assignment_info_count; +}; + + +#ifdef __cplusplus +} +#endif + + +/** + * @} + */ + + +#endif /* __TIZEN_UIX_MMI_WORKFLOW_INTERNAL_H__ */ diff --git a/src/mmi/mmi-workflow-script-common.h b/src/mmi/mmi-workflow-script-common.h index 81f3e42..f189275 100644 --- a/src/mmi/mmi-workflow-script-common.h +++ b/src/mmi/mmi-workflow-script-common.h @@ -28,6 +28,7 @@ enum class WorkflowScriptSection { NODE_LIST, LINK_LIST, ATTRIBUTE_LIST, + SIGNAL_LIST, OUTPUT_LIST, }; @@ -42,6 +43,7 @@ struct WorkflowScriptHelper { {WorkflowScriptSection::NODE_LIST, "@node-list"}, {WorkflowScriptSection::LINK_LIST, "@link-list"}, {WorkflowScriptSection::ATTRIBUTE_LIST, "@attribute-list"}, + {WorkflowScriptSection::SIGNAL_LIST, "@signal-list"}, {WorkflowScriptSection::OUTPUT_LIST, "@output-list"}, }; }; diff --git a/src/mmi/mmi-workflow-script-generator.h b/src/mmi/mmi-workflow-script-generator.h index 6cdd272..c32f64b 100644 --- a/src/mmi/mmi-workflow-script-generator.h +++ b/src/mmi/mmi-workflow-script-generator.h @@ -20,12 +20,8 @@ #define __MMI_WORKFLOW_SCRIPT_GENERATOR_H__ #include "mmi-log.h" -#include "mmi-node-source.h" -#include "mmi-node-processor.h" -#include "mmi-node-logic.h" -#include "mmi-node-controller.h" -#include "mmi-node-action.h" -#include "mmi-node-custom.h" +#include "mmi-node-types.h" +#include "mmi-workflow-internal.h" #include "mmi-workflow-script-common.h" #include "magic_enum/magic_enum.hpp" @@ -196,6 +192,26 @@ public: } return section_script; } + std::string generate_signal_list_section(mmi_workflow_s *workflow) { + std::string section_script; + auto found_section_name = std::find_if( + m_workflow_script_helper.section_names.begin(), + m_workflow_script_helper.section_names.end(), + [](WorkflowScriptSectionName section_name) { return section_name.section == WorkflowScriptSection::SIGNAL_LIST; }); + if (found_section_name != m_workflow_script_helper.section_names.end()) { + section_script += found_section_name->name + "\n"; + for (size_t i = 0; i < workflow->signal_assignment_info_count; i++) { + section_script += + std::string(workflow->signal_assignment_infos[i].target_node_name) + + "." + + std::string(workflow->signal_assignment_infos[i].target_signal_name) + + " as " + + std::string(workflow->signal_assignment_infos[i].signal_name) + + "\n"; + } + } + return section_script; + } std::string generate_output_list_section(mmi_workflow_s *workflow) { std::string section_script; auto found_section_name = std::find_if( @@ -230,6 +246,8 @@ public: script += "\n"; script += generate_attribute_list_section(workflow_ptr); script += "\n"; + script += generate_signal_list_section(workflow_ptr); + script += "\n"; script += generate_output_list_section(workflow_ptr); script += "\n"; diff --git a/src/mmi/mmi-workflow-script-parser.h b/src/mmi/mmi-workflow-script-parser.h index de58678..c912d59 100644 --- a/src/mmi/mmi-workflow-script-parser.h +++ b/src/mmi/mmi-workflow-script-parser.h @@ -24,12 +24,8 @@ #include #include "mmi-log.h" -#include "mmi-node-source.h" -#include "mmi-node-processor.h" -#include "mmi-node-logic.h" -#include "mmi-node-controller.h" -#include "mmi-node-action.h" -#include "mmi-node-custom.h" +#include "mmi-node-types.h" +#include "mmi-workflow-internal.h" #include "mmi-workflow-script-common.h" #include "magic_enum/magic_enum.hpp" @@ -96,6 +92,7 @@ public: m_section_patterns.push_back({WorkflowScriptSection::NODE_LIST, std::regex("^\\[([a-zA-Z]+)\\] ([a-zA-Z_\\-.]+) as ([a-zA-Z0-9_]+)$")}); m_section_patterns.push_back({WorkflowScriptSection::LINK_LIST, std::regex("^([a-zA-Z0-9_.]+) -> ([a-zA-Z0-9_.]+)$")}); m_section_patterns.push_back({WorkflowScriptSection::ATTRIBUTE_LIST, std::regex("^([a-zA-Z0-9_.]+) as ([a-zA-Z0-9_]+)$")}); + m_section_patterns.push_back({WorkflowScriptSection::SIGNAL_LIST, std::regex("^([a-zA-Z0-9_.]+) as ([a-zA-Z0-9_]+)$")}); m_section_patterns.push_back({WorkflowScriptSection::OUTPUT_LIST, std::regex("^([a-zA-Z0-9_.]+) as ([a-zA-Z0-9_]+)$")}); int loop; @@ -420,6 +417,29 @@ public: return true; } + bool process_signal_section(std::smatch matches, mmi_workflow_h workflow) { + if (matches.size() == 3) { + std::ssub_match sub_match_name = matches[1]; + std::string identifier = sub_match_name.str(); + + std::ssub_match sub_match_value = matches[2]; + std::string alias = sub_match_value.str(); + + LOGD("identifier: %s, alias: %s", identifier.c_str(), alias.c_str()); + + size_t pos = identifier.find("."); + if (pos != std::string::npos) { + std::string node_name = identifier.substr(0, pos); + std::string signal_name = identifier.substr(pos + 1); + + LOGD("node_name: %s, signal_name: %s", node_name.c_str(), signal_name.c_str()); + + mmi_workflow_signal_assign(workflow, alias.c_str(), node_name.c_str(), signal_name.c_str()); + } + } + return true; + } + bool process_output_section(std::smatch matches, mmi_workflow_h workflow) { if (matches.size() == 3) { std::ssub_match sub_match_name = matches[1]; @@ -475,6 +495,12 @@ public: return false; } break; + case WorkflowScriptSection::SIGNAL_LIST: + if (process_signal_section(matches, workflow) == false) { + LOGE("[ERROR] Failed to process attribute section"); + return false; + } + break; case WorkflowScriptSection::OUTPUT_LIST: if (process_output_section(matches, workflow) == false) { LOGE("[ERROR] Failed to process output section"); diff --git a/src/mmi/mmi-workflow-script.cpp b/src/mmi/mmi-workflow-script.cpp index 02c57c0..34bb597 100644 --- a/src/mmi/mmi-workflow-script.cpp +++ b/src/mmi/mmi-workflow-script.cpp @@ -17,7 +17,7 @@ #include "mmi.h" -#include "mmi-log.h" +#include "mmi-common.h" #include "mmi-workflow.h" #include "mmi-workflow-script-parser.h" diff --git a/src/mmi/mmi-workflow.cpp b/src/mmi/mmi-workflow.cpp index 77f913b..d4e2960 100644 --- a/src/mmi/mmi-workflow.cpp +++ b/src/mmi/mmi-workflow.cpp @@ -26,7 +26,8 @@ #include "mmi.h" #include "mmi-plugin-storage.h" -#include "mmi-log.h" +#include "mmi-common.h" +#include "mmi-workflow-internal.h" MMI_API int mmi_workflow_create(mmi_workflow_h *workflow) { if (nullptr == workflow) { diff --git a/src/mmi/mmi.cpp b/src/mmi/mmi.cpp index 88d10ec..70e8c13 100644 --- a/src/mmi/mmi.cpp +++ b/src/mmi/mmi.cpp @@ -23,7 +23,7 @@ #include -#include "mmi-log.h" +#include "mmi-common.h" #include "mmi-client-manager.h" diff --git a/tests/mmi-manager/node-instance-manager/mmi-node-instance-manager-tests.cpp b/tests/mmi-manager/node-instance-manager/mmi-node-instance-manager-tests.cpp index 646c427..5a1420f 100644 --- a/tests/mmi-manager/node-instance-manager/mmi-node-instance-manager-tests.cpp +++ b/tests/mmi-manager/node-instance-manager/mmi-node-instance-manager-tests.cpp @@ -32,6 +32,19 @@ public: virtual std::shared_ptr get_node_prototype( mmi_node_type_e type, mmi_node_sub_type_e sub_type) override { last_query = std::make_pair(type, sub_type); + + if (type == MMI_NODE_TYPE_LOGIC && + std::get(sub_type) == MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH) { + auto prototype = std::make_shared(); + prototype->set_type(MMI_NODE_TYPE_LOGIC); + prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); + PortInfo port_info_text{"TEXT", MMI_PORT_TYPE_IN, MMI_DATA_TYPE_TEXT, "Text Data"}; + PortInfo port_info_matched_candidate{"MATCHED_CANDIDATE", MMI_PORT_TYPE_OUT, MMI_DATA_TYPE_TEXT, "Matched Data"}; + prototype->add_port_info(port_info_matched_candidate); + prototype->add_port_info(port_info_text); + return prototype; + } + return nullptr; } @@ -53,6 +66,22 @@ public: std::shared_ptr proxy; }; +class PortInstanceManagerDummy : public IPortInstanceManager { +public: + std::shared_ptr create_port_instance() override { + return std::make_shared(); + } + bool destroy_port_instance( + std::shared_ptr port_instance) override { + return true; + } + bool link_port_instances( + std::shared_ptr out_port, + std::shared_ptr in_port) override { + return true; + } +}; + class NodeInstanceManagerTest : public testing::Test { public: NodeInstanceManagerTest() { @@ -62,9 +91,11 @@ public: void SetUp() override { prototype_store = std::make_shared(); plugin_module_proxy_provider = std::make_shared(); + port_instance_manager = std::make_shared(); manager.set_node_prototype_store(prototype_store); manager.set_plugin_module_proxy_provider(plugin_module_proxy_provider); + manager.set_port_instance_manager(port_instance_manager); ASSERT_NE(prototype_store, nullptr); ASSERT_NE(plugin_module_proxy_provider, nullptr); @@ -76,6 +107,7 @@ public: std::shared_ptr prototype_store; std::shared_ptr plugin_module_proxy_provider; + std::shared_ptr port_instance_manager; }; TEST_F(NodeInstanceManagerTest, ProperNodePrototypeQueriedWhenCreatingNodeInstance) { @@ -83,10 +115,52 @@ TEST_F(NodeInstanceManagerTest, ProperNodePrototypeQueriedWhenCreatingNodeInstan MMI_NODE_TYPE_NONE, std::monostate{}); std::shared_ptr instance = manager.create_node_instance( - MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR ); + MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); + + ASSERT_EQ(prototype_store->last_query.first, MMI_NODE_TYPE_LOGIC); + ASSERT_EQ(prototype_store->last_query.second, mmi_node_sub_type_e{MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH}); +} + +TEST_F(NodeInstanceManagerTest, NodeInstanceFoundByChildPortInstance) { + std::shared_ptr instance = manager.create_node_instance( + MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); + + mmi_node_instance_h node_instance = static_cast(instance.get()); + + mmi_port_instance_h port_instance_text = nullptr; + mmi_port_instance_h port_instance_matched_candidate = nullptr; + mmi_node_instance_find_port_instance(node_instance, MMI_PORT_TYPE_IN, "TEXT", &port_instance_text); + mmi_node_instance_find_port_instance(node_instance, MMI_PORT_TYPE_OUT, "MATCHED_CANDIDATE", &port_instance_matched_candidate); + + mmi_node_instance_h found_by_text = nullptr; + mmi_node_instance_h found_by_matched_candidate = nullptr; + mmi_node_instance_find_by_port_instance(port_instance_text, &found_by_text); + mmi_node_instance_find_by_port_instance(port_instance_matched_candidate, &found_by_matched_candidate); + + ASSERT_EQ(node_instance, found_by_matched_candidate); + ASSERT_EQ(node_instance, found_by_text); +} + +TEST_F(NodeInstanceManagerTest, NodeInstanceNotMatchByDifferentChildPortInstance) { + std::shared_ptr instance_1 = manager.create_node_instance( + MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); + std::shared_ptr instance_2 = manager.create_node_instance( + MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); + + mmi_node_instance_h node_instance_1 = static_cast(instance_1.get()); + mmi_node_instance_h node_instance_2 = static_cast(instance_2.get()); + + mmi_port_instance_h port_instance_text_1 = nullptr; + mmi_port_instance_h port_instance_matched_candidate_2 = nullptr; + mmi_node_instance_find_port_instance(node_instance_1, MMI_PORT_TYPE_IN, "TEXT", &port_instance_text_1); + mmi_node_instance_find_port_instance(node_instance_2, MMI_PORT_TYPE_OUT, "MATCHED_CANDIDATE", &port_instance_matched_candidate_2); + + mmi_node_instance_h found_by_text_1 = nullptr; + mmi_node_instance_h found_by_matched_candidate_2 = nullptr; + mmi_node_instance_find_by_port_instance(port_instance_text_1, &found_by_text_1); + mmi_node_instance_find_by_port_instance(port_instance_matched_candidate_2, &found_by_matched_candidate_2); - ASSERT_EQ(prototype_store->last_query.first, MMI_NODE_TYPE_PROCESSOR); - ASSERT_EQ(prototype_store->last_query.second, mmi_node_sub_type_e{MMI_NODE_PROCESSOR_TYPE_ASR}); + ASSERT_NE(found_by_matched_candidate_2, found_by_text_1); } } // namespace diff --git a/tests/mmi-manager/node-prototype-manager/mmi-node-prototype-manager-tests.cpp b/tests/mmi-manager/node-prototype-manager/mmi-node-prototype-manager-tests.cpp index 82a0c3c..e253acc 100644 --- a/tests/mmi-manager/node-prototype-manager/mmi-node-prototype-manager-tests.cpp +++ b/tests/mmi-manager/node-prototype-manager/mmi-node-prototype-manager-tests.cpp @@ -37,7 +37,7 @@ public: PluginModuleInfo{mmi_plugin_module_type_e::SHARED_LIBRARY, "test.so"}); valid_prototype->set_type(MMI_NODE_TYPE_SOURCE); - valid_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT); + valid_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER); ASSERT_TRUE(valid_prototype->is_valid()); } @@ -62,7 +62,7 @@ TEST_F(NodePrototypeManagerTest, NodePrototypeManagerRefusesInvalidPrototype_n) auto invalid_prototype = std::make_shared(); invalid_prototype->set_type(MMI_NODE_TYPE_SOURCE); - invalid_prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR); + invalid_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER); manager.add_node_prototype(invalid_prototype); diff --git a/tests/mmi-manager/node-prototype/mmi-node-prototype-tests.cpp b/tests/mmi-manager/node-prototype/mmi-node-prototype-tests.cpp index 22d8305..ab1827f 100644 --- a/tests/mmi-manager/node-prototype/mmi-node-prototype-tests.cpp +++ b/tests/mmi-manager/node-prototype/mmi-node-prototype-tests.cpp @@ -43,17 +43,17 @@ TEST_F(NodePrototypeTest, NodePrototypeValidationSucceedsForDifferentNodeTypes_p PluginModuleInfo{mmi_plugin_module_type_e::SHARED_LIBRARY, "test.so"}); prototype->set_type(MMI_NODE_TYPE_SOURCE); - prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT); - ASSERT_TRUE(prototype->is_valid()); - - prototype->set_type(MMI_NODE_TYPE_PROCESSOR); - prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR); + prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER); ASSERT_TRUE(prototype->is_valid()); prototype->set_type(MMI_NODE_TYPE_LOGIC); prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); ASSERT_TRUE(prototype->is_valid()); + prototype->set_type(MMI_NODE_TYPE_ACTION); + prototype->set_sub_type(MMI_NODE_ACTION_TYPE_KEY_EVENT); + ASSERT_TRUE(prototype->is_valid()); + prototype->set_type(MMI_NODE_TYPE_CUSTOM); prototype->set_sub_type("com.samsung.tizen.custom-node-llm"); ASSERT_TRUE(prototype->is_valid()); @@ -75,7 +75,7 @@ TEST_F(NodePrototypeTest, NodePrototypeValidationFailsWithIncorrectSubtype_n) { prototype->set_type(MMI_NODE_TYPE_SOURCE); /* PROCESSOR sub type for SOURCE type */ - prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR); + prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); ASSERT_FALSE(prototype->is_valid()); } @@ -86,7 +86,7 @@ TEST_F(NodePrototypeTest, NodePrototypeValidationFailsWithNoPluginModuleInfo_n) /* No plugin module identifier provided */ prototype->set_type(MMI_NODE_TYPE_SOURCE); - prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT); + prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER); ASSERT_FALSE(prototype->is_valid()); } @@ -99,18 +99,11 @@ TEST_F(NodePrototypeTest, NodePrototypeContainsCorrectSubType_p) { mmi_node_sub_type_e sub_type; prototype->set_type(MMI_NODE_TYPE_SOURCE); - prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT); + prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER); type = prototype->get_type(); sub_type = prototype->get_sub_type(); ASSERT_EQ(type, MMI_NODE_TYPE_SOURCE); - ASSERT_EQ(std::get(sub_type), MMI_NODE_SOURCE_TYPE_MIC_AMBIENT); - - prototype->set_type(MMI_NODE_TYPE_PROCESSOR); - prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR); - type = prototype->get_type(); - sub_type = prototype->get_sub_type(); - ASSERT_EQ(type, MMI_NODE_TYPE_PROCESSOR); - ASSERT_EQ(std::get(sub_type), MMI_NODE_PROCESSOR_TYPE_ASR); + ASSERT_EQ(std::get(sub_type), MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER); prototype->set_type(MMI_NODE_TYPE_LOGIC); prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); @@ -119,6 +112,13 @@ TEST_F(NodePrototypeTest, NodePrototypeContainsCorrectSubType_p) { ASSERT_EQ(type, MMI_NODE_TYPE_LOGIC); ASSERT_EQ(std::get(sub_type), MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); + prototype->set_type(MMI_NODE_TYPE_ACTION); + prototype->set_sub_type(MMI_NODE_ACTION_TYPE_KEY_EVENT); + type = prototype->get_type(); + sub_type = prototype->get_sub_type(); + ASSERT_EQ(type, MMI_NODE_TYPE_ACTION); + ASSERT_EQ(std::get(sub_type), MMI_NODE_ACTION_TYPE_KEY_EVENT); + prototype->set_type(MMI_NODE_TYPE_CUSTOM); prototype->set_sub_type("com.samsung.tizen.custom-node-llm"); type = prototype->get_type(); diff --git a/tests/mmi-manager/plugin-module-registry/mmi-plugin-module-registry-tests.cpp b/tests/mmi-manager/plugin-module-registry/mmi-plugin-module-registry-tests.cpp index dfdd760..7afb296 100644 --- a/tests/mmi-manager/plugin-module-registry/mmi-plugin-module-registry-tests.cpp +++ b/tests/mmi-manager/plugin-module-registry/mmi-plugin-module-registry-tests.cpp @@ -225,12 +225,12 @@ TEST_F(PluginModuleRegistryTest, DummyNodeInfoProperlyCreatedAndRetrieved_p) { bool ret = registry.load_node_prototypes(); ASSERT_TRUE(ret); - auto asr_node = node_prototype_store->get_node_prototype(MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR); - ASSERT_NE(nullptr, asr_node); - auto match_node = node_prototype_store->get_node_prototype(MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); ASSERT_NE(nullptr, match_node); + auto key_event_node = node_prototype_store->get_node_prototype(MMI_NODE_TYPE_ACTION, MMI_NODE_ACTION_TYPE_KEY_EVENT); + ASSERT_NE(nullptr, key_event_node); + registry.deinitialize(); } @@ -240,7 +240,7 @@ TEST_F(PluginModuleRegistryTest, NonExistingNodeNotRetrieved_n) { bool ret = registry.load_node_prototypes(); ASSERT_TRUE(ret); - auto node = node_prototype_store->get_node_prototype(MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_NONE); + auto node = node_prototype_store->get_node_prototype(MMI_NODE_TYPE_ACTION, MMI_NODE_PROCESSOR_TYPE_NONE); ASSERT_EQ(nullptr, node); registry.deinitialize(); @@ -252,7 +252,7 @@ TEST_F(PluginModuleRegistryTest, DummyWorkflowInfoProperlyCreatedAndRetrieved_p) bool ret = registry.load_workflow_prototypes(); ASSERT_TRUE(ret); - auto workflow = workflow_prototype_store->get_workflow_prototype(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + auto workflow = workflow_prototype_store->get_workflow_prototype(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); ASSERT_NE(nullptr, workflow); registry.deinitialize(); diff --git a/tests/mmi-manager/workflow-instance-manager/mmi-workflow-instance-manager-tests.cpp b/tests/mmi-manager/workflow-instance-manager/mmi-workflow-instance-manager-tests.cpp index cff4c25..e1c55ce 100644 --- a/tests/mmi-manager/workflow-instance-manager/mmi-workflow-instance-manager-tests.cpp +++ b/tests/mmi-manager/workflow-instance-manager/mmi-workflow-instance-manager-tests.cpp @@ -63,19 +63,19 @@ public: NodeInstanceManagerDummy() { node_prototype_store = std::make_shared(); - auto mic_prototype = std::make_shared(); - mic_prototype->set_type(MMI_NODE_TYPE_SOURCE); - mic_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT); - PortInfo mic_audio{"AUDIO", MMI_PORT_TYPE_OUT, MMI_DATA_TYPE_AUDIO, "audio data"}; - mic_prototype->add_port_info(mic_audio); - node_prototype_store->add_node_prototype(mic_prototype); - - auto asr_prototype = std::make_shared(); - asr_prototype->set_type(MMI_NODE_TYPE_PROCESSOR); - asr_prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR); - PortInfo asr_audio{"AUDIO", MMI_PORT_TYPE_IN, MMI_DATA_TYPE_AUDIO, "audio data"}; - asr_prototype->add_port_info(asr_audio); - node_prototype_store->add_node_prototype(asr_prototype); + auto screen_analyzer_prototype = std::make_shared(); + screen_analyzer_prototype->set_type(MMI_NODE_TYPE_SOURCE); + screen_analyzer_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER); + PortInfo mic_audio{"SCREEN_INFO", MMI_PORT_TYPE_OUT, MMI_DATA_TYPE_TEXT, "screen info"}; + screen_analyzer_prototype->add_port_info(mic_audio); + node_prototype_store->add_node_prototype(screen_analyzer_prototype); + + auto match_prototype = std::make_shared(); + match_prototype->set_type(MMI_NODE_TYPE_LOGIC); + match_prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); + PortInfo asr_audio{"TEXT", MMI_PORT_TYPE_IN, MMI_DATA_TYPE_TEXT, "text data"}; + match_prototype->add_port_info(asr_audio); + node_prototype_store->add_node_prototype(match_prototype); } virtual std::shared_ptr create_node_instance( @@ -201,7 +201,7 @@ TEST_F(WorkflowInstanceManagerTest, WorkflowInstanceCreatedProperly_p) { ClientMessageWorkflowInstanceCreate msg; msg.sender = std::string{"client-1"}; msg.local_workflow_instance_id = 0; - msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND; + msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH; channel.notify_observers( COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast(&msg)); @@ -215,7 +215,7 @@ TEST_F(WorkflowInstanceManagerTest, WorkflowInstanceNotCreatedProperlyWhenDuplic ClientMessageWorkflowInstanceCreate msg; msg.sender = std::string{"client-1"}; msg.local_workflow_instance_id = 0; - msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND; + msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH; channel.notify_observers( COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast(&msg)); @@ -253,7 +253,7 @@ TEST_F(WorkflowInstanceManagerTest, AllWorkflowInstanceDeletedOnDeinitialize_p) ClientMessageWorkflowInstanceCreate msg; msg.sender = std::string{"client-1"}; msg.local_workflow_instance_id = 0; - msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND; + msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH; channel.notify_observers( COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast(&msg)); @@ -268,19 +268,19 @@ TEST_F(WorkflowInstanceManagerTest, NodeInstanceCreationRequestedForWorkflowInst ASSERT_EQ(node_instance_manager->create_requests.size(), 0); auto prototype = std::make_shared(); - prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); /* Add 2 nodes to the workflow prototype */ prototype->add_node_info(mmi::NodeInfo{ - "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT}); + "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER}); prototype->add_node_info(mmi::NodeInfo{ - "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR}); + "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH}); workflow_prototype_store->add_workflow_prototype(prototype); ClientMessageWorkflowInstanceCreate msg; msg.sender = std::string{"client-1"}; msg.local_workflow_instance_id = 0; - msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND; + msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH; channel.notify_observers( COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast(&msg)); @@ -290,19 +290,19 @@ TEST_F(WorkflowInstanceManagerTest, NodeInstanceCreationRequestedForWorkflowInst TEST_F(WorkflowInstanceManagerTest, NodeInstanceDestroyRequestedOnWorkflowDestruction_p) { auto prototype = std::make_shared(); - prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); /* Add 2 nodes to the workflow prototype */ prototype->add_node_info(mmi::NodeInfo{ - "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT}); + "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER}); prototype->add_node_info(mmi::NodeInfo{ - "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR}); + "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH}); workflow_prototype_store->add_workflow_prototype(prototype); ClientMessageWorkflowInstanceCreate create_msg; create_msg.sender = std::string{"client-1"}; create_msg.local_workflow_instance_id = 0; - create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND; + create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH; channel.notify_observers( COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast(&create_msg)); @@ -320,19 +320,19 @@ TEST_F(WorkflowInstanceManagerTest, NodeInstanceDestroyRequestedOnWorkflowDestru TEST_F(WorkflowInstanceManagerTest, NodeInstanceDestroyRequestedOnClientDisconnection_p) { auto prototype = std::make_shared(); - prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); /* Add 2 nodes to the workflow prototype */ prototype->add_node_info(mmi::NodeInfo{ - "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT}); + "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER}); prototype->add_node_info(mmi::NodeInfo{ - "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR}); + "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH}); workflow_prototype_store->add_workflow_prototype(prototype); ClientMessageWorkflowInstanceCreate create_msg; create_msg.sender = std::string{"client-1"}; create_msg.local_workflow_instance_id = 0; - create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND; + create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH; channel.notify_observers( COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast(&create_msg)); @@ -347,21 +347,21 @@ TEST_F(WorkflowInstanceManagerTest, NodeInstanceDestroyRequestedOnClientDisconne TEST_F(WorkflowInstanceManagerTest, LinkCreatedIfLinkInfoIsProvided_p) { auto prototype = std::make_shared(); - prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); /* Add 2 nodes to the workflow prototype */ prototype->add_node_info(mmi::NodeInfo{ - "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT}); + "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER}); prototype->add_node_info(mmi::NodeInfo{ - "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR}); + "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH}); prototype->add_link_info(mmi::LinkInfo{ - "MIC", "AUDIO", "ASR", "AUDIO"}); + "SCREEN_ANALYZER", "SCREEN_INFO", "MATCH", "TEXT"}); workflow_prototype_store->add_workflow_prototype(prototype); ClientMessageWorkflowInstanceCreate create_msg; create_msg.sender = std::string{"client-1"}; create_msg.local_workflow_instance_id = 0; - create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND; + create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH; channel.notify_observers( COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast(&create_msg)); @@ -371,19 +371,19 @@ TEST_F(WorkflowInstanceManagerTest, LinkCreatedIfLinkInfoIsProvided_p) { TEST_F(WorkflowInstanceManagerTest, LinkNotCreatedIfLinkInfoIsNotProvided_n) { auto prototype = std::make_shared(); - prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); /* Add 2 nodes to the workflow prototype */ prototype->add_node_info(mmi::NodeInfo{ - "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT}); + "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER}); prototype->add_node_info(mmi::NodeInfo{ - "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR}); + "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH}); workflow_prototype_store->add_workflow_prototype(prototype); ClientMessageWorkflowInstanceCreate create_msg; create_msg.sender = std::string{"client-1"}; create_msg.local_workflow_instance_id = 0; - create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND; + create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH; channel.notify_observers( COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast(&create_msg)); @@ -393,21 +393,21 @@ TEST_F(WorkflowInstanceManagerTest, LinkNotCreatedIfLinkInfoIsNotProvided_n) { TEST_F(WorkflowInstanceManagerTest, LinkNotCreatedIfPortNameIsInvalid_n) { auto prototype = std::make_shared(); - prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); /* Add 2 nodes to the workflow prototype */ prototype->add_node_info(mmi::NodeInfo{ - "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT}); + "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER}); prototype->add_node_info(mmi::NodeInfo{ - "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR}); + "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH}); prototype->add_link_info(mmi::LinkInfo{ - "MIC", "UNKNOWN_PORT", "ASR", "AUDIO"}); + "SCREEN_ANALYZER", "UNKNOWN_PORT", "MATCH", "TEXT"}); workflow_prototype_store->add_workflow_prototype(prototype); ClientMessageWorkflowInstanceCreate create_msg; create_msg.sender = std::string{"client-1"}; create_msg.local_workflow_instance_id = 0; - create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND; + create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH; channel.notify_observers( COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast(&create_msg)); @@ -417,21 +417,21 @@ TEST_F(WorkflowInstanceManagerTest, LinkNotCreatedIfPortNameIsInvalid_n) { TEST_F(WorkflowInstanceManagerTest, LinkNotCreatedIfNodeNameIsInvalid_n) { auto prototype = std::make_shared(); - prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); /* Add 2 nodes to the workflow prototype */ prototype->add_node_info(mmi::NodeInfo{ - "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT}); + "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER}); prototype->add_node_info(mmi::NodeInfo{ - "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR}); + "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH}); prototype->add_link_info(mmi::LinkInfo{ - "UNKNOWN_NODE", "AUDIO", "ASR", "AUDIO"}); + "UNKNOWN_NODE", "SCREEN_INFO", "MATCH", "TEXT"}); workflow_prototype_store->add_workflow_prototype(prototype); ClientMessageWorkflowInstanceCreate create_msg; create_msg.sender = std::string{"client-1"}; create_msg.local_workflow_instance_id = 0; - create_msg.workflow_type = MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND; + create_msg.workflow_type = MMI_STANDARD_WORKFLOW_VOICE_TOUCH; channel.notify_observers( COMMUNICATION_CHANNEL_EVENT_TYPE::MESSAGE_RECEIVED, static_cast(&create_msg)); diff --git a/tests/mmi-manager/workflow-instance/mmi-workflow-instance-tests.cpp b/tests/mmi-manager/workflow-instance/mmi-workflow-instance-tests.cpp index 04e3280..257e895 100644 --- a/tests/mmi-manager/workflow-instance/mmi-workflow-instance-tests.cpp +++ b/tests/mmi-manager/workflow-instance/mmi-workflow-instance-tests.cpp @@ -35,17 +35,17 @@ public: mmi_primitive_value_destroy(value); auto prototype = std::make_shared(); - prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); /* Add 2 nodes to the workflow prototype */ prototype->add_node_info(mmi::NodeInfo{ - "MIC", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_MIC_AMBIENT}); + "SCREEN_ANALYZER", MMI_NODE_TYPE_SOURCE, MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER}); prototype->add_node_info(mmi::NodeInfo{ - "ASR", MMI_NODE_TYPE_PROCESSOR, MMI_NODE_PROCESSOR_TYPE_ASR}); + "MATCH", MMI_NODE_TYPE_LOGIC, MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH}); AttributeAssignmentInfo attribute_assignment_info; - attribute_assignment_info.attribute_name = "COMMAND"; - attribute_assignment_info.target_node_name = "ASR"; - attribute_assignment_info.target_attribute_name = "CANDIDATE"; + attribute_assignment_info.attribute_name = "CANDIDATES"; + attribute_assignment_info.target_node_name = "MATCH"; + attribute_assignment_info.target_attribute_name = "CANDIDATES"; prototype->add_attribute_assignment_info(attribute_assignment_info); prototype->add_attribute_default_value_info(attribute_default_value_info); @@ -140,19 +140,19 @@ public: NodeInstanceManagerDummy() { node_prototype_store = std::make_shared(); - auto mic_prototype = std::make_shared(); - mic_prototype->set_type(MMI_NODE_TYPE_SOURCE); - mic_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT); - PortInfo mic_audio{"AUDIO", MMI_PORT_TYPE_OUT, MMI_DATA_TYPE_AUDIO, "audio data"}; - mic_prototype->add_port_info(mic_audio); - node_prototype_store->add_node_prototype(mic_prototype); - - auto asr_prototype = std::make_shared(); - asr_prototype->set_type(MMI_NODE_TYPE_PROCESSOR); - asr_prototype->set_sub_type(MMI_NODE_PROCESSOR_TYPE_ASR); - PortInfo asr_audio{"AUDIO", MMI_PORT_TYPE_IN, MMI_DATA_TYPE_AUDIO, "audio data"}; - asr_prototype->add_port_info(asr_audio); - node_prototype_store->add_node_prototype(asr_prototype); + auto screen_analyzer_prototype = std::make_shared(); + screen_analyzer_prototype->set_type(MMI_NODE_TYPE_SOURCE); + screen_analyzer_prototype->set_sub_type(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER); + PortInfo screen_info{"SCREEN_INFO", MMI_PORT_TYPE_OUT, MMI_DATA_TYPE_TEXT, "screen info"}; + screen_analyzer_prototype->add_port_info(screen_info); + node_prototype_store->add_node_prototype(screen_analyzer_prototype); + + auto match_prototype = std::make_shared(); + match_prototype->set_type(MMI_NODE_TYPE_LOGIC); + match_prototype->set_sub_type(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); + PortInfo match_text{"TEXT", MMI_PORT_TYPE_IN, MMI_DATA_TYPE_TEXT, "text data"}; + match_prototype->add_port_info(match_text); + node_prototype_store->add_node_prototype(match_prototype); } virtual std::shared_ptr create_node_instance( @@ -211,7 +211,7 @@ public: void SetUp() override { workflow_instance = std::make_shared(); if (workflow_instance) { - workflow_instance->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + workflow_instance->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); workflow_instance->set_workflow_prototype_store(workflow_prototype_store); workflow_instance->set_plugin_module_proxy_provider(plugin_module_proxy_provider); @@ -236,12 +236,12 @@ TEST_F(WorkflowInstanceTest, WorkflowAttributePassedToNodeAttribute_p) { mmi_primitive_value_h value = nullptr; mmi_primitive_value_create_string("Hello", &value); mmi_attribute_h attribute = nullptr; - mmi_attribute_create(value, "COMMAND", &attribute); + mmi_attribute_create(value, "CANDIDATES", &attribute); EXPECT_TRUE(workflow_instance->set_attribute(attribute)); - EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_PROCESSOR); - EXPECT_TRUE(std::holds_alternative(g_last_node_attribute_set_history.m_sub_type)); - EXPECT_EQ(std::get(g_last_node_attribute_set_history.m_sub_type), - MMI_NODE_PROCESSOR_TYPE_ASR); + EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_LOGIC); + EXPECT_TRUE(std::holds_alternative(g_last_node_attribute_set_history.m_sub_type)); + EXPECT_EQ(std::get(g_last_node_attribute_set_history.m_sub_type), + MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); EXPECT_TRUE(g_last_node_attribute_set_history.m_attribute != nullptr); mmi_primitive_value_h history_item_value; @@ -267,7 +267,7 @@ TEST_F(WorkflowInstanceTest, WorkflowAttributePassedProperlyAfter2ndInitializati workflow_instance.reset(); workflow_instance = std::make_shared(); if (workflow_instance) { - workflow_instance->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + workflow_instance->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); workflow_instance->set_workflow_prototype_store(workflow_prototype_store); workflow_instance->set_plugin_module_proxy_provider(plugin_module_proxy_provider); @@ -280,10 +280,10 @@ TEST_F(WorkflowInstanceTest, WorkflowAttributePassedProperlyAfter2ndInitializati mmi_attribute_h attribute = nullptr; mmi_attribute_create(value, "COMMAND", &attribute); EXPECT_TRUE(workflow_instance->set_attribute(attribute)); - EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_PROCESSOR); - EXPECT_TRUE(std::holds_alternative(g_last_node_attribute_set_history.m_sub_type)); - EXPECT_EQ(std::get(g_last_node_attribute_set_history.m_sub_type), - MMI_NODE_PROCESSOR_TYPE_ASR); + EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_LOGIC); + EXPECT_TRUE(std::holds_alternative(g_last_node_attribute_set_history.m_sub_type)); + EXPECT_EQ(std::get(g_last_node_attribute_set_history.m_sub_type), + MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); EXPECT_TRUE(g_last_node_attribute_set_history.m_attribute != nullptr); mmi_primitive_value_h history_item_value; @@ -309,10 +309,10 @@ TEST_F(WorkflowInstanceTest, WorkflowDefaultAttributePassedToNodeAttribute_p) { EXPECT_NE(workflow_instance, nullptr); workflow_instance->initialize(); - EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_PROCESSOR); - EXPECT_TRUE(std::holds_alternative(g_last_node_attribute_set_history.m_sub_type)); - EXPECT_EQ(std::get(g_last_node_attribute_set_history.m_sub_type), - MMI_NODE_PROCESSOR_TYPE_ASR); + EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_LOGIC); + EXPECT_TRUE(std::holds_alternative(g_last_node_attribute_set_history.m_sub_type)); + EXPECT_EQ(std::get(g_last_node_attribute_set_history.m_sub_type), + MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); EXPECT_TRUE(g_last_node_attribute_set_history.m_attribute != nullptr); mmi_primitive_value_h history_item_value; @@ -341,10 +341,10 @@ TEST_F(WorkflowInstanceTest, WorkflowDefaultAttributePassedProperlyAfter2ndIniti EXPECT_NE(workflow_instance, nullptr); workflow_instance->initialize(); - EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_PROCESSOR); - EXPECT_TRUE(std::holds_alternative(g_last_node_attribute_set_history.m_sub_type)); - EXPECT_EQ(std::get(g_last_node_attribute_set_history.m_sub_type), - MMI_NODE_PROCESSOR_TYPE_ASR); + EXPECT_EQ(g_last_node_attribute_set_history.m_type, MMI_NODE_TYPE_LOGIC); + EXPECT_TRUE(std::holds_alternative(g_last_node_attribute_set_history.m_sub_type)); + EXPECT_EQ(std::get(g_last_node_attribute_set_history.m_sub_type), + MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH); EXPECT_TRUE(g_last_node_attribute_set_history.m_attribute != nullptr); char *name = nullptr; diff --git a/tests/mmi-manager/workflow-prototype/mmi-workflow-prototype-tests.cpp b/tests/mmi-manager/workflow-prototype/mmi-workflow-prototype-tests.cpp index 89c1d2d..61e97a3 100644 --- a/tests/mmi-manager/workflow-prototype/mmi-workflow-prototype-tests.cpp +++ b/tests/mmi-manager/workflow-prototype/mmi-workflow-prototype-tests.cpp @@ -43,7 +43,7 @@ TEST_F(WorkflowPrototypeTest, WorkflowPrototypeValidationSucceeds_p) { prototype->set_plugin_module_info( PluginModuleInfo{mmi_plugin_module_type_e::SHARED_LIBRARY, "test.so"}); - prototype->set_type(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + prototype->set_type(MMI_STANDARD_WORKFLOW_VOICE_TOUCH); ASSERT_TRUE(prototype->is_valid()); } diff --git a/tests/mmi/mmi-ipc-test.cpp b/tests/mmi/mmi-ipc-test.cpp index 7604dcb..eeede6a 100644 --- a/tests/mmi/mmi-ipc-test.cpp +++ b/tests/mmi/mmi-ipc-test.cpp @@ -64,7 +64,7 @@ TEST_F(MMIIpcTest, MMIFWIpcWorkflowInstanceCreationSuccess_p) { wait_until_connected(1000); mmi_workflow_instance_h instance = nullptr; - res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND, &instance); + res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_VOICE_TOUCH, &instance); EXPECT_EQ(res, MMI_ERROR_NONE); res = mmi_unset_state_changed_cb(state_changed_cb); @@ -84,7 +84,7 @@ TEST_F(MMIIpcTest, MMIFWIpcWorkflowInstanceSetAttributeSuccess_p) { wait_until_connected(1000); mmi_workflow_instance_h instance = nullptr; - res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND, &instance); + res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_VOICE_TOUCH, &instance); EXPECT_EQ(res, MMI_ERROR_NONE); mmi_attribute_h attribute = nullptr; @@ -113,7 +113,7 @@ TEST_F(MMIIpcTest, MMIFWIpcWorkflowInstanceActivateSuccess_p) { wait_until_connected(1000); mmi_workflow_instance_h instance = nullptr; - res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND, &instance); + res = mmi_standard_workflow_instance_create(MMI_STANDARD_WORKFLOW_VOICE_TOUCH, &instance); EXPECT_EQ(res, MMI_ERROR_NONE); res = mmi_workflow_instance_activate(instance); diff --git a/tests/mmi/workflow/mmi-workflow-test.cpp b/tests/mmi/workflow/mmi-workflow-test.cpp index 29b52bf..bd39ca3 100644 --- a/tests/mmi/workflow/mmi-workflow-test.cpp +++ b/tests/mmi/workflow/mmi-workflow-test.cpp @@ -3,9 +3,7 @@ #include #include -#include -#include -#include +#include #include "mmi-workflow-script-parser.h" @@ -33,23 +31,23 @@ public: void SetUp(void) override { mmi_workflow_create(&m_workflow); - mmi_workflow_set_type(m_workflow, MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + mmi_workflow_set_type(m_workflow, MMI_STANDARD_WORKFLOW_VOICE_TOUCH); - m_node_mic = nullptr; + m_node_screen_analyzer = nullptr; /* FIXME: node should be 'found' instead of 'created' */ - mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &m_node_mic); - mmi_workflow_node_add(m_workflow, "MIC", m_node_mic); - - m_node_asr = nullptr; - mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &m_node_asr); - mmi_workflow_node_add(m_workflow, "ASR", m_node_asr); + mmi_node_create_source(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER, &m_node_screen_analyzer); + mmi_workflow_node_add(m_workflow, "SCREEN_ANALYZER", m_node_screen_analyzer); m_node_match = nullptr; mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &m_node_match); mmi_workflow_node_add(m_workflow, "MATCH", m_node_match); - mmi_workflow_link_nodes_by_names(m_workflow, "MIC", "AUDIO", "ASR", "AUDIO"); - mmi_workflow_link_nodes_by_names(m_workflow, "ASR", "FINAL_RESULT", "MATCH", "TEXT"); + m_node_key_event = nullptr; + mmi_node_create_action(MMI_NODE_ACTION_TYPE_KEY_EVENT, &m_node_key_event); + mmi_workflow_node_add(m_workflow, "KEY_EVENT", m_node_key_event); + + mmi_workflow_link_nodes_by_names(m_workflow, "SCREEN_ANALYZER", "SCREEN_INFO", "MATCH", "TEXT"); + mmi_workflow_link_nodes_by_names(m_workflow, "MATCH", "MATCHED_CANDIDATE", "KEY_EVENT", "KEY_EVENT"); mmi_workflow_attribute_assign(m_workflow, "COMMANDS", "MATCH", "CANDIDATES"); @@ -57,17 +55,17 @@ public: } void TearDown(void) override { + mmi_node_destroy(m_node_key_event); mmi_node_destroy(m_node_match); - mmi_node_destroy(m_node_asr); - mmi_node_destroy(m_node_mic); + mmi_node_destroy(m_node_screen_analyzer); mmi_workflow_destroy(m_workflow); } mmi_workflow_h m_workflow{nullptr}; - mmi_node_h m_node_mic{nullptr}; - mmi_node_h m_node_asr{nullptr}; + mmi_node_h m_node_screen_analyzer{nullptr}; mmi_node_h m_node_match{nullptr}; + mmi_node_h m_node_key_event{nullptr}; }; static bool compare_workflow_prototype(mmi_workflow_h first, mmi_workflow_h second) { @@ -200,23 +198,23 @@ TEST_F(MMIWorkflowTest, TestCompareFunction_p1) { mmi_workflow_create(&workflow); - mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_WAKEUPLESS_COMMAND); + mmi_workflow_set_type(workflow, MMI_STANDARD_WORKFLOW_VOICE_TOUCH); - mmi_node_h node_mic = nullptr; + mmi_node_h node_screen_analyzer = nullptr; /* FIXME: node should be 'found' instead of 'created' */ - mmi_node_create_source(MMI_NODE_SOURCE_TYPE_MIC_AMBIENT, &node_mic); - mmi_workflow_node_add(workflow, "MIC", node_mic); - - mmi_node_h node_asr = nullptr; - mmi_node_create_processor(MMI_NODE_PROCESSOR_TYPE_ASR, &node_asr); - mmi_workflow_node_add(workflow, "ASR", node_asr); + mmi_node_create_source(MMI_NODE_SOURCE_TYPE_SCREEN_ANALYZER, &node_screen_analyzer); + mmi_workflow_node_add(workflow, "SCREEN_ANALYZER", node_screen_analyzer); mmi_node_h node_match = nullptr; mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_FIXED_STRING_MATCH, &node_match); mmi_workflow_node_add(workflow, "MATCH", node_match); - mmi_workflow_link_nodes_by_names(workflow, "MIC", "AUDIO", "ASR", "AUDIO"); - mmi_workflow_link_nodes_by_names(workflow, "ASR", "FINAL_RESULT", "MATCH", "TEXT"); + mmi_node_h node_key_event = nullptr; + mmi_node_create_action(MMI_NODE_ACTION_TYPE_KEY_EVENT, &node_key_event); + mmi_workflow_node_add(workflow, "KEY_EVENT", node_key_event); + + mmi_workflow_link_nodes_by_names(workflow, "SCREEN_ANALYZER", "SCREEN_INFO", "MATCH", "TEXT"); + mmi_workflow_link_nodes_by_names(workflow, "MATCH", "MATCHED_CANDIDATE", "ACTION", "KEY_EVENT"); mmi_workflow_attribute_assign(workflow, "COMMANDS", "MATCH", "CANDIDATES"); @@ -224,9 +222,9 @@ TEST_F(MMIWorkflowTest, TestCompareFunction_p1) { EXPECT_TRUE(compare_workflow_prototype(m_workflow, workflow)); + mmi_node_destroy(node_key_event); mmi_node_destroy(node_match); - mmi_node_destroy(node_asr); - mmi_node_destroy(node_mic); + mmi_node_destroy(node_screen_analyzer); mmi_workflow_destroy(workflow); } @@ -246,13 +244,13 @@ TEST_F(MMIWorkflowTest, TestCompareFunction_n1) { mmi_workflow_clone(m_workflow, &workflow); - mmi_node_h node_regex_match = nullptr; - mmi_node_create_logic(MMI_NODE_LOGIC_TYPE_REGEX_STRING_MATCH, &node_regex_match); - mmi_workflow_node_add(workflow, "REGEX_MATCH", node_regex_match); + mmi_node_h node_click_event = nullptr; + mmi_node_create_action(MMI_NODE_ACTION_TYPE_MOUSE_EVENT, &node_click_event); + mmi_workflow_node_add(workflow, "MOUSE_EVENT", node_click_event); EXPECT_FALSE(compare_workflow_prototype(m_workflow, workflow)); - mmi_node_destroy(node_regex_match); + mmi_node_destroy(node_click_event); mmi_workflow_destroy(workflow); } @@ -266,12 +264,12 @@ name : WAKEUPLESS_COMMAND @node-list [Source] MIC_AMBIENT as MIC -[Processor] ASR as ASR [Logic] FIXED_STRING_MATCH as MATCH +[Action] KEY_EVENT as KEY_EVENT @link-list -MIC.AUDIO -> ASR.AUDIO -ASR.FINAL_RESULT -> MATCH.TEXT +MIC.AUDIO -> MATCH.TEXT +MATCH.MATCHED_CANDIDATES -> KEY_EVENT.KEY_EVENT @attribute-list MATCH.CANDIDATES as COMMANDS