Add Intent understanding 43/264043/1
authorJihoon Kim <jihoon48.kim@samsung.com>
Wed, 18 Aug 2021 11:05:27 +0000 (20:05 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Mon, 13 Sep 2021 11:24:41 +0000 (20:24 +0900)
Change-Id: I68065cc3800da0794f517b67aabba7be1eafdb67
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
26 files changed:
meson.build
packaging/mmi-manager.spec
src/iu/data/default_rule.json [new file with mode: 0644]
src/iu/input_intent.cpp [new file with mode: 0644]
src/iu/input_intent.h [new file with mode: 0644]
src/iu/intent_understanding_engine.cpp [new file with mode: 0644]
src/iu/intent_understanding_engine.h [new file with mode: 0644]
src/iu/iu_rule.cpp [new file with mode: 0644]
src/iu/iu_rule.h [new file with mode: 0644]
src/iu/mmi_iu.cpp [new file with mode: 0644]
src/iu/mmi_iu.h [new file with mode: 0644]
src/iu/mmi_iu_error.h [new file with mode: 0644]
src/iu/mmi_iu_event.h [new file with mode: 0644]
src/iu/mmi_iu_log.h [new file with mode: 0644]
src/iu/output_intent.cpp [new file with mode: 0644]
src/iu/output_intent.h [new file with mode: 0644]
src/meson.build
tests/iu/intent_understanding_engine_rule_unittests.cpp [new file with mode: 0644]
tests/iu/intent_understanding_engine_unittests.cpp [new file with mode: 0644]
tests/iu/iu_rule_unittests.cpp [new file with mode: 0644]
tests/iu/main.cpp [new file with mode: 0644]
tests/iu/meson.build [new file with mode: 0644]
tests/iu/mmi_iu_feed_input_event_unittests.cpp [new file with mode: 0644]
tests/iu/mmi_iu_noinit_unittests.cpp [new file with mode: 0644]
tests/iu/mmi_iu_unittests.cpp [new file with mode: 0644]
tests/iu/output_intent_unittests.cpp [new file with mode: 0644]

index 26ca905..3ddad21 100644 (file)
@@ -15,3 +15,4 @@ pkgconfig = import('pkgconfig')
 
 subdir('src')
 subdir('tests')
+subdir('tests/iu')
index 3afd8e1..241e488 100644 (file)
@@ -16,6 +16,7 @@ BuildRequires:        pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(dlog)
 BuildRequires: pkgconfig(rpc-port)
 BuildRequires: pkgconfig(ecore)
+BuildRequires: pkgconfig(json-glib-1.0)
 
 #Build dependencies for tests
 BuildRequires: pkgconfig(gmock)
@@ -66,6 +67,7 @@ mkdir -p %{buildroot}%{_libdir}/provider
 %{_bindir}/mmi-manager
 %{_libdir}/provider/libmmi*.so
 %{_libdir}/fusion/libmmi*.so
+%{_datadir}/iu/*
 
 %files devel
 %manifest %{name}.manifest
@@ -78,4 +80,5 @@ mkdir -p %{buildroot}%{_libdir}/provider
 %defattr(-,root,root,-)
 %license COPYING
 %{_bindir}/mmi-manager-tests
+%{_bindir}/iu-tests
 
diff --git a/src/iu/data/default_rule.json b/src/iu/data/default_rule.json
new file mode 100644 (file)
index 0000000..ba8d522
--- /dev/null
@@ -0,0 +1,401 @@
+{
+    "IURule" : [
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "KeyInput",
+                    "Action" : "PressMicButton"
+                }
+            ],
+            "MMIStatus" : "Initiation",
+            "OutputIntent": {
+                "Action" : "WakeUp"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Gesture",
+                    "Action" : "ShowPalm"
+                }
+            ],
+            "MMIStatus": "Initiation",
+            "OutputIntent": {
+                "Action" : "WakeUp"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "KeyInput",
+                    "Action" : "PressUpButton"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveUp"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "KeyInput",
+                    "Action" : "PressDownButton"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveDown"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "KeyInput",
+                    "Action" : "PressRightButton"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveRight"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "KeyInput",
+                    "Action" : "PressLeftButton"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveLeft"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "MoveUp"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveUp"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "MoveDown"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveDown"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "MoveRight"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveRight"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "MoveLeft"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveLeft"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Gesture",
+                    "Action" : "HandUp"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveUp"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Gesture",
+                    "Action" : "HandDown"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveDown"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Gesture",
+                    "Action" : "HandRight"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveRight"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Gesture",
+                    "Action" : "HandLeft"
+                }
+            ],
+            "MMIStatus": "Exploration",
+            "OutputIntent": {
+                "Action" : "MoveLeft"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "KeyInput",
+                    "Action" : "PressOKButton"
+                }
+            ],
+            "MMIStatus": "Execution",
+            "OutputIntent": {
+                "Action" : "Execute"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "Execute"
+                }
+            ],
+            "MMIStatus": "Execution",
+            "OutputIntent": {
+                "Action" : "Execute"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "Play"
+                }
+            ],
+            "MMIStatus": "Execution",
+            "OutputIntent": {
+                "Action" : "Play"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "Yes"
+                }
+            ],
+            "MMIStatus": "Execution",
+            "OutputIntent": {
+                "Action" : "Yes"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "Yes"
+                }
+            ],
+            "MMIStatus": "Execution",
+            "OutputIntent": {
+                "Action" : "Execute"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "Yes"
+                }
+            ],
+            "MMIStatus": "Execution",
+            "OutputIntent": {
+                "Action" : "Execute"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Gesture",
+                    "Action" : "HandPush"
+                }
+            ],
+            "MMIStatus": "Execution",
+            "OutputIntent": {
+                "Action" : "Execute"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "KeyInput",
+                    "Action" : "PressOKButton"
+                }
+            ],
+            "MMIStatus": "Execution",
+            "OutputIntent": {
+                "Action" : "Execute"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "KeyInput",
+                    "Action" : "PressBackButton"
+                }
+            ],
+            "MMIStatus": "Execution",
+            "OutputIntent": {
+                "Action" : "Cancel"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "KeyInput",
+                    "Action" : "PressBackButton"
+                }
+            ],
+            "MMIStatus": "Feedback",
+            "OutputIntent": {
+                "Action" : "Cancel"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "Cancel"
+                }
+            ],
+            "MMIStatus": "Feedback",
+            "OutputIntent": {
+                "Action" : "Cancel"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "Back"
+                }
+            ],
+            "MMIStatus": "Feedback",
+            "OutputIntent": {
+                "Action" : "Cancel"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Gesture",
+                    "Action" : "WaveHandX"
+                }
+            ],
+            "MMIStatus": "Feedback",
+            "OutputIntent": {
+                "Action" : "Cancel"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Vision",
+                    "Action" : "OutOfVision"
+                }
+            ],
+            "MMIStatus": "Observation",
+            "OutputIntent": {
+                "Action" : "Pause"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "KeyInput",
+                    "Action" : "PressBackButton"
+                }
+            ],
+            "MMIStatus": "Termination",
+            "OutputIntent": {
+                "Action" : "Exit"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "Exit"
+                }
+            ],
+            "MMIStatus": "Termination",
+            "OutputIntent": {
+                "Action" : "Exit"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "Stop"
+                }
+            ],
+            "MMIStatus": "Termination",
+            "OutputIntent": {
+                "Action" : "Stop"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Voice",
+                    "Action" : "Terminate"
+                }
+            ],
+            "MMIStatus": "Termination",
+            "OutputIntent": {
+                "Action" : "Terminate"
+            }
+        },
+        {
+            "InputIntents" : [
+                {
+                    "Modality" : "Gesture",
+                    "Action" : "FlipPalm"
+                }
+            ],
+            "MMIStatus": "Termination",
+            "OutputIntent": {
+                "Action" : "Exit"
+            }
+        }
+    ]
+}
+
diff --git a/src/iu/input_intent.cpp b/src/iu/input_intent.cpp
new file mode 100644 (file)
index 0000000..5cdf95e
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+#include <unistd.h>
+#include <string>
+
+#include "input_intent.h"
+
+using namespace std;
+
+InputIntent::InputIntent()
+{
+
+}
+
+InputIntent::~InputIntent()
+{
+
+}
+
+void InputIntent::set_modality(string modality)
+{
+    this->modality = modality;
+}
+
+string InputIntent::get_modality()
+{
+    return modality;
+}
+
+void InputIntent::set_action(string action)
+{
+    this->action = action;
+}
+
+string InputIntent::get_action()
+{
+    return action;
+}
+
+void InputIntent::set_input_time(int time)
+{
+    input_time = time;
+}
+
+int InputIntent::get_input_time()
+{
+    return input_time;
+}
+
+void InputIntent::set_input_duration(int duration)
+{
+    input_duration = duration;
+}
+
+int InputIntent::get_input_duration()
+{
+    return input_duration;
+}
+
+bool InputIntent::match_intent(const InputIntent &other)
+{
+    if (this->modality == other.modality &&
+        this->action == other.action)
+        return true;
+
+    return false;
+}
diff --git a/src/iu/input_intent.h b/src/iu/input_intent.h
new file mode 100644 (file)
index 0000000..0280c37
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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 __INPUT_INTENT_H__
+#define __INPUT_INTENT_H__
+
+#include <unistd.h>
+#include <string>
+
+using namespace std;
+
+class InputIntent {
+public:
+    InputIntent();
+    virtual ~InputIntent();
+
+    void set_modality(string modality);
+    string get_modality();
+
+    void set_action(string modality);
+    string get_action();
+
+    void set_input_time(int time);
+    int get_input_time();
+
+    void set_input_duration(int duration);
+    int get_input_duration();
+
+    bool match_intent(const InputIntent &other);
+
+private:
+    string modality;
+    string action;
+    int input_time = 0;
+    int input_duration = 0;
+};
+
+#endif /* __INPUT_INTENT_H__ */
diff --git a/src/iu/intent_understanding_engine.cpp b/src/iu/intent_understanding_engine.cpp
new file mode 100644 (file)
index 0000000..e6dca32
--- /dev/null
@@ -0,0 +1,454 @@
+/*
+ * 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.
+ */
+
+#include <unistd.h>
+#include <string>
+#include <json-glib/json-glib.h>
+#include <dlog.h>
+#include <unordered_map>
+
+using namespace std;
+
+#include "mmi_iu_log.h"
+#include "intent_understanding_engine.h"
+#include "input_intent.h"
+#include "output_intent.h"
+#include "mmi-common.h"
+#include "mmi_iu_event.h"
+
+static unordered_map<int, string> key_action_map
+    = { { MMI_EVENT_KEYEVENT_MIC,   "Mic" },
+        { MMI_EVENT_KEYEVENT_UP,    "Up" },
+        { MMI_EVENT_KEYEVENT_DOWN,  "Down" },
+        { MMI_EVENT_KEYEVENT_LEFT,  "Left" },
+        { MMI_EVENT_KEYEVENT_RIGHT, "Right" },
+        { MMI_EVENT_KEYEVENT_SELECT, "OK" },
+        { MMI_EVENT_KEYEVENT_BACK,  "Back" },
+      };
+
+static unordered_map<int, string> voice_action_map
+    = { { MMI_EVENT_VOICE_UP,       "MoveUp" },
+        { MMI_EVENT_VOICE_DOWN,     "MoveDown" },
+        { MMI_EVENT_VOICE_LEFT,     "MoveLeft" },
+        { MMI_EVENT_VOICE_RIGHT,    "MoveRight" },
+        { MMI_EVENT_VOICE_CANCEL,   "Cancel" },
+        { MMI_EVENT_VOICE_PLAY,     "Play" },
+        { MMI_EVENT_VOICE_YES,      "Yes" },
+        { MMI_EVENT_VOICE_EXECUTE,  "Execute" },
+        { MMI_EVENT_VOICE_BACK,     "Back" },
+        { MMI_EVENT_VOICE_EXIT,     "Exit" },
+        { MMI_EVENT_VOICE_STOP,     "Stop" },
+        { MMI_EVENT_VOICE_TERMINATE, "Terminate" },
+      };
+
+static unordered_map<int, string> gesture_action_map
+    = { { MMI_EVENT_GESTURE_SWIPE_UP,   "HandUp" },
+        { MMI_EVENT_GESTURE_SWIPE_DOWN, "HandDown" },
+        { MMI_EVENT_GESTURE_SWIPE_LEFT, "HandLeft" },
+        { MMI_EVENT_GESTURE_SWIPE_RIGHT, "HandRight" },
+        { MMI_EVENT_GESTURE_PUSH,       "HandPush" },
+        { MMI_EVENT_GESTURE_WAVEHANDX,  "WaveHandX" },
+        { MMI_EVENT_GESTURE_FLIPPALM,   "FlipPalm" },
+        { MMI_EVENT_GESTURE_SHOWPALM,   "ShowPalm" }
+      };
+
+static unordered_map<int, string> vision_action_map
+    = { { MMI_EVENT_VISION_MOVE_AWAY, "OutOfVision" }
+      };
+
+IntentUnderstandingEngine::IntentUnderstandingEngine()
+{
+}
+
+IntentUnderstandingEngine::~IntentUnderstandingEngine()
+{
+
+}
+
+void IntentUnderstandingEngine::set_app_state(const char *state)
+{
+     if (string(state) == "Initiation")
+        application_state = MMI_STATE_INITIATION;
+    else if (string(state) == "Exploration")
+        application_state = MMI_STATE_EXPLORATION;
+    else if (string(state) == "Execution")
+        application_state = MMI_STATE_EXECUTION;
+    else if (string(state) == "Feedback")
+        application_state = MMI_STATE_FEEDBACK;
+    else if (string(state) == "Observation")
+        application_state = MMI_STATE_OBSERVATION;
+    else if (string(state) == "Termination")
+        application_state = MMI_STATE_TERMINATION;
+}
+
+void IntentUnderstandingEngine::set_app_state(mmi_state appstate)
+{
+    application_state = appstate;
+}
+
+mmi_state IntentUnderstandingEngine::get_app_state()
+{
+    return application_state;
+}
+
+bool IntentUnderstandingEngine::parse_json_data(JsonParser *parser)
+{
+    JsonNode *root = NULL;
+
+    JsonObject *root_obj = NULL;
+    JsonObject *output_intent_obj = NULL;
+    JsonObject *input_intent_obj = NULL;
+    JsonObject *iu_rule_arr_obj = NULL;
+
+    JsonArray *input_intent_array = NULL;
+    JsonArray *iu_rule_array = NULL;
+
+    const gchar *status = NULL;
+    const gchar *output_action = NULL;
+    const gchar *modality = NULL;
+    const gchar *action = NULL;
+
+    int arr_len = 0;
+
+    root = json_parser_get_root(parser);
+    if (root == NULL) {
+        _E("failed to get root");
+        return false;
+    }
+
+    root_obj = json_node_get_object(root);
+    if (root_obj == NULL) {
+        _E("failed to get object");
+        return false;
+    }
+
+    iu_rule_array = json_object_get_array_member(root_obj, "IURule");
+    if (iu_rule_array) {
+        iu_rule_list.clear();
+
+        arr_len = json_array_get_length(iu_rule_array);
+
+        for (int i = 0; i < arr_len; i++) {
+            IntentUnderstandingRule iu_rule;
+            iu_rule_arr_obj = json_array_get_object_element(iu_rule_array, i);
+            input_intent_array = json_object_get_array_member(iu_rule_arr_obj, "InputIntents");
+
+            if (input_intent_array) {
+                int input_intent_list_len = json_array_get_length(input_intent_array);
+                for (int j = 0; j < input_intent_list_len; j++) {
+                    input_intent_obj = json_array_get_object_element(input_intent_array, j);
+
+                    modality = json_object_get_string_member(input_intent_obj, "Modality");
+                    action = json_object_get_string_member(input_intent_obj, "Action");
+
+                    InputIntent intent;
+                    intent.set_modality(string(modality));
+                    intent.set_action(string(action));
+
+                    iu_rule.add_input_intent(intent);
+                }
+            }
+
+            status = json_object_get_string_member(iu_rule_arr_obj, "MMIStatus");
+            iu_rule.set_app_state(status);
+
+            output_intent_obj = json_object_get_object_member(iu_rule_arr_obj, "OutputIntent");
+            output_action = json_object_get_string_member(output_intent_obj, "Action");
+
+            OutputIntent oi;
+            oi.set_action(output_action);
+
+            iu_rule.set_output_intent(oi);
+
+            iu_rule_list.push_back(iu_rule);
+        }
+    }
+
+    return true;
+}
+
+bool IntentUnderstandingEngine::set_rule_json_file(const char *json_file_path)
+{
+    if (!json_file_path)
+        return false;
+
+    JsonParser *parser = json_parser_new();
+    GError *err_msg = NULL;
+    bool ret = true;
+
+    json_parser_load_from_file(parser, (char *)json_file_path, &err_msg);
+    if (err_msg) {
+        _E("failed to load json file. error message: %s", err_msg->message);
+        ret = false;
+        goto cleanup;
+    }
+
+    ret = parse_json_data(parser);
+
+cleanup:
+    if (err_msg)
+        g_error_free(err_msg);
+
+    if (parser)
+        g_object_unref(parser);
+
+    return ret;
+}
+
+bool IntentUnderstandingEngine::set_rule_json_data(const char *json_data)
+{
+    if (!json_data)
+        return false;
+
+    JsonParser *parser = json_parser_new();
+    GError *err_msg = NULL;
+    bool ret = true;
+
+    json_parser_load_from_data(parser, (char *)json_data, -1, &err_msg);
+    if (err_msg) {
+        _E("failed to load json file. error message: %s", err_msg->message);
+        ret = false;
+        goto cleanup;
+    }
+
+    parse_json_data(parser);
+
+cleanup:
+    if (err_msg)
+        g_error_free(err_msg);
+
+    if (parser)
+        g_object_unref(parser);
+
+    return ret;
+}
+
+bool IntentUnderstandingEngine::set_input_intent_json_data(const char *json_data)
+{
+    JsonParser *parser = json_parser_new();
+    GError *err_msg = NULL;
+    JsonNode *root = NULL;
+    JsonObject *root_obj = NULL;
+    JsonArray *input_intent_array = NULL;
+    JsonObject *arr_obj;
+    const gchar *modality_type;
+    const gchar *action;
+
+    bool ret = true;
+    int arr_len = 0;
+    int input_time = 0, input_duration = 0;
+
+    json_parser_load_from_data(parser, (char *)json_data, -1, &err_msg);
+    if (err_msg) {
+        _E("failed to load json file. error message: %s", err_msg->message);
+        ret = false;
+        goto cleanup;
+    }
+
+    root = json_parser_get_root(parser);
+    if (root == NULL) {
+        _E("failed to get root");
+        ret = false;
+        goto cleanup;
+    }
+
+    root_obj = json_node_get_object(root);
+    if (root_obj == NULL) {
+        _E("failed to get object");
+        ret = false;
+        goto cleanup;
+    }
+
+    input_intent_array = json_object_get_array_member(root_obj, "InputIntents");
+    if (input_intent_array) {
+        input_intent_list.clear();
+
+        arr_len = json_array_get_length(input_intent_array);
+
+        for (int i = 0; i < arr_len; i++) {
+            input_time = 0, input_duration = 0;
+            arr_obj = json_array_get_object_element(input_intent_array, i);
+            modality_type = json_object_get_string_member(arr_obj, "Modality");
+            action = json_object_get_string_member(arr_obj, "Action");
+
+            if (json_object_has_member(arr_obj, "Time"))
+                input_time = json_object_get_int_member(arr_obj, "Time");
+
+            if (json_object_has_member(arr_obj, "Duration"))
+                input_duration = json_object_get_int_member(arr_obj, "Duration");
+
+            _I("### modality type: %s, action: %s, time: %d, duration: %d ###\n", modality_type, action, input_time, input_duration);
+
+            InputIntent intent;
+            intent.set_modality(string(modality_type));
+            intent.set_action(string(action));
+            intent.set_input_time(input_time);
+            intent.set_input_duration(input_duration);
+
+            input_intent_list.push_back(intent);
+        }
+    }
+
+cleanup:
+    if (err_msg)
+        g_error_free(err_msg);
+
+    if (parser)
+        g_object_unref(parser);
+
+    return ret;
+}
+
+string IntentUnderstandingEngine::convert_key_event(int type, int keycode)
+{
+    string action;
+    string button_name;
+
+    if (type == MMI_EVENT_KEY_DOWN)
+    {
+        button_name = key_action_map[keycode];
+        if (!button_name.empty()) {
+           action = "Press" + button_name + "Button";
+        }
+    }
+
+    return action;
+}
+
+string IntentUnderstandingEngine::convert_voice_event(int type)
+{
+    string action = voice_action_map[type];
+    return action;
+}
+
+string IntentUnderstandingEngine::convert_gesture_event(int type)
+{
+    string action = gesture_action_map[type];
+    return action;
+}
+
+string IntentUnderstandingEngine::convert_vision_event(int type)
+{
+    string action = vision_action_map[type];
+    return action;
+}
+
+bool IntentUnderstandingEngine::set_input_event(int type, void *event)
+{
+    InputIntent intent;
+    string modality_type;
+    string action;
+
+    mmi_provider_event_key *key_event;
+    mmi_provider_event_voice *voice_event;
+    mmi_provider_event_gesture *gesture_event;
+    mmi_provider_event_vision *vision_event;
+
+    switch (type) {
+        case MMI_EVENT_KEY_DOWN:
+            modality_type = "KeyInput";
+            key_event = (mmi_provider_event_key *)event;
+            action = convert_key_event(type, key_event->keycode);
+            break;
+        case MMI_EVENT_VOICE:
+            modality_type = "Voice";
+            voice_event = (mmi_provider_event_voice *)event;
+            action = convert_voice_event(voice_event->type);
+            break;
+        case MMI_EVENT_GESTURE:
+            modality_type = "Gesture";
+            gesture_event = (mmi_provider_event_gesture *)event;
+            action = convert_gesture_event(gesture_event->type);
+            break;
+        case MMI_EVENT_VISION:
+            modality_type = "Vision";
+            vision_event = (mmi_provider_event_vision *)event;
+            action = convert_vision_event(vision_event->type);
+            break;
+        default:
+            break;
+    }
+
+    intent.set_modality(modality_type);
+    intent.set_action(action);
+
+    input_intent_list.push_back(intent);
+
+    return !action.empty();
+}
+
+string IntentUnderstandingEngine::get_output_intent_json_data()
+{
+    OutputIntent oi;
+    string output_json_text;
+
+    oi.set_action(get_output_intent_action());
+
+    output_json_text = oi.get_output_intent_text();
+
+    return output_json_text;
+}
+
+bool IntentUnderstandingEngine::match_input_intent(IntentUnderstandingRule iu_rule)
+{
+    unsigned int input_intent_size = input_intent_list.size();
+    unsigned int match_count = 0;
+
+    if (iu_rule.get_input_intent_size() != input_intent_size)
+        return false;
+
+    for (InputIntent it : input_intent_list)
+    {
+        if (iu_rule.find_input_intent(it))
+        {
+            match_count++;
+            break;
+        }
+    }
+
+    return input_intent_size == match_count ? true : false;
+}
+
+string IntentUnderstandingEngine::get_output_intent_action()
+{
+    if (iu_rule_list.empty()) {
+        _E("No intent understanding rule data");
+        return string("");
+    }
+
+    for (IntentUnderstandingRule iu_rule : iu_rule_list)
+    {
+        if (match_input_intent(iu_rule) && iu_rule.get_app_state() == application_state) {
+            string output_action = iu_rule.get_output_intent().get_action();
+            _D("Output action : %s\n", output_action.c_str());
+            return output_action;
+        }
+    }
+
+    return string("");
+}
+
+void IntentUnderstandingEngine::init_input_buffer()
+{
+    input_intent_list.clear();
+}
diff --git a/src/iu/intent_understanding_engine.h b/src/iu/intent_understanding_engine.h
new file mode 100644 (file)
index 0000000..0675607
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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 __INTENT_UNDERSTANDING_ENGINE__
+#define __INTENT_UNDERSTANDING_ENGINE__
+
+#include <unistd.h>
+#include <string>
+#include <list>
+
+#include "input_intent.h"
+#include "mmi-common.h"
+#include "iu_rule.h"
+
+using namespace std;
+
+class IntentUnderstandingEngine {
+public:
+    IntentUnderstandingEngine();
+    virtual ~IntentUnderstandingEngine();
+
+    bool set_rule_json_file(const char *json_file_path);
+    bool set_rule_json_data(const char *json_data);
+
+    bool set_input_intent_json_data(const char *json_data);
+    bool set_input_event(int type, void *event);
+
+    string get_output_intent_json_data();
+    string get_output_intent_action();
+
+    void set_app_state(mmi_state appstate);
+    void set_app_state(const char *state);
+
+    void init_input_buffer();
+
+    mmi_state get_app_state();
+
+private:
+    bool match_input_intent(IntentUnderstandingRule iu_rule);
+
+    bool parse_json_data(JsonParser *parser);
+
+    string convert_key_event(int type, int keycode);
+    string convert_voice_event(int type);
+    string convert_gesture_event(int type);
+    string convert_vision_event(int type);
+
+    list<IntentUnderstandingRule> iu_rule_list;
+    list<InputIntent> input_intent_list;
+
+    mmi_state application_state = MMI_STATE_INITIATION;
+};
+
+#endif /* __INTENT_UNDERSTANDING_ENGINE__ */
diff --git a/src/iu/iu_rule.cpp b/src/iu/iu_rule.cpp
new file mode 100644 (file)
index 0000000..2e5834c
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+#include <unistd.h>
+#include <string>
+
+#include "input_intent.h"
+#include "iu_rule.h"
+
+using namespace std;
+
+IntentUnderstandingRule::IntentUnderstandingRule()
+{
+
+}
+
+IntentUnderstandingRule::~IntentUnderstandingRule()
+{
+
+}
+
+void IntentUnderstandingRule::set_app_state(const char* state)
+{
+    if (string(state) == "Initiation")
+        app_state = MMI_STATE_INITIATION;
+    else if (string(state) == "Exploration")
+        app_state = MMI_STATE_EXPLORATION;
+    else if (string(state) == "Execution")
+        app_state = MMI_STATE_EXECUTION;
+    else if (string(state) == "Feedback")
+        app_state = MMI_STATE_FEEDBACK;
+    else if (string(state) == "Observation")
+        app_state = MMI_STATE_OBSERVATION;
+    else if (string(state) == "Termination")
+        app_state = MMI_STATE_TERMINATION;
+}
+
+mmi_state  IntentUnderstandingRule::get_app_state()
+{
+    return app_state;
+}
+
+void IntentUnderstandingRule::set_output_intent(const OutputIntent &output_intent)
+{
+    this->output_intent = output_intent;
+}
+
+OutputIntent IntentUnderstandingRule::get_output_intent()
+{
+    return this->output_intent;
+}
+
+void IntentUnderstandingRule::add_input_intent(const InputIntent &intent)
+{
+    input_intent_list.push_back(intent);
+}
+
+bool IntentUnderstandingRule::find_input_intent(InputIntent intent)
+{
+    for (InputIntent it : input_intent_list)
+    {
+        if (it.match_intent(intent))
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+unsigned int IntentUnderstandingRule::get_input_intent_size()
+{
+    return input_intent_list.size();
+}
diff --git a/src/iu/iu_rule.h b/src/iu/iu_rule.h
new file mode 100644 (file)
index 0000000..45dd0c7
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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 __IU_RULE__
+#define __IU_RULE__
+
+#include <unistd.h>
+#include <string>
+#include <list>
+
+#include "input_intent.h"
+#include "output_intent.h"
+#include "mmi-common.h"
+
+using namespace std;
+
+class IntentUnderstandingRule {
+public:
+    IntentUnderstandingRule();
+    virtual ~IntentUnderstandingRule();
+
+    void set_app_state(const char* state);
+    mmi_state get_app_state();
+
+    void set_output_intent(const OutputIntent &output_intent);
+    OutputIntent get_output_intent();
+
+    void add_input_intent(const InputIntent &intent);
+    bool find_input_intent(InputIntent intent);
+    unsigned int get_input_intent_size();
+
+private:
+    list<InputIntent> input_intent_list;
+
+    OutputIntent output_intent;
+
+    mmi_state app_state;
+};
+
+#endif /* __IU_RULE__ */
diff --git a/src/iu/mmi_iu.cpp b/src/iu/mmi_iu.cpp
new file mode 100644 (file)
index 0000000..c9cb68b
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <dlog.h>
+#include <string>
+#include <list>
+#include <json-glib/json-glib.h>
+
+#include "mmi_iu.h"
+#include "mmi_iu_log.h"
+#include "output_intent.h"
+#include "input_intent.h"
+#include "intent_understanding_engine.h"
+#include "mmi-common.h"
+#include "mmi_iu_event.h"
+
+using namespace std;
+
+static mmi_state g_app_state = MMI_STATE_INITIATION;
+static mmi_iu_output_intent_received_cb iu_output_intent_received_callback = NULL;
+static void *iu_output_intent_user_data = NULL;
+
+static bool initialized = false;
+
+static string g_system_app_id;
+static string g_focus_app_id;
+
+static IntentUnderstandingEngine *iu_engine = NULL;
+
+#define DEFAULT_RULE_FILE "/usr/share/iu/default_rule.json"
+
+static void init()
+{
+    initialized = true;
+
+    g_app_state = MMI_STATE_INITIATION;
+
+    iu_output_intent_received_callback = NULL;
+
+    iu_output_intent_user_data = NULL;
+
+    g_system_app_id = "";
+    g_focus_app_id = "";
+}
+
+EXPORT_API int mmi_iu_init()
+{
+    init();
+
+    iu_engine = new IntentUnderstandingEngine();
+
+    if (!iu_engine)
+        return MMI_IU_ERROR_OUT_OF_MEMORY;
+
+    int ret = mmi_iu_set_rule_filepath(DEFAULT_RULE_FILE);
+
+    return ret;
+}
+
+EXPORT_API int mmi_iu_shutdown()
+{
+    init();
+
+    if (iu_engine) {
+        delete iu_engine;
+        iu_engine = NULL;
+    }
+
+    if (!initialized)
+        return MMI_IU_ERROR_NOT_INITIALIZED;
+
+    initialized = false;
+
+    return MMI_IU_ERROR_NONE;
+}
+
+EXPORT_API int mmi_iu_set_rule_filepath(const char *filepath)
+{
+    if (!initialized || !iu_engine)
+        return MMI_IU_ERROR_NOT_INITIALIZED;
+
+    if (!iu_engine->set_rule_json_file(filepath)) {
+        _W("Failed to set rule data");
+        return MMI_IU_ERROR_OPERATION_FAILED;
+    }
+
+    return MMI_IU_ERROR_NONE;
+}
+
+static void fire_output_intent_callback(const char *app_id, const char *output_intent)
+{
+    if (iu_output_intent_received_callback)
+        iu_output_intent_received_callback(app_id, output_intent, iu_output_intent_user_data);
+    else
+        _D("No output intent receive callback\n");
+}
+
+static void fire_output_intent(const char *app_id, const char *json_output_intent)
+{
+    if (g_system_app_id == string(app_id)) {
+        fire_output_intent_callback(app_id, json_output_intent);
+    }
+    else {
+        if (g_focus_app_id.empty()) {
+            fire_output_intent_callback(app_id, json_output_intent);
+        }
+        else {
+            if (g_focus_app_id == string(app_id)) {
+                fire_output_intent_callback(app_id, json_output_intent);
+            }
+            else {
+                _I("different focus app\n");
+            }
+        }
+    }
+}
+
+EXPORT_API int mmi_iu_feed_intent(const char *app_id, const char *json_data)
+{
+    if (!app_id || !json_data) {
+        _W("[ERROR] Invalid parameter");
+        return MMI_IU_ERROR_INVALID_PARAMETER;
+    }
+
+    if (!initialized) {
+        _W("[ERROR] Not initialized");
+        return MMI_IU_ERROR_NOT_INITIALIZED;
+    }
+
+    if (iu_engine)
+        if (!iu_engine->set_input_intent_json_data(json_data))
+            return MMI_IU_ERROR_OPERATION_FAILED;
+
+    _I("app state: %d\n", g_app_state);
+
+    string json_output_intent;
+    if (iu_engine) {
+        iu_engine->set_app_state(g_app_state);
+
+        json_output_intent = iu_engine->get_output_intent_json_data();
+        _I("output intent : %s\n", json_output_intent.c_str());
+    }
+
+    if (json_output_intent.empty())
+        return MMI_IU_ERROR_OPERATION_FAILED;
+
+    fire_output_intent(app_id, json_output_intent.c_str());
+
+    return MMI_IU_ERROR_NONE;
+}
+
+EXPORT_API int mmi_iu_feed_input_event(const char *app_id, int type, void *event)
+{
+    if (!app_id || !event) {
+        _W("[ERROR] Invalid parameter");
+        return MMI_IU_ERROR_INVALID_PARAMETER;
+    }
+
+    if (!initialized) {
+        _W("[ERROR] Not initialized");
+        return MMI_IU_ERROR_NOT_INITIALIZED;
+    }
+
+    if (iu_engine)
+        if (!iu_engine->set_input_event(type, event))
+            return MMI_IU_ERROR_OPERATION_FAILED;
+
+    _I("app state: %d\n", g_app_state);
+
+    string json_output_intent;
+    if (iu_engine) {
+        iu_engine->set_app_state(g_app_state);
+
+        json_output_intent = iu_engine->get_output_intent_json_data();
+        _I("output intent : %s\n", json_output_intent.c_str());
+    }
+
+    if (json_output_intent.empty())
+        return MMI_IU_ERROR_OPERATION_FAILED;
+
+    fire_output_intent(app_id, json_output_intent.c_str());
+
+    iu_engine->init_input_buffer();
+
+    return MMI_IU_ERROR_NONE;
+}
+
+EXPORT_API int mmi_iu_set_output_intent_received_callback(mmi_iu_output_intent_received_cb callback, void *user_data)
+{
+    if (!callback) {
+        _W("[ERROR] Invalid parameter");
+        return MMI_IU_ERROR_INVALID_PARAMETER;
+    }
+
+    if (!initialized) {
+        _W("[ERROR] Not initialized");
+        return MMI_IU_ERROR_NOT_INITIALIZED;
+    }
+
+    iu_output_intent_received_callback = callback;
+    iu_output_intent_user_data = user_data;
+
+    return MMI_IU_ERROR_NONE;
+}
+
+EXPORT_API int mmi_iu_unset_output_intent_received_callback()
+{
+    if (!initialized) {
+        _W("[ERROR] Not initialized");
+        return MMI_IU_ERROR_NOT_INITIALIZED;
+    }
+
+    iu_output_intent_received_callback = NULL;
+    iu_output_intent_user_data = NULL;
+
+    return MMI_IU_ERROR_NONE;
+}
+
+EXPORT_API int mmi_iu_set_app_state(mmi_state app_state)
+{
+    if (!initialized) {
+        _W("[ERROR] Not initialized");
+        return MMI_IU_ERROR_NOT_INITIALIZED;
+    }
+
+    g_app_state = app_state;
+
+    return MMI_IU_ERROR_NONE;
+}
+
+EXPORT_API int mmi_iu_set_focus_app_id(const char *app_id)
+{
+    if (!app_id) {
+        _W("[ERROR] Invalid parameter");
+        return MMI_IU_ERROR_INVALID_PARAMETER;
+    }
+
+    if (!initialized) {
+        _W("[ERROR] Not initialized");
+        return MMI_IU_ERROR_NOT_INITIALIZED;
+    }
+
+    g_focus_app_id = string(app_id);
+
+    return MMI_IU_ERROR_NONE;
+}
+
+EXPORT_API int mmi_iu_set_system_app_id(const char *system_app_id)
+{
+    if (!system_app_id) {
+        _W("[ERROR] Invalid parameter");
+        return MMI_IU_ERROR_INVALID_PARAMETER;
+    }
+
+    if (!initialized) {
+        _W("[ERROR] Not initialized");
+        return MMI_IU_ERROR_NOT_INITIALIZED;
+    }
+
+    g_system_app_id = string(system_app_id);
+
+    return MMI_IU_ERROR_NONE;
+}
diff --git a/src/iu/mmi_iu.h b/src/iu/mmi_iu.h
new file mode 100644 (file)
index 0000000..a3c15ae
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * 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 __TIZEN_UIX_MMI_IU_H__
+#define __TIZEN_UIX_MMI_IU_H__
+
+#include "mmi_iu_error.h"
+#include "mmi-common.h"
+#include "mmi_iu_event.h"
+
+/**
+ * @file iu.h
+ * @brief This file contains Intent Understanding APIs and related enumeration.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup UIX_MMI_IU_MODULE
+ * @{
+ */
+
+/**
+ * @brief The callback function to receive output intent
+ * @param[in] target_app_id The app ID to process output intent (focused app or system app id)
+ * @param[in] json_data The output intent data with json format
+ * @param[in] user_data The user data passed from the callback function
+ */
+typedef void (*mmi_iu_output_intent_received_cb)(const char *target_app_id, const char *json_data, void *user_data);
+
+/**
+ * @brief Initialize Intent Understanding library
+ *
+ * @return int MMI_IU_ERROR_NONE on success
+ */
+int mmi_iu_init();
+
+/**
+ * @brief Shutdown Intent Understanding library
+ *
+ * @return int MMI_IU_ERROR_NONE on success
+ */
+int mmi_iu_shutdown();
+
+/**
+ * @brief Set file path of json rule data
+ * @param[in] filepath file path of json rule data
+ *
+ * @return int MMI_IU_ERROR_NONE on success
+ */
+int mmi_iu_set_rule_filepath(const char *filepath);
+
+/**
+ * @brief Feed input intent
+ * @remark The result can be received by the callback registered by mmi_iu_set_output_intent_received_callback().
+ * @param[in] app_id The app ID that input event occurred
+ */
+int mmi_iu_feed_intent(const char *app_id, const char *json_data);
+
+/**
+ * @brief Feed raw input event
+ * @remark The result can be received by the callback registered by mmi_iu_set_output_intent_received_callback().
+ * @param[in] app_id The app ID that input event occurred
+ * @param[in] type The input event type (key, voice, gesture, ..)
+ * @param[in] event The event information
+ */
+int mmi_iu_feed_input_event(const char *app_id, int type, void *event);
+
+/**
+ * @brief Register the callback function to receive output intent
+ * @param callback The (callback) function to be called when output intent is generated.
+ * @param data The data pointer to be passed to @p callback
+ */
+int mmi_iu_set_output_intent_received_callback(mmi_iu_output_intent_received_cb callback, void *user_data);
+
+/**
+ * @brief Unregister the callback function to receive output intent
+ */
+int mmi_iu_unset_output_intent_received_callback();
+
+/**
+ * @brief Set app state
+ * @param app_state The application state
+ */
+int mmi_iu_set_app_state(mmi_state app_state);
+
+/**
+ * @brief Set system application ID
+ * @param[in] system_app_id system application ID
+ */
+int mmi_iu_set_system_app_id(const char *system_app_id);
+
+/**
+ * @brief Set focus app ID
+ * @param[in] app_id The focus application ID
+ */
+int mmi_iu_set_focus_app_id(const char *app_id);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_MMI_IU_H__ */
diff --git a/src/iu/mmi_iu_error.h b/src/iu/mmi_iu_error.h
new file mode 100644 (file)
index 0000000..7f1410a
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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 __TIZEN_UIX_MMI_IU_ERROR_H__
+#define __TIZEN_UIX_MMI_IU_ERROR_H__
+
+#include <tizen.h>
+
+/**
+ * @file MMI_IU_ERROR.h
+ * @brief This file contains intent understanding error enumeration.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup UIX_IU_COMMON_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for intent understanding function error.
+ *
+ * @since_tizen 6.5
+ */
+typedef enum {
+    MMI_IU_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+    MMI_IU_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+    MMI_IU_ERROR_NOT_INITIALIZED = TIZEN_ERROR_UNKNOWN - 1, /**< Not initialized */
+    MMI_IU_ERROR_OPERATION_FAILED = TIZEN_ERROR_UNKNOWN - 2, /**< Operation failed */
+    MMI_IU_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+} MMI_IU_ERROR_e;
+
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_MMI_IU_ERROR_H__ */
diff --git a/src/iu/mmi_iu_event.h b/src/iu/mmi_iu_event.h
new file mode 100644 (file)
index 0000000..c899add
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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 __TIZEN_UIX_MMI_IU_EVENT_H__
+#define __TIZEN_UIX_MMI_IU_EVENT_H__
+
+typedef enum {
+    MMI_EVENT_WAKE_UP,
+    MMI_EVENT_KEY_DOWN,
+    MMI_EVENT_KEY_UP,
+    MMI_EVENT_GESTURE,
+    MMI_EVENT_VOICE,
+    MMI_EVENT_VISION,
+} mmi_event_type_e;
+
+typedef enum {
+    MMI_EVENT_KEYEVENT_UP,
+    MMI_EVENT_KEYEVENT_DOWN,
+    MMI_EVENT_KEYEVENT_LEFT,
+    MMI_EVENT_KEYEVENT_RIGHT,
+    MMI_EVENT_KEYEVENT_SELECT,
+    MMI_EVENT_KEYEVENT_BACK,
+    MMI_EVENT_KEYEVENT_MIC
+} mmi_event_key_type_e;
+
+typedef enum {
+    MMI_EVENT_GESTURE_SWIPE_UP,
+    MMI_EVENT_GESTURE_SWIPE_DOWN,
+    MMI_EVENT_GESTURE_SWIPE_LEFT,
+    MMI_EVENT_GESTURE_SWIPE_RIGHT,
+    MMI_EVENT_GESTURE_PUSH,
+    MMI_EVENT_GESTURE_WAVEHANDX,
+    MMI_EVENT_GESTURE_FLIPPALM,
+    MMI_EVENT_GESTURE_SHOWPALM
+} mmi_event_gesture_type_e;
+
+typedef enum {
+    MMI_EVENT_VOICE_UP,
+    MMI_EVENT_VOICE_DOWN,
+    MMI_EVENT_VOICE_LEFT,
+    MMI_EVENT_VOICE_RIGHT,
+    MMI_EVENT_VOICE_YES,
+    MMI_EVENT_VOICE_CANCEL,
+    MMI_EVENT_VOICE_PLAY,
+    MMI_EVENT_VOICE_EXECUTE,
+    MMI_EVENT_VOICE_BACK,
+    MMI_EVENT_VOICE_EXIT,
+    MMI_EVENT_VOICE_STOP,
+    MMI_EVENT_VOICE_TERMINATE
+} mmi_event_voice_type_e;
+
+typedef enum {
+    MMI_EVENT_VISION_MOVE_AWAY,
+} mmi_event_vision_type_e;
+
+#endif /* __TIZEN_UIX_MMI_IU_EVENT_H__ */
diff --git a/src/iu/mmi_iu_log.h b/src/iu/mmi_iu_log.h
new file mode 100644 (file)
index 0000000..eb89c1f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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 __TIZEN_UIX_MMI_IU_LOG_H__
+#define __TIZEN_UIX_MMI_IU_LOG_H__
+
+#include <dlog.h>
+#include <stdio.h>
+#include <libgen.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "MMI_IU"
+
+#ifdef _E
+#undef _E
+#endif
+
+#ifdef _W
+#undef _W
+#endif
+
+#ifdef _I
+#undef _I
+#endif
+
+#ifdef _D
+#undef _D
+#endif
+
+#define _D LOGD
+#define _E LOGE
+#define _I LOGI
+#define _W LOGW
+
+#endif /* __TIZEN_UIX_MMI_IU_LOG_H__ */
diff --git a/src/iu/output_intent.cpp b/src/iu/output_intent.cpp
new file mode 100644 (file)
index 0000000..17b3e79
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+#include <unistd.h>
+#include <string>
+
+#include "output_intent.h"
+#include "mmi_iu_log.h"
+
+OutputIntent::OutputIntent()
+{
+    json_object = json_object_new();
+}
+
+OutputIntent::~OutputIntent()
+{
+    json_object = NULL;
+}
+
+string OutputIntent::get_action()
+{
+    return action;
+}
+
+void OutputIntent::set_action(string action)
+{
+    json_object_set_string_member(json_object, "Action", action.c_str());
+    this->action = action;
+}
+
+void OutputIntent::add_member_value(string key, string value)
+{
+    json_object_set_string_member(json_object, key.c_str(), value.c_str());
+}
+
+string OutputIntent::get_output_intent_text()
+{
+    string json_output_text;
+    JsonGenerator *j_generator = NULL;
+    JsonNode *j_node = NULL;
+    gsize size = 0;
+    gchar *data = NULL;
+
+    j_generator = json_generator_new();
+    if (j_generator == NULL) {
+        _E("json generator create error");
+        goto cleanup;
+    }
+
+    j_node = json_node_new(JSON_NODE_OBJECT);
+    if (j_node == NULL) {
+        _E("json node create error");
+        goto cleanup;
+    }
+
+    json_node_set_object(j_node, json_object);
+    json_generator_set_root(j_generator, j_node);
+
+    data = json_generator_to_data(j_generator, &size);
+    if (data == NULL) {
+        _E("Failed to get json data");
+        goto cleanup;
+    }
+
+    json_output_text = string(data);
+
+cleanup:
+    if (data)
+        g_free(data);
+
+    if (j_node)
+        json_node_free(j_node);
+
+    if (j_generator)
+        g_object_unref(j_generator);
+
+    return json_output_text;
+}
diff --git a/src/iu/output_intent.h b/src/iu/output_intent.h
new file mode 100644 (file)
index 0000000..5608662
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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 __OUTPUT_INTENT_H__
+#define __OUTPUT_INTENT_H__
+
+#include <unistd.h>
+#include <string>
+#include <json-glib/json-glib.h>
+
+using namespace std;
+
+class OutputIntent
+{
+public:
+    OutputIntent();
+    virtual ~OutputIntent();
+
+    void add_member_value(string key, string value);
+    void set_action(string action);
+    string get_action();
+
+    string get_output_intent_text();
+
+private:
+    JsonObject *json_object = NULL;
+    string action;
+};
+
+#endif /* __OUTPUT_INTENT_H__ */
index c3ca073..05f6c94 100644 (file)
@@ -18,6 +18,15 @@ mmi_manager_srcs = [
        'mmi-manager-dbg.h',
        'interface/mmifw_stub.h',
        'interface/mmifw_stub.c',
+       'iu/input_intent.cpp',
+       'iu/input_intent.h',
+       'iu/intent_understanding_engine.cpp',
+       'iu/intent_understanding_engine.h',
+       'iu/iu_rule.cpp',
+       'iu/iu_rule.h',
+       'iu/mmi_iu.cpp',
+       'iu/output_intent.cpp',
+       'iu/output_intent.h'
        ]
 
 install_headers(
@@ -27,12 +36,15 @@ install_headers(
        'mmi-fusion-iface.h'
        )
 
+install_data('iu/data/default_rule.json', install_dir : '/usr/share/iu/')
+
 glib_dep = dependency('glib-2.0')
 gio_dep = dependency('gio-2.0')
 bundle_dep = dependency('bundle')
 dlog_dep = dependency('dlog')
 ecore_dep = dependency('ecore', method : 'pkg-config')
 rpc_port_dep = dependency('rpc-port')
+json_glib_dep = dependency('json-glib-1.0')
 libtzplatform_config_dep = dependency('libtzplatform-config')
 
 mmi_manager_deps = [
@@ -42,6 +54,7 @@ mmi_manager_deps = [
        bundle_dep,
        dlog_dep,
        rpc_port_dep,
+       json_glib_dep,
        libtzplatform_config_dep]
 
 subdir('modules/modality_keyboard')
@@ -61,7 +74,7 @@ mmi_manager_include_dirs = include_directories(
 
 mmi_manager_declared_dep = declare_dependency(
        dependencies : [mmi_manager_deps],
-       include_directories : [mmi_manager_include_dirs]        
+       include_directories : [mmi_manager_include_dirs]
        )
 
 pkgconfig.generate(
diff --git a/tests/iu/intent_understanding_engine_rule_unittests.cpp b/tests/iu/intent_understanding_engine_rule_unittests.cpp
new file mode 100644 (file)
index 0000000..44cb9e9
--- /dev/null
@@ -0,0 +1,1005 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <string>
+
+#include "mmi_iu.h"
+#include "output_intent.h"
+#include "intent_understanding_engine.h"
+#include <glib.h>
+#include <string>
+#include <json-glib/json-glib.h>
+
+using namespace std;
+
+namespace {
+
+class IUEngineRuleTest : public testing::Test {
+    public:
+        virtual void SetUp() {
+            EXPECT_EQ(iue.set_rule_json_data(rule.c_str()), true);
+        }
+        virtual void TearDown() {
+        }
+
+        IntentUnderstandingEngine iue;
+
+    private:
+        string rule = R"({
+            "IURule" : [
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "KeyInput",
+                            "Action" : "PressMicButton"
+                        }
+                    ],
+                    "MMIStatus" : "Initiation",
+                    "OutputIntent": {
+                        "Action" : "WakeUp"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Gesture",
+                            "Action" : "ShowPalm"
+                        }
+                    ],
+                    "MMIStatus": "Initiation",
+                    "OutputIntent": {
+                        "Action" : "WakeUp"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "KeyInput",
+                            "Action" : "PressUpButton"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveUp"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "KeyInput",
+                            "Action" : "PressDownButton"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveDown"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "KeyInput",
+                            "Action" : "PressRightButton"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveRight"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "KeyInput",
+                            "Action" : "PressLeftButton"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveLeft"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "MoveUp"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveUp"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "MoveDown"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveDown"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "MoveRight"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveRight"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "MoveLeft"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveLeft"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Gesture",
+                            "Action" : "HandUp"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveUp"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Gesture",
+                            "Action" : "HandDown"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveDown"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Gesture",
+                            "Action" : "HandRight"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveRight"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Gesture",
+                            "Action" : "HandLeft"
+                        }
+                    ],
+                    "MMIStatus": "Exploration",
+                    "OutputIntent": {
+                        "Action" : "MoveLeft"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "KeyInput",
+                            "Action" : "PressOKButton"
+                        }
+                    ],
+                    "MMIStatus": "Execution",
+                    "OutputIntent": {
+                        "Action" : "Execute"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "Execute"
+                        }
+                    ],
+                    "MMIStatus": "Execution",
+                    "OutputIntent": {
+                        "Action" : "Execute"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "Play"
+                        }
+                    ],
+                    "MMIStatus": "Execution",
+                    "OutputIntent": {
+                        "Action" : "Play"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "Yes"
+                        }
+                    ],
+                    "MMIStatus": "Execution",
+                    "OutputIntent": {
+                        "Action" : "Yes"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "Yes"
+                        }
+                    ],
+                    "MMIStatus": "Execution",
+                    "OutputIntent": {
+                        "Action" : "Execute"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "Yes"
+                        }
+                    ],
+                    "MMIStatus": "Execution",
+                    "OutputIntent": {
+                        "Action" : "Execute"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Gesture",
+                            "Action" : "HandPush"
+                        }
+                    ],
+                    "MMIStatus": "Execution",
+                    "OutputIntent": {
+                        "Action" : "Execute"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "KeyInput",
+                            "Action" : "PressOKButton"
+                        }
+                    ],
+                    "MMIStatus": "Execution",
+                    "OutputIntent": {
+                        "Action" : "Execute"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "KeyInput",
+                            "Action" : "PressBackButton"
+                        }
+                    ],
+                    "MMIStatus": "Execution",
+                    "OutputIntent": {
+                        "Action" : "Cancel"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "KeyInput",
+                            "Action" : "PressBackButton"
+                        }
+                    ],
+                    "MMIStatus": "Feedback",
+                    "OutputIntent": {
+                        "Action" : "Cancel"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "Cancel"
+                        }
+                    ],
+                    "MMIStatus": "Feedback",
+                    "OutputIntent": {
+                        "Action" : "Cancel"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "Back"
+                        }
+                    ],
+                    "MMIStatus": "Feedback",
+                    "OutputIntent": {
+                        "Action" : "Cancel"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Gesture",
+                            "Action" : "WaveHandX"
+                        }
+                    ],
+                    "MMIStatus": "Feedback",
+                    "OutputIntent": {
+                        "Action" : "Cancel"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Vision",
+                            "Action" : "OutOfVision"
+                        }
+                    ],
+                    "MMIStatus": "Observation",
+                    "OutputIntent": {
+                        "Action" : "Pause"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "KeyInput",
+                            "Action" : "PressBackButton"
+                        }
+                    ],
+                    "MMIStatus": "Termination",
+                    "OutputIntent": {
+                        "Action" : "Exit"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "Exit"
+                        }
+                    ],
+                    "MMIStatus": "Termination",
+                    "OutputIntent": {
+                        "Action" : "Exit"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "Stop"
+                        }
+                    ],
+                    "MMIStatus": "Termination",
+                    "OutputIntent": {
+                        "Action" : "Stop"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Voice",
+                            "Action" : "Terminate"
+                        }
+                    ],
+                    "MMIStatus": "Termination",
+                    "OutputIntent": {
+                        "Action" : "Terminate"
+                    }
+                },
+                {
+                    "InputIntents" : [
+                        {
+                            "Modality" : "Gesture",
+                            "Action" : "FlipPalm"
+                        }
+                    ],
+                    "MMIStatus": "Termination",
+                    "OutputIntent": {
+                        "Action" : "Exit"
+                    }
+                }
+            ]
+        })";
+};
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_keyinput_press_mic_button)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressMicButton"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_INITIATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "WakeUp");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_gesture_showpalm)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "ShowPalm"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_INITIATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "WakeUp");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_key_input_press_up)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressUpButton"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveUp");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_key_input_press_down)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressDownButton"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveDown");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_key_input_press_right)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressRightButton"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveRight");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_key_input_press_left)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressLeftButton"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveLeft");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_move_up)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "MoveUp"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveUp");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_move_down)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "MoveDown"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveDown");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_move_right)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "MoveRight"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveRight");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_move_left)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "MoveLeft"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveLeft");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_gesture_hand_up)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "HandUp"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveUp");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_gesture_hand_down)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "HandDown"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveDown");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_gesture_hand_right)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "HandRight"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveRight");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_gesture_hand_left)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "HandLeft"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXPLORATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "MoveLeft");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_key_press_ok)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressOKButton"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXECUTION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Execute");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_execute)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Execute"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXECUTION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Execute");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_play)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Play"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXECUTION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Play");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_yes)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Yes"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXECUTION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Yes");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_gesture_hand_push)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "HandPush"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_EXECUTION);
+
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Execute");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_key_back_button)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressBackButton"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_FEEDBACK);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Cancel");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_cancel)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Cancel"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_FEEDBACK);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Cancel");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_back)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Back"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_FEEDBACK);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Cancel");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_gesture_wavehandx)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "WaveHandX"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_FEEDBACK);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Cancel");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_vision_outofvision)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Vision",
+                "Action" : "OutOfVision"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_OBSERVATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Pause");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_key_back_terminate)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressBackButton"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_TERMINATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Exit");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_exit)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Exit"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_TERMINATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Exit");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_stop)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Stop"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_TERMINATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Stop");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_voice_terminate)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Terminate"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_TERMINATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Terminate");
+}
+
+TEST_F(IUEngineRuleTest, utc_intent_understanding_engine_rule_gesture_flippalm)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "FlipPalm"
+            }
+        ]
+    }
+    )";
+
+    iue.set_app_state(MMI_STATE_TERMINATION);
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "Exit");
+}
+
+} // namespace
+
+
diff --git a/tests/iu/intent_understanding_engine_unittests.cpp b/tests/iu/intent_understanding_engine_unittests.cpp
new file mode 100644 (file)
index 0000000..2f822ef
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <string>
+
+#include "mmi_iu.h"
+#include "output_intent.h"
+#include "intent_understanding_engine.h"
+#include <glib.h>
+#include <string>
+#include <json-glib/json-glib.h>
+
+using namespace std;
+
+namespace {
+
+class IUEngineTest : public testing::Test {
+    public:
+        virtual void SetUp() {
+        }
+        virtual void TearDown() {
+        }
+
+    private:
+};
+
+TEST_F(IUEngineTest, utc_intent_understanding_engine)
+{
+    IntentUnderstandingEngine iue;
+
+    string rule = R"({
+        "IURule" : [
+            {
+                "InputIntents" : [
+                    {
+                        "Modality" : "KeyInput",
+                        "Action" : "PressMicButton"
+                    }
+                ],
+                "MMIStatus" : "Initiation",
+                "OutputIntent": {
+                    "Action" : "WakeUp"
+                }
+            },
+            {
+                "InputIntents" : [
+                    {
+                        "Modality" : "Gesture",
+                        "Action" : "ShowPalm"
+                    }
+                ],
+                "MMIStatus": "Initiation",
+                "OutputIntent": {
+                    "Action" : "WakeUp"
+                }
+            },
+            {
+                "InputIntents" : [
+                    {
+                        "Modality" : "KeyInput",
+                        "Action" : "PressUpButton"
+                    }
+                ],
+                "MMIStatus": "Exploration",
+                "OutputIntent": {
+                    "Action" : "MoveUp"
+                }
+            }
+        ]
+    })";
+
+    EXPECT_EQ(iue.set_rule_json_data(rule.c_str()), true);
+}
+
+TEST_F(IUEngineTest, utc_intent_understanding_engine_get_output_intent_p)
+{
+    IntentUnderstandingEngine iue;
+
+    string rule = R"({
+        "IURule" : [
+            {
+                "InputIntents" : [
+                    {
+                        "Modality" : "KeyInput",
+                        "Action" : "PressMicButton"
+                    }
+                ],
+                "MMIStatus" : "Initiation",
+                "OutputIntent": {
+                    "Action" : "WakeUp"
+                }
+            },
+            {
+                "InputIntents" : [
+                    {
+                        "Modality" : "Gesture",
+                        "Action" : "ShowPalm"
+                    }
+                ],
+                "MMIStatus": "Initiation",
+                "OutputIntent": {
+                    "Action" : "WakeUp"
+                }
+            },
+            {
+                "InputIntents" : [
+                    {
+                        "Modality" : "KeyInput",
+                        "Action" : "PressUpButton"
+                    }
+                ],
+                "MMIStatus": "Exploration",
+                "OutputIntent": {
+                    "Action" : "MoveUp"
+                }
+            }
+        ]
+    })";
+
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressMicButton"
+            }
+        ]
+    }
+    )";
+
+    EXPECT_EQ(iue.set_rule_json_data(rule.c_str()), true);
+
+    iue.set_input_intent_json_data(input_intent_json_data.c_str());
+
+    EXPECT_STREQ(iue.get_output_intent_action().c_str(), "WakeUp");
+}
+
+} // namespace
+
+
diff --git a/tests/iu/iu_rule_unittests.cpp b/tests/iu/iu_rule_unittests.cpp
new file mode 100644 (file)
index 0000000..de2f7b8
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <string>
+
+#include "iu_rule.h"
+#include <glib.h>
+#include <string>
+#include <json-glib/json-glib.h>
+
+using namespace std;
+
+namespace {
+
+class IntentUnderstandingRuleTest : public testing::Test {
+    public:
+        virtual void SetUp() {
+        }
+        virtual void TearDown() {
+        }
+
+private:
+
+};
+
+TEST_F(IntentUnderstandingRuleTest, utc_iu_rule_set_app_state)
+{
+    IntentUnderstandingRule iu_rule;
+    iu_rule.set_app_state("Initiation");
+    EXPECT_EQ(iu_rule.get_app_state(), MMI_STATE_INITIATION);
+
+    iu_rule.set_app_state("Exploration");
+    EXPECT_EQ(iu_rule.get_app_state(), MMI_STATE_EXPLORATION);
+
+    iu_rule.set_app_state("Execution");
+    EXPECT_EQ(iu_rule.get_app_state(), MMI_STATE_EXECUTION);
+
+    iu_rule.set_app_state("Feedback");
+    EXPECT_EQ(iu_rule.get_app_state(), MMI_STATE_FEEDBACK);
+
+    iu_rule.set_app_state("Observation");
+    EXPECT_EQ(iu_rule.get_app_state(), MMI_STATE_OBSERVATION);
+
+    iu_rule.set_app_state("Termination");
+    EXPECT_EQ(iu_rule.get_app_state(), MMI_STATE_TERMINATION);
+}
+
+} // namespace
diff --git a/tests/iu/main.cpp b/tests/iu/main.cpp
new file mode 100644 (file)
index 0000000..a37d671
--- /dev/null
@@ -0,0 +1,7 @@
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/tests/iu/meson.build b/tests/iu/meson.build
new file mode 100644 (file)
index 0000000..9570486
--- /dev/null
@@ -0,0 +1,30 @@
+iu_tests_srcs = [
+       'intent_understanding_engine_rule_unittests.cpp',
+       'intent_understanding_engine_unittests.cpp',
+       'iu_rule_unittests.cpp',
+       'main.cpp',
+       'mmi_iu_feed_input_event_unittests.cpp',
+       'mmi_iu_noinit_unittests.cpp',
+       'mmi_iu_unittests.cpp',
+       'output_intent_unittests.cpp',
+       '../../src/iu/input_intent.cpp',
+       '../../src/iu/intent_understanding_engine.cpp',
+       '../../src/iu/iu_rule.cpp',
+       '../../src/iu/mmi_iu.cpp',
+       '../../src/iu/output_intent.cpp'
+       ]
+
+gmock_dep = dependency('gmock', method : 'pkg-config')
+ecore_dep = dependency('ecore', method : 'pkg-config')
+json_glib_dep = dependency('json-glib-1.0', method : 'pkg-config')
+
+incdir = include_directories('../../src/iu')
+
+executable(
+       'iu-tests',
+       iu_tests_srcs,
+       dependencies : [mmi_manager_declared_dep, gmock_dep, ecore_dep, json_glib_dep],
+       include_directories : incdir,
+       install_dir : mmi_manager_prefix_bindir,
+       install : true
+       )
diff --git a/tests/iu/mmi_iu_feed_input_event_unittests.cpp b/tests/iu/mmi_iu_feed_input_event_unittests.cpp
new file mode 100644 (file)
index 0000000..2a55c64
--- /dev/null
@@ -0,0 +1,488 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <string>
+
+#include "mmi_iu.h"
+#include "mmi_iu_log.h"
+
+#include <glib.h>
+#include <string>
+#include <json-glib/json-glib.h>
+
+using namespace std;
+
+#define TEST_APP_ID "org.tizen.iu-test"
+#define SYSTEM_APP_ID "org.tizen.system-app"
+
+static string output_action;
+
+namespace {
+
+static void output_intent_received_cb(const char *app_id, const char *json_data, void *user_data)
+{
+    JsonParser *parser = json_parser_new();
+    GError *err_msg = NULL;
+    JsonNode *root = NULL;
+    JsonObject *root_obj = NULL;
+    const gchar *action = NULL;
+
+    json_parser_load_from_data(parser, (char *)json_data, -1, &err_msg);
+    if (err_msg) {
+        _E("failed to load json file. error message: %s\n", err_msg->message);
+        goto cleanup;
+    }
+
+    root = json_parser_get_root(parser);
+    if (root == NULL) {
+        _E("failed to get root\n");
+        goto cleanup;
+    }
+
+    root_obj = json_node_get_object(root);
+    if (root_obj == NULL) {
+        _E("failed to get object\n");
+        goto cleanup;
+    }
+
+    action = json_object_get_string_member(root_obj, "Action");
+    _D("Action: %s\n", action);
+    output_action = string(action);
+
+cleanup:
+    if (err_msg)
+        g_error_free(err_msg);
+
+    if (parser)
+        g_object_unref(parser);
+}
+
+class IUClientFeedInputEventTest : public testing::Test {
+    public:
+        virtual void SetUp() {
+            int ret = mmi_iu_init();
+            EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+            output_action = string("");
+
+            ret = mmi_iu_set_output_intent_received_callback(output_intent_received_cb, NULL);
+            EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+        }
+        virtual void TearDown() {
+            mmi_iu_shutdown();
+        }
+    private:
+
+};
+
+int feed_input_event_test(mmi_state app_state, int type, void *event)
+{
+    int ret = mmi_iu_set_app_state(app_state);
+    if (ret != MMI_IU_ERROR_NONE)
+        return ret;
+
+    ret = mmi_iu_set_focus_app_id(TEST_APP_ID);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    ret = mmi_iu_feed_input_event(TEST_APP_ID, type, event);
+    return ret;
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_input_event_keyinput_press_mic_button)
+{
+    mmi_provider_event_key key_event;
+    key_event.type = MMI_EVENT_KEY_DOWN;
+    key_event.keycode = MMI_EVENT_KEYEVENT_MIC;
+
+    int ret = feed_input_event_test(MMI_STATE_INITIATION, MMI_EVENT_KEY_DOWN, &key_event);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "WakeUp");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_gesture_showpalm)
+{
+    mmi_provider_event_gesture ge;
+    ge.type = MMI_EVENT_GESTURE_SHOWPALM;
+
+    int ret = feed_input_event_test(MMI_STATE_INITIATION, MMI_EVENT_GESTURE, &ge);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "WakeUp");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_key_input_press_up)
+{
+    mmi_provider_event_key key_event;
+    key_event.type = MMI_EVENT_KEY_DOWN;
+    key_event.keycode = MMI_EVENT_KEYEVENT_UP;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_KEY_DOWN, &key_event);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveUp");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_key_input_press_down)
+{
+    mmi_provider_event_key key_event;
+    key_event.type = MMI_EVENT_KEY_DOWN;
+    key_event.keycode = MMI_EVENT_KEYEVENT_DOWN;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_KEY_DOWN, &key_event);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveDown");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_key_input_press_right)
+{
+    mmi_provider_event_key key_event;
+    key_event.type = MMI_EVENT_KEY_DOWN;
+    key_event.keycode = MMI_EVENT_KEYEVENT_RIGHT;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_KEY_DOWN, &key_event);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveRight");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_key_input_press_left)
+{
+    mmi_provider_event_key key_event;
+    key_event.type = MMI_EVENT_KEY_DOWN;
+    key_event.keycode = MMI_EVENT_KEYEVENT_LEFT;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_KEY_DOWN, &key_event);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveLeft");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_move_up)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_UP;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveUp");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_move_down)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_DOWN;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveDown");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_move_right)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_RIGHT;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveRight");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_move_left)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_LEFT;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveLeft");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_gesture_hand_up)
+{
+    mmi_provider_event_gesture ge;
+    ge.type = MMI_EVENT_GESTURE_SWIPE_UP;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_GESTURE, &ge);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveUp");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_gesture_hand_down)
+{
+    mmi_provider_event_gesture ge;
+    ge.type = MMI_EVENT_GESTURE_SWIPE_DOWN;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_GESTURE, &ge);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveDown");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_gesture_hand_right)
+{
+    mmi_provider_event_gesture ge;
+    ge.type = MMI_EVENT_GESTURE_SWIPE_RIGHT;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_GESTURE, &ge);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveRight");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_gesture_hand_left)
+{
+    mmi_provider_event_gesture ge;
+    ge.type = MMI_EVENT_GESTURE_SWIPE_LEFT;
+
+    int ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_EVENT_GESTURE, &ge);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveLeft");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_key_press_ok)
+{
+    mmi_provider_event_key key_event;
+    key_event.type = MMI_EVENT_KEY_DOWN;
+    key_event.keycode = MMI_EVENT_KEYEVENT_SELECT;
+
+    int ret = feed_input_event_test(MMI_STATE_EXECUTION, MMI_EVENT_KEY_DOWN, &key_event);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Execute");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_execute)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_EXECUTE;
+
+    int ret = feed_input_event_test(MMI_STATE_EXECUTION, MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Execute");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_play)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_PLAY;
+
+    int ret = feed_input_event_test(MMI_STATE_EXECUTION, MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Play");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_yes)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_YES;
+
+    int ret = feed_input_event_test(MMI_STATE_EXECUTION,  MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Yes");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_gesture_hand_push)
+{
+    mmi_provider_event_gesture ge;
+    ge.type = MMI_EVENT_GESTURE_PUSH;
+
+    int ret = feed_input_event_test(MMI_STATE_EXECUTION, MMI_EVENT_GESTURE, &ge);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Execute");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_key_back_button)
+{
+    mmi_provider_event_key key_event;
+    key_event.type = MMI_EVENT_KEY_DOWN;
+    key_event.keycode = MMI_EVENT_KEYEVENT_BACK;
+
+    int ret = feed_input_event_test(MMI_STATE_FEEDBACK, MMI_EVENT_KEY_DOWN, &key_event);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Cancel");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_cancel)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_CANCEL;
+
+    int ret = feed_input_event_test(MMI_STATE_FEEDBACK, MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Cancel");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_back)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_BACK;
+
+    int ret = feed_input_event_test(MMI_STATE_FEEDBACK, MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Cancel");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_gesture_wavehandx)
+{
+    mmi_provider_event_gesture ge;
+    ge.type = MMI_EVENT_GESTURE_WAVEHANDX;
+
+    int ret = feed_input_event_test(MMI_STATE_FEEDBACK, MMI_EVENT_GESTURE, &ge);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Cancel");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_vision_outofvision)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Vision",
+                "Action" : "OutOfVision"
+            }
+        ]
+    }
+    )";
+
+    mmi_provider_event_vision vision_event;
+    vision_event.type = MMI_EVENT_VISION_MOVE_AWAY;
+
+    int ret = feed_input_event_test(MMI_STATE_OBSERVATION, MMI_EVENT_VISION, &vision_event);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Pause");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_key_back_terminate)
+{
+    mmi_provider_event_key key_event;
+    key_event.type = MMI_EVENT_KEY_DOWN;
+    key_event.keycode = MMI_EVENT_KEYEVENT_BACK;
+
+    int ret = feed_input_event_test(MMI_STATE_TERMINATION, MMI_EVENT_KEY_DOWN, &key_event);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Exit");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_exit)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_EXIT;
+
+    int ret = feed_input_event_test(MMI_STATE_TERMINATION, MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Exit");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_stop)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_STOP;
+
+    int ret = feed_input_event_test(MMI_STATE_TERMINATION, MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Stop");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_voice_terminate)
+{
+    mmi_provider_event_voice ve;
+    ve.type = MMI_EVENT_VOICE_TERMINATE;
+
+    int ret = feed_input_event_test(MMI_STATE_TERMINATION, MMI_EVENT_VOICE, &ve);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Terminate");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_gesture_flippalm)
+{
+    mmi_provider_event_gesture ge;
+    ge.type = MMI_EVENT_GESTURE_FLIPPALM;
+
+    int ret = feed_input_event_test(MMI_STATE_TERMINATION, MMI_EVENT_GESTURE, &ge);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Exit");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_gesture_continuous_test)
+{
+    mmi_provider_event_gesture ge;
+    ge.type = MMI_EVENT_GESTURE_SHOWPALM;
+
+    int ret = feed_input_event_test(MMI_STATE_INITIATION, MMI_EVENT_GESTURE, &ge);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "WakeUp");
+
+    ge.type = MMI_EVENT_GESTURE_FLIPPALM;
+
+    ret = feed_input_event_test(MMI_STATE_TERMINATION, MMI_EVENT_GESTURE, &ge);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Exit");
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_intent_gesture_flippalm_different_focus)
+{
+    int ret = mmi_iu_set_output_intent_received_callback(output_intent_received_cb, NULL);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    ret = mmi_iu_set_app_state(MMI_STATE_TERMINATION);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    ret = mmi_iu_set_focus_app_id(SYSTEM_APP_ID);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    mmi_provider_event_gesture ge;
+    ge.type = MMI_EVENT_GESTURE_FLIPPALM;
+
+    ret = mmi_iu_feed_input_event(TEST_APP_ID, MMI_EVENT_GESTURE, &ge);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "");
+}
+
+} // namespace
diff --git a/tests/iu/mmi_iu_noinit_unittests.cpp b/tests/iu/mmi_iu_noinit_unittests.cpp
new file mode 100644 (file)
index 0000000..7dedb16
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <string>
+
+#include "mmi_iu.h"
+#include "mmi_iu_log.h"
+#include "mmi-common.h"
+
+#include <glib.h>
+#include <string>
+#include <json-glib/json-glib.h>
+
+using namespace std;
+
+#define TEST_APP_ID "org.tizen.iu-test"
+#define SYSTEM_APP_ID "org.tizen.system-app"
+
+namespace {
+
+class IUClientNoInitTest : public testing::Test {
+    public:
+        virtual void SetUp() {
+        }
+        virtual void TearDown() {
+        }
+    private:
+};
+
+TEST_F(IUClientNoInitTest, utc_mmi_iu_feed_intent_n)
+{
+    int ret = mmi_iu_feed_intent(TEST_APP_ID, NULL);
+    EXPECT_EQ(ret, MMI_IU_ERROR_INVALID_PARAMETER);
+}
+
+static void output_intent_received_cb(const char *app_id, const char *json_data, void *user_data)
+{
+
+}
+
+TEST_F(IUClientNoInitTest, utc_mmi_iu_feed_intent_no_init)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressMicButton"
+            }
+        ]
+    }
+    )";
+
+    int ret = mmi_iu_feed_intent(TEST_APP_ID, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NOT_INITIALIZED);
+}
+
+TEST_F(IUClientNoInitTest, utc_mmi_iu_feed_input_event_no_init)
+{
+    mmi_provider_event_key key_event;
+    key_event.type = MMI_EVENT_KEY_DOWN;
+    key_event.keycode = MMI_EVENT_KEYEVENT_MIC;
+
+    int ret = mmi_iu_feed_input_event(TEST_APP_ID, MMI_EVENT_KEY_DOWN, &key_event);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NOT_INITIALIZED);
+}
+
+TEST_F(IUClientNoInitTest, utc_mmi_iu_set_output_intent_received_callback_no_init)
+{
+    int ret = mmi_iu_set_output_intent_received_callback(output_intent_received_cb, NULL);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NOT_INITIALIZED);
+}
+
+TEST_F(IUClientNoInitTest, utc_mmi_iu_set_app_state_no_init)
+{
+    int ret = mmi_iu_set_app_state(MMI_STATE_EXECUTION);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NOT_INITIALIZED);
+}
+
+TEST_F(IUClientNoInitTest, utc_mmi_iu_set_focus_app_id_no_init)
+{
+    int ret = mmi_iu_set_focus_app_id(TEST_APP_ID);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NOT_INITIALIZED);
+}
+
+TEST_F(IUClientNoInitTest, utc_mmi_iu_set_system_app_id_no_init)
+{
+    int ret = mmi_iu_set_system_app_id(SYSTEM_APP_ID);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NOT_INITIALIZED);
+}
+
+TEST_F(IUClientNoInitTest, utc_mmi_iu_unset_output_intent_received_callback_no_init)
+{
+    int ret = mmi_iu_unset_output_intent_received_callback();
+    EXPECT_EQ(ret, MMI_IU_ERROR_NOT_INITIALIZED);
+}
+
+} // namespace
diff --git a/tests/iu/mmi_iu_unittests.cpp b/tests/iu/mmi_iu_unittests.cpp
new file mode 100644 (file)
index 0000000..e62793b
--- /dev/null
@@ -0,0 +1,792 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <string>
+
+#include "mmi_iu.h"
+#include "mmi_iu_log.h"
+
+#include <glib.h>
+#include <string>
+#include <json-glib/json-glib.h>
+
+using namespace std;
+
+#define TEST_APP_ID "org.tizen.iu-test"
+#define SYSTEM_APP_ID "org.tizen.system-app"
+
+static string output_action;
+
+namespace {
+
+static void output_intent_received_cb(const char *app_id, const char *json_data, void *user_data)
+{
+    JsonParser *parser = json_parser_new();
+    GError *err_msg = NULL;
+    JsonNode *root = NULL;
+    JsonObject *root_obj = NULL;
+    const gchar *action = NULL;
+
+    json_parser_load_from_data(parser, (char *)json_data, -1, &err_msg);
+    if (err_msg) {
+        _E("failed to load json file. error message: %s\n", err_msg->message);
+        goto cleanup;
+    }
+
+    root = json_parser_get_root(parser);
+    if (root == NULL) {
+        _E("failed to get root\n");
+        goto cleanup;
+    }
+
+    root_obj = json_node_get_object(root);
+    if (root_obj == NULL) {
+        _E("failed to get object\n");
+        goto cleanup;
+    }
+
+    action = json_object_get_string_member(root_obj, "Action");
+    _D("Action: %s\n", action);
+    output_action = string(action);
+
+cleanup:
+    if (err_msg)
+        g_error_free(err_msg);
+
+    if (parser)
+        g_object_unref(parser);
+}
+
+class IUClientTest : public testing::Test {
+    public:
+        virtual void SetUp() {
+            int ret = mmi_iu_init();
+            EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+            output_action = string("");
+        }
+        virtual void TearDown() {
+            mmi_iu_shutdown();
+        }
+    private:
+
+};
+
+class IUClientFeedIntentTest : public testing::Test {
+    public:
+        virtual void SetUp() {
+            int ret = mmi_iu_init();
+            EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+            output_action = string("");
+
+            ret = mmi_iu_set_output_intent_received_callback(output_intent_received_cb, NULL);
+            EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+        }
+        virtual void TearDown() {
+            mmi_iu_shutdown();
+        }
+    private:
+
+};
+
+
+/**
+ * @function        utc_mmi_iu_init_p
+ * @description     Positive UTC of the function that inits intent understanding
+ * @parameter       NA
+ */
+TEST_F(IUClientTest, utc_mmi_iu_init_p)
+{
+    int ret = mmi_iu_init();
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+}
+
+/**
+ * @function        utc_mmi_mmi_iu_shutdown_p
+ * @description     Positive UTC of the function that shutdowns intent understanding
+ * @parameter       NA
+ */
+TEST_F(IUClientTest, utc_mmi_mmi_iu_shutdown_p)
+{
+    int ret = mmi_iu_init();
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    ret = mmi_iu_shutdown();
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+}
+
+/**
+ * @function        utc_mmi_iu_feed_intent_n
+ * @description     Negative UTC of the feed_intent function
+ * @parameter       NA
+ */
+TEST_F(IUClientTest, utc_mmi_iu_feed_intent_n)
+{
+    int ret = mmi_iu_feed_intent(TEST_APP_ID, NULL);
+    EXPECT_EQ(ret, MMI_IU_ERROR_INVALID_PARAMETER);
+}
+
+int feed_intent_test(mmi_state app_state, const char *input_intent)
+{
+    int ret = mmi_iu_set_app_state(app_state);
+    if (ret != MMI_IU_ERROR_NONE)
+        return ret;
+
+    ret = mmi_iu_set_focus_app_id(TEST_APP_ID);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    ret = mmi_iu_feed_intent(TEST_APP_ID, input_intent);
+    return ret;
+}
+
+/**
+ * @function        utc_mmi_iu_feed_intent_keyinput_press_mic_button
+ * @description     Positive UTC of the feed_intent function
+ * @parameter       NA
+ */
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_keyinput_press_mic_button)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressMicButton"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_INITIATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "WakeUp");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_gesture_showpalm)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "ShowPalm"
+            }
+        ]
+    })";
+
+    int ret = feed_intent_test(MMI_STATE_INITIATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "WakeUp");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_key_input_press_up)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressUpButton"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveUp");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_key_input_press_down)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressDownButton"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveDown");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_key_input_press_right)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressRightButton"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveRight");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_key_input_press_left)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressLeftButton"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveLeft");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_move_up)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "MoveUp"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveUp");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_move_down)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "MoveDown"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveDown");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_move_right)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "MoveRight"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveRight");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_move_left)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "MoveLeft"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveLeft");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_gesture_hand_up)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "HandUp"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveUp");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_gesture_hand_down)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "HandDown"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveDown");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_gesture_hand_right)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "HandRight"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveRight");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_gesture_hand_left)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "HandLeft"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXPLORATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "MoveLeft");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_key_press_ok)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressOKButton"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXECUTION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Execute");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_execute)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Execute"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXECUTION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Execute");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_play)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Play"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXECUTION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Play");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_yes)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Yes"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXECUTION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Yes");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_gesture_hand_push)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "HandPush"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_EXECUTION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Execute");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_key_back_button)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressBackButton"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_FEEDBACK, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Cancel");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_cancel)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Cancel"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_FEEDBACK, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Cancel");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_back)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Back"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_FEEDBACK, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Cancel");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_gesture_wavehandx)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "WaveHandX"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_FEEDBACK, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Cancel");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_vision_outofvision)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Vision",
+                "Action" : "OutOfVision"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_OBSERVATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Pause");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_key_back_terminate)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "KeyInput",
+                "Action" : "PressBackButton"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_TERMINATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Exit");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_exit)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Exit"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_TERMINATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Exit");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_stop)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Stop"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_TERMINATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Stop");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_voice_terminate)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Voice",
+                "Action" : "Terminate"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_TERMINATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Terminate");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_gesture_flippalm)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "FlipPalm"
+            }
+        ]
+    }
+    )";
+
+    int ret = feed_intent_test(MMI_STATE_TERMINATION, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "Exit");
+}
+
+TEST_F(IUClientFeedIntentTest, utc_mmi_iu_feed_intent_gesture_flippalm_different_focus)
+{
+    std::string input_intent_json_data =
+    R"({
+        "InputIntents" : [
+            {
+                "Modality" : "Gesture",
+                "Action" : "FlipPalm"
+            }
+        ]
+    }
+    )";
+
+    int ret = mmi_iu_set_output_intent_received_callback(output_intent_received_cb, NULL);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    ret = mmi_iu_set_focus_app_id(SYSTEM_APP_ID);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    ret = mmi_iu_feed_intent(TEST_APP_ID, input_intent_json_data.c_str());
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), "");
+}
+
+TEST_F(IUClientTest, utc_mmi_iu_set_output_intent_received_callback_n_callback_null)
+{
+    int ret = mmi_iu_set_output_intent_received_callback(NULL, NULL);
+    EXPECT_EQ(ret, MMI_IU_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(IUClientTest, utc_mmi_iu_set_output_intent_received_callback_p)
+{
+    int ret = mmi_iu_set_output_intent_received_callback(output_intent_received_cb, NULL);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+}
+
+TEST_F(IUClientTest, utc_mmi_iu_set_app_state_p)
+{
+    int ret = mmi_iu_set_app_state(MMI_STATE_EXECUTION);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+}
+
+TEST_F(IUClientTest, utc_mmi_iu_set_focus_app_id_p)
+{
+    int ret = mmi_iu_set_focus_app_id(TEST_APP_ID);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+}
+
+TEST_F(IUClientTest, utc_mmi_iu_set_focus_app_id_n)
+{
+    int ret = mmi_iu_set_focus_app_id(NULL);
+    EXPECT_EQ(ret, MMI_IU_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(IUClientTest, utc_mmi_iu_set_system_app_id_p)
+{
+    int ret = mmi_iu_set_system_app_id(SYSTEM_APP_ID);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+}
+
+TEST_F(IUClientTest, utc_mmi_iu_set_system_app_id_n)
+{
+    int ret = mmi_iu_set_system_app_id(NULL);
+    EXPECT_EQ(ret, MMI_IU_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(IUClientTest, utc_mmi_iu_unset_output_intent_received_callback_p)
+{
+    int ret = mmi_iu_unset_output_intent_received_callback();
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+}
+
+} // namespace
diff --git a/tests/iu/output_intent_unittests.cpp b/tests/iu/output_intent_unittests.cpp
new file mode 100644 (file)
index 0000000..dc50173
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <string>
+
+#include "mmi_iu.h"
+#include "output_intent.h"
+#include <glib.h>
+#include <string>
+#include <json-glib/json-glib.h>
+
+using namespace std;
+
+namespace {
+
+class OutputIntentTest : public testing::Test {
+    public:
+        virtual void SetUp() {
+        }
+        virtual void TearDown() {
+        }
+
+private:
+
+};
+
+TEST_F(OutputIntentTest, utc_output_intent_p)
+{
+    OutputIntent oi;
+    oi.set_action("WakeUp");
+
+    EXPECT_STREQ(oi.get_output_intent_text().c_str(),
+        R"({"Action":"WakeUp"})");
+}
+
+TEST_F(OutputIntentTest, utc_output_intent_p2)
+{
+    OutputIntent oi;
+    oi.add_member_value("Action", "WakeUp");
+    oi.add_member_value("Time", "Now");
+
+    EXPECT_STREQ(oi.get_output_intent_text().c_str(),
+        R"({"Action":"WakeUp","Time":"Now"})");
+}
+
+} // namespace