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 7a646f0..3084847 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 6d83053..5f3e561 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 e0bd49c..1206dcc 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 3e51599..0b19f27 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 7672a6b..72f0079 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 5db6ed1..4d9dc71 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 394b168..2082fca 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 8a6c1a1..fddb0aa 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