add FaceRecognitionEngine, face recognition json result, and TCs 51/295851/1
authordyamy-lee <dyamy.lee@samsung.com>
Thu, 1 Jun 2023 11:02:49 +0000 (20:02 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Fri, 14 Jul 2023 10:54:57 +0000 (19:54 +0900)
This patch is added FaceRecognitionEngine which handle face recognition event.
The logic for using FaceRecognitionEngine is in mmi_iu module.
Also, it added creating json result logic about face recognition event's result.
Then, it can check it's working by adding test case which get result from face recognition event.

Change-Id: I43cf857b341f064f0d173eb71fbd1e361ee3567a

src/mmimgr/iu/FaceRecognitionEngine.cpp [new file with mode: 0644]
src/mmimgr/iu/FaceRecognitionEngine.h [new file with mode: 0644]
src/mmimgr/iu/json_provider.cpp
src/mmimgr/iu/json_provider.h
src/mmimgr/iu/mmi_iu.cpp
src/mmimgr/meson.build
src/mmimgr/mmi-common.h
src/mmimgr/mmi-core.c
src/mmimgr/mmi-provider.c
tests/iu/mmi_iu_feed_input_event_unittests.cpp

diff --git a/src/mmimgr/iu/FaceRecognitionEngine.cpp b/src/mmimgr/iu/FaceRecognitionEngine.cpp
new file mode 100644 (file)
index 0000000..71fe385
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *               http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+#include <chrono>
+
+#include "mmi_iu_log.h"
+#include "FaceRecognitionEngine.h"
+
+FaceRecognitionEngine::FaceRecognitionEngine()
+{
+       outputResultUserData = nullptr;
+       outputResultCallback = nullptr;
+}
+
+FaceRecognitionEngine::~FaceRecognitionEngine()
+{
+}
+
+long FaceRecognitionEngine::getCurrentTimestamp()
+{
+       auto currentTime = std::chrono::system_clock::now();
+       long timestamp = chrono::time_point_cast<chrono::milliseconds>(currentTime).time_since_epoch().count();
+       _D("[FaceRecognitionEngine] current timestamp(%ld)", timestamp);
+
+       return timestamp;
+}
+
+void FaceRecognitionEngine::iterateRecognizedFacesCallback(gpointer data, gpointer userData)
+{
+       face_result* info = reinterpret_cast<face_result*>(data);
+       FaceRecognitionEngine* engine = reinterpret_cast<FaceRecognitionEngine*>(userData);
+
+       engine->mRecognizedFacesList.push_back(*info);
+       _D("[FaceRecognitionEngine] iterateRecognizedFacesCallback: name(%s), id(%s), confidence(%f)", info->name, info->id, info->confidence);
+}
+
+bool FaceRecognitionEngine::setInputModalityData(int modalityType, void *data)
+{
+       _I("[FaceRecognitionEngine] Set input modality data. type(%d)", modalityType);
+
+       mmi_provider_event_face_recognizer *event = reinterpret_cast<mmi_provider_event_face_recognizer *>(data);
+       if (event == nullptr) {
+               _E("[FaceRecognitionEngine] event is NULL");
+               return false;
+       }
+
+       int timestamp = this->getCurrentTimestamp();
+       JsonProvider provider;
+       provider.setInputEvent(MMI_KEY_FACE_RECOGNITION);
+
+       switch (event->type) {
+       case MMI_FACE_RECOGNIZER_RECORDING_START:
+               _I("[FaceRecognitionEngine] mmi_face_recognizer camera_preview_start");
+               provider.setOutputEvent(MMI_KEY_CAMERA_PREVIEW_START);
+               break;
+
+       case MMI_FACE_RECOGNIZER_RECORDING_STOP:
+               _I("[FaceRecognitionEngine] mmi_face_recognizer camera_preview_stop");
+               provider.setOutputEvent(MMI_KEY_CAMERA_PREVIEW_STOP);
+               break;
+
+       case MMI_FACE_RECOGNIZER_ADD_USER:
+               _I("[FaceRecognitionEngine] mmi_face_recognizer add_user");
+               provider.setOutputEvent(MMI_KEY_ADD_USER_FACE);
+               break;
+
+       case MMI_FACE_RECOGNIZER_DELETE_USER:
+               provider.setOutputEvent(MMI_KEY_DELETE_USER_FACE);
+               break;
+
+       case MMI_FACE_RECOGNIZER_RECOGNIZE_FACE:
+               if (event->n_faces == 0) {
+                       _E("[FaceRecognitionEngine] There is no recognized face");
+                       provider.setOutputEvent(MMI_KEY_ERROR);
+                       provider.setErrorEvent(MMI_REASON_NO_RECOGNIZED_FACES, timestamp);
+                       break;
+               }
+
+               provider.setOutputEvent(MMI_KEY_RECOGNIZED_FACE);
+               provider.setFaceRecognitionEvent(MMI_KEY_RECOGNIZED_FACE, event->n_faces, timestamp);
+               mRecognizedFacesList.clear();
+
+               g_list_foreach(event->recognized_faces_list, iterateRecognizedFacesCallback, reinterpret_cast<gpointer>(this));
+
+               for (auto &recognizedFace : mRecognizedFacesList) {
+                       provider.addInfoRecognizedFaces(recognizedFace.id, recognizedFace.name, recognizedFace.confidence,recognizedFace.coord_x, recognizedFace.coord_y, recognizedFace.width, recognizedFace.height);
+               }
+               break;
+
+       default:
+               _E("[FaceRecognitionEngine] Unknown event type(%d)", event->type);
+               return false;
+       }
+
+       // send json data
+       _D("face recognition engine json data(%s)", provider.jsonToString().c_str());
+       invokeOutputResultCallback(provider.jsonToString());
+       return true;
+}
+
+void FaceRecognitionEngine::invokeOutputResultCallback(std::string outputResult)
+{
+       if (outputResultCallback == nullptr) {
+               _W("[FaceRecognitionEngine] output result callback is not set. Please check it");
+               return;
+       }
+
+       _I("[FaceRecognitionEngine] invokeOutputResultCallback");
+       outputResultCallback(outputResult.c_str(), outputResultUserData);
+}
+
+void FaceRecognitionEngine::setOutputResultCallback(face_recognition_engine_output_result_cb callback, void *userData)
+{
+       outputResultCallback = callback;
+       outputResultUserData = userData;
+}
diff --git a/src/mmimgr/iu/FaceRecognitionEngine.h b/src/mmimgr/iu/FaceRecognitionEngine.h
new file mode 100644 (file)
index 0000000..f7b9ed8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *               http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+
+#ifndef __FACE_RECOGNITION_ENGINE_H__
+#define __FACE_RECOGNITION_ENGINE_H__
+
+#include <vector>
+#include "json_provider.h"
+#include "mmi-common.h"
+
+typedef void (*face_recognition_engine_output_result_cb)(const char *output_result, void *user_data);
+
+class FaceRecognitionEngine {
+public:
+       FaceRecognitionEngine();
+       ~FaceRecognitionEngine();
+
+       bool setInputModalityData(int modalityType, void *data);
+       void setOutputResultCallback(face_recognition_engine_output_result_cb callback, void *userData);
+
+private:
+       long getCurrentTimestamp();
+       void invokeOutputResultCallback(std::string result);
+       static void iterateRecognizedFacesCallback(gpointer data, gpointer userData);
+
+private:
+       std::vector<face_result> mRecognizedFacesList;
+       void *outputResultUserData;
+       face_recognition_engine_output_result_cb outputResultCallback;
+};
+
+#endif /* __FACE_RECOGNITION_ENGINE_H__ */
index 7a646f0a412c31e015f0b71038e2f5a3f0a91678..3084847181efeeefebd225bd49f76a4c0ac032ca 100644 (file)
@@ -61,6 +61,11 @@ JsonProvider::~JsonProvider()
         mSpeakerRecognitionObj = nullptr;
     }
 
+    if (mFaceRecognitionObj) {
+        json_object_unref(mFaceRecognitionObj);
+        mFaceRecognitionObj = nullptr;
+    }
+
     if (mRecognizedSpeakerCandidateListArr) {
         json_array_unref(mRecognizedSpeakerCandidateListArr);
         mRecognizedSpeakerCandidateListArr = nullptr;
@@ -71,8 +76,40 @@ JsonProvider::~JsonProvider()
         mRecognizedSpeakerResultObj = nullptr;
     }
 
+    if (mRecognizedFaceResultObj) {
+        json_object_unref(mRecognizedFaceResultObj);
+        mRecognizedFaceResultObj = nullptr;
+    }
+}
+
+void JsonProvider::setFaceRecognitionEvent(const char* resultType, int numOfFaces, int timeStamp)
+{
+    if (!mFaceRecognitionObj)
+        mFaceRecognitionObj = json_object_new();
+
+    json_object_set_object_member(mRootObj, MMI_KEY_RECOGNIZED_FACE, mFaceRecognitionObj);
+    json_object_set_int_member(mFaceRecognitionObj, MMI_KEY_NUM_OF_RECOGNIZED_FACES, numOfFaces);
+    json_object_set_int_member(mFaceRecognitionObj, MMI_KEY_TIMESTAMP, timeStamp);
 }
 
+void JsonProvider::addInfoRecognizedFaces(const char* id, const char* name, float confidence, int x, int y, int w, int h)
+{
+    if (!mRecognizedFaceResultListArr)
+    {
+        mRecognizedFaceResultListArr = json_array_new();
+        json_object_set_array_member(mFaceRecognitionObj, MMI_KEY_RECOGNIZED_FACE_LISTS, mRecognizedFaceResultListArr);
+    }
+
+    JsonObject* obj = json_object_new();
+    json_array_add_object_element(mRecognizedFaceResultListArr, obj);
+    json_object_set_string_member(obj, MMI_KEY_RECOGNIZED_FACE_ID, id);
+    json_object_set_string_member(obj, MMI_KEY_RECOGNIZED_FACE_NAME, name);
+    json_object_set_double_member(obj, MMI_KEY_RECOGNIZED_FACE_CONFIDENCE, (double)confidence);
+    json_object_set_int_member(obj, MMI_KEY_UI_OBJECT_X, x);
+    json_object_set_int_member(obj, MMI_KEY_UI_OBJECT_Y, y);
+    json_object_set_int_member(obj, MMI_KEY_UI_OBJECT_WIDTH, w);
+    json_object_set_int_member(obj, MMI_KEY_UI_OBJECT_HEIGHT, h);
+}
 
 void JsonProvider::setSpeakerRecognitionEvent(const char* result, int timeStamp)
 {
@@ -108,8 +145,6 @@ void JsonProvider::addRecognizedSpeakerCandidate(const char* id, const char* nam
     json_object_set_double_member(obj, MMI_KEY_SPEAKER_SCORE, (double)score);
 }
 
-
-
 void JsonProvider::setInputEvent(const char* value)
 {
        json_object_set_string_member(mRootObj, MMI_KEY_INPUT_EVENT, value);
index 6d830539dddef8429df68ed14b1bc933861b55c4..5f3e561d2825b46f1a9ffb6c85539bb0efb4bea6 100644 (file)
@@ -55,10 +55,24 @@ using namespace std;
 #define MMI_KEY_SPEAKER_NAME                        "speakerName"
 #define MMI_KEY_SPEAKER_SCORE                        "speakerScore"
 
+#define MMI_KEY_FACE_RECOGNITION                      "faceRecognition"
 
+#define MMI_KEY_CAMERA_PREVIEW_START                  "cameraPreviewStart"
+#define MMI_KEY_CAMERA_PREVIEW_STOP                   "cameraPreviewStop"
+#define MMI_KEY_ADD_USER_FACE                         "addUserFace"
+#define MMI_KEY_DELETE_USER_FACE                      "deleteUserFace"
+
+#define MMI_KEY_RECOGNIZED_FACE                        "recognizedFace"
+#define MMI_KEY_RECOGNIZED_FACE_LISTS                  "recognizedFaceLists"
+
+#define MMI_KEY_NUM_OF_RECOGNIZED_FACES                "numOfRecognizedFaces"
+#define MMI_KEY_RECOGNIZED_FACE_ID                     "recognizedFaceId"
+#define MMI_KEY_RECOGNIZED_FACE_NAME                   "recognizedFaceName"
+#define MMI_KEY_RECOGNIZED_FACE_CONFIDENCE             "recognizedFaceConfidence"
 
 #define MMI_REASON_NO_MATCHED_COMMANDS         "noMatchedCommands"
 #define MMI_REASON_NO_CLICKABLE_OBJECTS                "noClickableObjects"
+#define MMI_REASON_NO_RECOGNIZED_FACES      "noRecognizedFaces"
 
 struct UiClickedObject{
     int timeStamp;
@@ -99,6 +113,8 @@ public:
     void addRecognizedSpeakerCandidate(const char* id, const char* name, float score);
     void setRecognizedSpeakerResult(const char* result);
 
+    void setFaceRecognitionEvent(const char* resultType, int numOfFaces, int timeStamp);
+    void addInfoRecognizedFaces(const char* id, const char* name, float confidence, int x, int y, int w, int h);
 
     std::string jsonToString(void);
 
@@ -122,6 +138,9 @@ private:
     JsonArray* mRecognizedSpeakerCandidateListArr = nullptr;
     JsonObject* mRecognizedSpeakerResultObj = nullptr;
 
+    JsonObject* mFaceRecognitionObj = nullptr;
+    JsonArray* mRecognizedFaceResultListArr = nullptr;
+    JsonObject* mRecognizedFaceResultObj = nullptr;
 };
 
 
index e0bd49c0fbc8847b4bd0d758e010fabcd51d673c..1206dcc33bbd1fac452f7b2ad456c8d5c6268b6d 100644 (file)
@@ -24,6 +24,7 @@
 #include "mmi_iu_log.h"
 #include "VoiceTouchEngine.h"
 #include "SpeakerRecognitionEngine.h"
+#include "FaceRecognitionEngine.h"
 #include "mmi-common.h"
 
 using namespace std;
@@ -41,7 +42,7 @@ static bool initialized = false;
 static VoiceTouchEngine *g_VoiceTouchEngine = nullptr;
 
 static SpeakerRecognitionEngine *g_SpeakerRecognitionEngine = nullptr;
-
+static FaceRecognitionEngine *g_FaceRecognitionEngine = nullptr;
 
 static void init()
 {
@@ -87,6 +88,15 @@ void __mmi_iu_speaker_recognition_engine_output_result_cb(const char *output_res
     iu_output_result_received_callback(MMI_INPUT_EVENT_TYPE_SPEAKER_RECOGNITION, output_result, iu_output_result_user_data);
 }
 
+void mmi_iu_face_recognition_engine_output_result_cb(const char *output_result, void *user_data)
+{
+    if (iu_output_result_received_callback == nullptr) {
+        _E("[MMI IU] Output result callback is not set");
+        return;
+    }
+
+    iu_output_result_received_callback(MMI_INPUT_EVENT_TYPE_FACE_RECOGNITION, output_result, iu_output_result_user_data);
+}
 
 EXPORT_API int mmi_iu_init()
 {
@@ -117,6 +127,16 @@ EXPORT_API int mmi_iu_init()
         g_SpeakerRecognitionEngine->setOutputResultCallback(__mmi_iu_speaker_recognition_engine_output_result_cb, nullptr);
     }
 
+    try {
+        g_FaceRecognitionEngine = new FaceRecognitionEngine();
+    } catch (exception &e) {
+        _E("[MMI IU] Fail to allocate memory. (%s)", e.what());
+        return MMI_IU_ERROR_OUT_OF_MEMORY;
+    }
+
+    if (g_FaceRecognitionEngine) {
+        g_FaceRecognitionEngine->setOutputResultCallback(mmi_iu_face_recognition_engine_output_result_cb, nullptr);
+    }
 
     return MMI_IU_ERROR_NONE;
 }
@@ -133,6 +153,8 @@ EXPORT_API int mmi_iu_shutdown()
     delete g_SpeakerRecognitionEngine;
     g_SpeakerRecognitionEngine = nullptr;
 
+    delete g_FaceRecognitionEngine;
+    g_FaceRecognitionEngine = nullptr;
 
     if (!initialized)
         return MMI_IU_ERROR_NOT_INITIALIZED;
@@ -155,9 +177,15 @@ EXPORT_API int mmi_iu_feed_input_modality(int type, void *event)
     }
 
     if (type == MMI_PROVIDER_EVENT_FACE_RECOGNIZER) {
-        // Todo. FaceRecognitionEngine
-        _D("Face Recognition Engine is not supported yet.");
-        return MMI_IU_ERROR_NOT_SUPPORTED_TYPE;
+        _D("[DEBUG] The type is MMI_PROVIDER_EVENT_FACE_RECOGNIZER(%d)", type);
+        if (g_FaceRecognitionEngine) {
+            int res = g_FaceRecognitionEngine->setInputModalityData(type, event);
+            if(!res) {
+                _W("[ERROR] Not Supported Event Type");
+                return MMI_IU_ERROR_NOT_SUPPORTED_TYPE;
+            }
+            return MMI_IU_ERROR_NONE;
+        }
     }
 
     if (type == MMI_PROVIDER_EVENT_SPEAKER_RECOGNIZER) {
index 3e51599e814789e4812f81a9cf4161ed003e70f7..0b19f27e15b9f6dfa6ba4317a431d4e044bd6a1b 100644 (file)
@@ -35,6 +35,8 @@ mmimgr_srcs = [
        'output_modality/mmi_output_modality.h',
        'output_modality/TouchModule.cpp',
        'output_modality/TouchModule.h',
+       'iu/FaceRecognitionEngine.cpp',
+       'iu/FaceRecognitionEngine.h',
        ]
 
 install_headers(
index 7672a6b325cf0c5dc68c9cda6d69c85336362e32..72f00797ce0aaf7347355070f975f3810595aeb5 100644 (file)
@@ -332,7 +332,7 @@ typedef enum mmi_speaker_recognizer_operation
        MMI_SPEAKER_RECOGNIZER_RECORDING_STOP,
        MMI_SPEAKER_RECOGNIZER_ADD_USER,
        MMI_SPEAKER_RECOGNIZER_DELETE_USER,
-       MMI_SPEAKER_RECOGNIZER_RECOGNIZE_SPEAKER,
+       MMI_SPEAKER_RECOGNIZER_RECOGNIZE_SPEAKER
 } mmi_speaker_recognizer_operation;
 
 typedef struct
@@ -352,14 +352,32 @@ typedef struct
        GList *speaker_list; // list of speaker_result
 } mmi_provider_event_speaker_recognizer;
 
+typedef enum mmi_face_recognizer_operation
+{
+       MMI_FACE_RECOGNIZER_RECORDING_START,
+       MMI_FACE_RECOGNIZER_RECORDING_STOP,
+       MMI_FACE_RECOGNIZER_ADD_USER,
+       MMI_FACE_RECOGNIZER_DELETE_USER,
+       MMI_FACE_RECOGNIZER_RECOGNIZE_FACE,
+} mmi_face_recognizer_operation;
+
+typedef struct
+{
+       char *id;
+       char *name;
+       float confidence;
+       int coord_x;
+       int coord_y;
+       int width;
+       int height;
+} face_result;
+
 typedef struct
 {
        int type;
        int timestamp;
-       double confidence;
-       char *recognizer;
-       int n_recognizers;
-       GList *recognizer_list;
+       int n_faces;
+       GList *recognized_faces_list;
 } mmi_provider_event_face_recognizer;
 
 typedef struct
index 5db6ed1430b9b398f614fb4f6a7d5e82d349913c..4d9dc711f79b24bd00b7c8c9d8cc38d4bf293f35 100644 (file)
@@ -212,6 +212,7 @@ static Eina_Bool __speaker_recognizer_event_cb(void *data EINA_UNUSED, int type,
 static Eina_Bool face_recognizer_event_cb(void *data EINA_UNUSED, int type, void *event)
 {
        mmi_provider_event_face_recognizer *ev = (mmi_provider_event_face_recognizer *)event;
+       _I("[Face recognizer] type : %d, timestamp : %d, n_faces : %d", ev->type, ev->timestamp, ev->n_faces);
 
        mmi_iu_feed_input_modality(MMI_PROVIDER_EVENT_FACE_RECOGNIZER, ev);
        return ECORE_CALLBACK_PASS_ON;
index 394b168f22025cf2742f4326dd3b5474bfb58f86..2082fca0a4832dbe9e47af17b4eba06798309943 100644 (file)
@@ -294,6 +294,9 @@ _event_handler_init()
        LOGD("MMI_PROVIDER_EVENT_SCREEN_ANALYZER=%d\n", MMI_PROVIDER_EVENT_SCREEN_ANALYZER);
        LOGD("MMI_PROVIDER_EVENT_VOICE_TOUCH=%d\n", MMI_PROVIDER_EVENT_VOICE_TOUCH);
 
+       LOGD("MMI_PROVIDER_EVENT_FACE_RECOGNIZER=%d\n", MMI_PROVIDER_EVENT_FACE_RECOGNIZER);
+       LOGD("MMI_EVENT_FACE_RECOGNIZER=%d\n", MMI_EVENT_FACE_RECOGNIZER);
+
        //For debugging
        _provider_event_handlers[0] = ecore_event_handler_add(MMI_PROVIDER_EVENT_KEY,
                        _key_provider_event_cb, NULL);
index 8a6c1a157dfb02589e5651a5e8c537af0d45745c..fddb0aa93ad8c8b9b43e5b6ca7950ac90935e5c6 100644 (file)
@@ -27,6 +27,7 @@
 #include "mmi_iu.h"
 #include "mmi_iu_log.h"
 #include "mmi_iu_event.h"
+#include "json_provider.h"
 
 #include <glib.h>
 #include <string>
@@ -48,11 +49,6 @@ static bool g_event_received_cb = false;
 static bool g_check_event_received = false;
 
 #define MMI_EVENT_VOICE_TYPE_GO 1000 // for test
-#define MMI_KEY_OUTPUT_EVENT           "outputEvent"
-#define MMI_KEY_ASR_FINAL_RESULT       "asrFinalResult"
-#define MMI_KEY_RESULT         "result"
-#define MMI_KEY_UI_CLICKABLE_OBJECT            "uiClickableObject"
-#define MMI_KEY_NUM_OF_CLICKABLE_OBJECTS       "numOfClickableObjects"
 
 namespace {
 
@@ -158,6 +154,7 @@ class IUClientFeedInputEventTest : public testing::Test {
             MMI_PROVIDER_EVENT_VISION = ecore_event_type_new();
             MMI_PROVIDER_EVENT_SCREEN_ANALYZER = ecore_event_type_new();
             MMI_PROVIDER_EVENT_VOICE_TOUCH = ecore_event_type_new();
+            MMI_PROVIDER_EVENT_FACE_RECOGNIZER = ecore_event_type_new();
 
             g_received_event_type = -1;
             g_received_event_data = NULL;
@@ -184,6 +181,7 @@ class IUClientFeedInputEventTest : public testing::Test {
             MMI_PROVIDER_EVENT_VOICE = -1;
             MMI_PROVIDER_EVENT_VISION = -1;
             MMI_PROVIDER_EVENT_VOICE_TOUCH = -1;
+            MMI_PROVIDER_EVENT_FACE_RECOGNIZER = -1;
 
             ecore_shutdown();
         }
@@ -416,7 +414,99 @@ static void face_output_intent_received_cb(int type, const char *json_data, void
 {
     _D("face_output_intent_received_cb\n");
 
+    JsonParser *parser = json_parser_new();
+    GError *err_msg = NULL;
+    JsonNode *root = NULL;
+    JsonObject *root_obj = NULL;
+    JsonObject *result_obj = NULL;
+    const gchar *action = NULL;
+    string output_event = "";
+    JsonArray *output_array = NULL;
+    int num = 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 root_obj\n");
+        goto cleanup;
+    }
+
+    output_array = json_object_get_array_member(root_obj, MMI_KEY_OUTPUT_EVENT);
+    if (output_array == NULL) {
+        _E("output array is null");
+        goto cleanup;
+    }
+
+    action = json_array_get_string_element(output_array, 0);
+    if (action == nullptr) {
+        _E("failed to get output_array\n");
+        goto cleanup;
+    }
+
+    output_event = string(action);
+    if (output_event == MMI_KEY_RECOGNIZED_FACE) {
+        result_obj = json_object_get_object_member(root_obj, MMI_KEY_RECOGNIZED_FACE);
+        if (result_obj != NULL) {
+            num = json_object_get_int_member(result_obj, MMI_KEY_NUM_OF_RECOGNIZED_FACES);
+            if (num == NULL) {
+                _E("failed to get object of result\n");
+                goto cleanup;
+            }
+            _D("num of faces : %d", num);
+
+            output_array = json_object_get_array_member(result_obj, MMI_KEY_RECOGNIZED_FACE_LISTS);
+            if (output_array == NULL) {
+                _E("output array is null");
+                goto cleanup;
+            }
+
+            result_obj = json_array_get_object_element(output_array, 0);
+            if (result_obj != NULL) {
+                action = json_object_get_string_member(result_obj, MMI_KEY_RECOGNIZED_FACE_NAME);
+                if (action == nullptr) {
+                    _E("failed to get object of result\n");
+                    goto cleanup;
+                }
+
+                output_action = string(action);
+            }
+        }
+    }
+    else if (output_event == MMI_KEY_ERROR) {
+        result_obj = json_object_get_object_member(root_obj, MMI_KEY_ERROR);
+        if (result_obj != NULL) {
+            action = json_object_get_string_member(result_obj, MMI_KEY_REASON);
+            if (action == nullptr) {
+                _E("failed to get object of result\n");
+                goto cleanup;
+            }
+
+            output_action = string(action);
+        }
+    }
+
+    if (parser)
+        g_object_unref(parser);
+
     return;
+
+cleanup:
+    if (err_msg)
+        g_error_free(err_msg);
+
+    if (parser)
+        g_object_unref(parser);
 }
 
 TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_input_event_face_recognizer_p)
@@ -425,11 +515,37 @@ TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_input_event_face_recognizer_p
     EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
 
     mmi_provider_event_face_recognizer fe = { 0, };
-    fe.type = 0;
-    fe.n_recognizers = 1;
+    fe.type = MMI_FACE_RECOGNIZER_RECOGNIZE_FACE;
+    fe.n_faces = 1;
+    face_result *person1 = (face_result *)malloc(sizeof(face_result));
+    person1->id = strdup("id1");
+    person1->name = strdup("person1");
+    person1->confidence = 0.9;
+    person1->coord_x = 0;
+    person1->coord_y = 0;
+    person1->width = 100;
+    person1->height = 100;
+    fe.recognized_faces_list = g_list_append(fe.recognized_faces_list, person1);
 
     ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_PROVIDER_EVENT_FACE_RECOGNIZER, &fe);
-    EXPECT_EQ(ret, MMI_IU_ERROR_NOT_SUPPORTED_TYPE);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), person1->name);
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_input_event_face_recognizer_n)
+{
+    int ret = mmi_iu_set_output_result_received_callback(face_output_intent_received_cb, NULL);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    mmi_provider_event_face_recognizer fe = { 0, };
+    fe.type = MMI_FACE_RECOGNIZER_RECOGNIZE_FACE;
+    fe.n_faces = 0;
+
+    ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_PROVIDER_EVENT_FACE_RECOGNIZER, &fe);
+    EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+    EXPECT_STREQ(output_action.c_str(), MMI_REASON_NO_RECOGNIZED_FACES);
 }
 
 } // namespace