[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/multimedia/audio-tuning/audio-xml-parser/audio_big_sw/AudioParamParser.h b/src/multimedia/audio-tuning/audio-xml-parser/audio_big_sw/AudioParamParser.h
new file mode 100644
index 0000000..eef274e
--- /dev/null
+++ b/src/multimedia/audio-tuning/audio-xml-parser/audio_big_sw/AudioParamParser.h
@@ -0,0 +1,1425 @@
+/* MediaTek Inc. (C) 2016. All rights reserved.
+ *
+ * Copyright Statement:
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ */
+
+/*
+ * Description:
+ *   Explor all public AudioParamParser APIs
+ */
+
+#ifndef AUDIO_PARAM_PARSER_H
+#define AUDIO_PARAM_PARSER_H
+
+#include <libxml/parser.h>
+#include <libxml/xmlreader.h>
+#include <libxml/tree.h>
+
+#ifdef WIN32
+#pragma warning( disable : 4996 )
+#ifdef __cplusplus
+#define EXPORT extern "C" __declspec(dllexport)
+#else
+#define EXPORT __declspec(dllexport)
+#endif
+#else   /* WIN32*/
+#define EXPORT
+#ifdef __cplusplus
+extern "C" {
+#endif
+#endif
+
+#include "utstring.h"
+#include "uthash.h"
+#include "utlist.h"
+
+#ifndef WIN32
+#include <dlfcn.h>
+#include <pthread.h>
+#if defined(MTK_YOCTO_AUDIO)
+#include <logger/utils/Log.h>
+#else
+#include <utils/Log.h>
+#endif
+
+#endif
+
+/* Enable cus xml support */
+#define APP_FORCE_ENABLE_CUS_XML
+
+/* Debugging Macro Definition */
+//#define FORCE_DEBUG_LEVEL
+
+static const char *XML_FOLDER_LIST_ON_TUNING_TOOL[] = {
+    ".\\preload_xml\\",
+    NULL
+};
+#define XML_CUS_FOLDER_ON_TUNING_TOOL   ".\\cus_xml\\"
+
+static const char *XML_FOLDER_LIST_ON_DEVICE[] = {
+    "/odm/etc/audio_param/",
+    "/vendor/etc/audio_param/",
+    "/system/etc/audio_param/",
+    NULL
+};
+
+/* For AudioParamParser on EM, No valid audio type list */
+static const char *EM_AUDIO_TYPE_LOADING_LIST[] = {
+    NULL
+};
+
+static const char *ATCMDHANDLER_AUDIO_TYPE_LOADING_LIST[] = {
+    "PlaybackACF",
+    "PlaybackDRC",
+    "PlaybackHCF",
+    "PlaybackVolDigi",
+    "SpeechVol",
+    "VoIPVol",
+    "Volume",
+    "VolumeGainMap",
+    NULL
+};
+
+#if defined(SYS_IMPL)
+#define APP_LIB_NAME "libaudio_param_parser-sys.so"
+#else
+#if defined(MTK_YOCTO_AUDIO)
+#define APP_LIB_NAME "libaudioparamparser.so.1.0.0"
+#else
+#define APP_LIB_NAME "libaudio_param_parser-vnd.so"
+#endif
+#endif
+
+#ifndef XML_CUS_FOLDER_ON_DEVICE
+#if defined(MTK_YOCTO_AUDIO)
+#define XML_CUS_FOLDER_ON_DEVICE        "/home/root/.audio_param/"
+#else
+#define XML_CUS_FOLDER_ON_DEVICE        "/data/vendor/audiohal/audio_param/"
+#endif
+#endif
+
+#define MAX_AUDIO_TYPE_LEN 50
+#define INOTIFY_BUF_SIZE 512
+
+#define AUDIO_PARAM_XML_POSFIX          "_AudioParam.xml"
+#define PARAM_UNIT_DESC_XML_POSFIX      "_ParamUnitDesc.xml"
+#define PARAM_TREE_VIEW_XML_POSFIX      "_ParamTreeView.xml"
+#define FEATURE_OPTIONS_XML             "AudioParamOptions.xml"
+
+/* XML element definition */
+#define ELEM_AUDIO_FEATURE_OPTIONS      "AudioParamOptions"
+#define ELEM_PARAM                      "Param"
+#define ELEM_PARAM_UNIT_DESC            "ParamUnitDesc"
+#define ELEM_CATEGORY_TYPE_LIST         "CategoryTypeList"
+#define ELEM_CATEGORY_TYPE              "CategoryType"
+#define ELEM_CATEGORY_GROUP             "CategoryGroup"
+#define ELEM_CATEGORY                   "Category"
+
+#define ELEM_AUDIO_PARAM                "AudioParam"
+#define ELEM_PARAM_TREE                 "ParamTree"
+#define ELEM_PARAM_UNIT_POOL            "ParamUnitPool"
+#define ELEM_PARAM_UNIT                 "ParamUnit"
+#define ELEM_PARAM                      "Param"
+#define ELEM_FIELD                      "Field"
+
+#define ELEM_PARAM_TREE_VIEW            "ParamTreeView"
+#define ELEM_TREE_ROOT                  "TreeRoot"
+#define ELEM_SHEET                      "Sheet"
+#define ELEM_FEATURE                    "Feature"
+#define ELEM_FIELD_LIST                 "FieldList"
+#define ELEM_CATEGORY_PATH_LIST         "CategoryPathList"
+
+/* XML attribute definition */
+#define ATTRI_NAME                      "name"
+#define ATTRI_TAB_NAME                  "tab_name"
+#define ATTRI_VERSION                   "version"
+#define ATTRI_WORDING                   "wording"
+#define ATTRI_PARAM_ID                  "param_id"
+#define ATTRI_PATH                      "path"
+#define ATTRI_VALUE                     "value"
+#define ATTRI_TYPE                      "type"
+#define ATTRI_ARRAY_INDEX               "array_index"
+#define ATTRI_BIT                       "bit"
+#define ATTRI_CHECK_LIST                "check_list"
+#define ATTRI_ALIAS                     "alias"
+#define ATTRI_FEATURE_OPTION            "feature_option"
+#define ATTRI_SWITCH_AUDIO_TYPE         "switch_audio_type"
+#define ATTRI_SWITCH_PARAM              "switch_param"
+#define ATTRI_SWITCH_FIELD              "switch_field"
+#define ATTRI_AUDIO_TYPE                "audio_type"
+#define ATTRI_PARAM                     "param"
+#define ATTRI_VISIBLE                   "visible"
+#define ATTRI_PATH_DESC                 "path_desc"
+
+/* DATA_TYPE string */
+#define DATA_TYPE_UNKNOWN_STRING        "unknown"
+#define DATA_TYPE_STR_STRING            "string"
+#define DATA_TYPE_INT_STRING            "int"
+#define DATA_TYPE_UINT_STRING           "uint"
+#define DATA_TYPE_FLOAT_STRING          "float"
+#define DATA_TYPE_BYTE_ARRAY_STRING     "byte_array"
+#define DATA_TYPE_UBYTE_ARRAY_STRING    "ubyte_array"
+#define DATA_TYPE_SHORT_ARRAY_STRING    "short_array"
+#define DATA_TYPE_USHORT_ARRAY_STRING   "ushort_array"
+#define DATA_TYPE_INT_ARRAY_STRING      "int_array"
+#define DATA_TYPE_UINT_ARRAY_STRING     "uint_array"
+#define DATA_TYPE_DOUBLE_ARRAY_STRING   "double_array"
+#define DATA_TYPE_FIELD_STRING          "Field"
+
+#define ARRAY_SEPERATOR                 ","
+#define ARRAY_SEPERATOR_CH              ','
+#define PARAM_FIELD_NAME_SEPERATOR      "/"
+
+#define AUDIO_TYPE_FMT_STR(STR_LEN) AUDIO_TYPE_FMT(STR_LEN)
+#define AUDIO_TYPE_FMT(STR_LEN) "%"#STR_LEN"[^_]"
+
+#define APP_GET_FIELD_KEY               "APP_GET_FIELD"
+#define APP_GET_FO_KEY                  "APP_GET_FO"
+#define APP_GET_PARAM_KEY               "APP_GET_PARAM"
+#define APP_GET_CATEGORY_KEY            "APP_GET_CATEGORY"
+#define APP_SET_PARAM_KEY               "APP_SET_PARAM"
+#define APP_SET_FIELD_KEY               "APP_SET_FIELD"
+#define APP_SAVE_XML_KEY                "APP_SAVE_XML"
+#define APP_GET_CHECKLIST_KEY           "APP_GET_CHECKLIST"
+
+typedef struct _AppHandle               AppHandle;
+typedef struct _AudioType               AudioType;
+typedef struct _FieldInfo               FieldInfo;
+typedef struct _Category                Category;
+typedef struct _CategoryAlias           CategoryAlias;
+typedef struct _CategoryGroup           CategoryGroup;
+typedef struct _CategoryNameAlias       CategoryNameAlias;
+typedef struct _CategoryPath            CategoryPath;
+typedef struct _CategoryType            CategoryType;
+typedef struct _Feature                 Feature;
+typedef struct _FeatureField            FeatureField;
+typedef struct _FeatureOption           FeatureOption;
+typedef struct _Param                   Param;
+typedef struct _ParamInfo               ParamInfo;
+typedef struct _ParamTreeView           ParamTreeView;
+typedef struct _ParamUnit               ParamUnit;
+typedef struct _TreeRoot                TreeRoot;
+typedef struct _NotifyCb                NotifyCb;
+
+typedef void(*NOTIFY_CB_FUN)(AppHandle *appHandle, const char *audioType);
+
+typedef enum {
+    DEBUG_LEVEL = 0,
+    INFO_LEVEL,
+    WARN_LEVEL,
+    ERR_LEVEL,
+} MSG_LEVEL;
+
+typedef enum {
+    APP_ERROR = 0,
+    APP_NO_ERROR = 1,
+} APP_STATUS;
+
+typedef enum {
+    PARENT_IS_CATEGORY_GROUP = 0,
+    PARENT_IS_CATEGORY_TYPE = 1,
+} CATEGORY_PARENT_TYPE;
+
+/*
+   Due to the system/media/camera/include/system/camera_metadata.h declare the same TYPE_FLOAT enum name,
+   If module include the camera_metadata.h and AudioParamParser.h, AudioParamParser change the DATA_TYPE
+   enum decleration to avoid conflict.
+   User could using the APP_TYPE_FLOAT enum instead the TYPE_FLOAT.
+*/
+#ifndef SYSTEM_MEDIA_INCLUDE_ANDROID_CAMERA_METADATA_H
+typedef enum {
+    TYPE_UNKNOWN = -1,
+    TYPE_STR,
+    TYPE_INT,
+    TYPE_UINT,
+    TYPE_FLOAT,
+    TYPE_BYTE_ARRAY,
+    TYPE_UBYTE_ARRAY,
+    TYPE_SHORT_ARRAY,
+    TYPE_USHORT_ARRAY,
+    TYPE_INT_ARRAY,
+    TYPE_UINT_ARRAY,
+    TYPE_DOUBLE_ARRAY,
+    TYPE_FIELD,
+} DATA_TYPE;
+#else
+typedef enum {
+    APP_TYPE_UNKNOWN = -1,
+    APP_TYPE_STR,
+    APP_TYPE_INT,
+    APP_TYPE_UINT,
+    APP_TYPE_FLOAT,
+    APP_TYPE_BYTE_ARRAY,
+    APP_TYPE_UBYTE_ARRAY,
+    APP_TYPE_SHORT_ARRAY,
+    APP_TYPE_USHORT_ARRAY,
+    APP_TYPE_INT_ARRAY,
+    APP_TYPE_UINT_ARRAY,
+    APP_TYPE_DOUBLE_ARRAY,
+    APP_TYPE_FIELD,
+} DATA_TYPE;
+#endif
+
+typedef union CategoryParent {
+    Category *category;                 /* Link to parent Category if it's not CategoryGroup */
+    CategoryType *categoryType;         /* Link to parent CategoryType if it's CategoryGroup */
+} CategoryParent;
+
+/* UHash the parameter tree info from ParamTreeView.xml */
+struct _CategoryPath {
+    char *path;
+    Feature *feature;
+    UT_hash_handle hh;
+};
+
+struct _FeatureField {
+    FieldInfo *fieldInfo;
+    UT_hash_handle hh;
+};
+
+struct _Feature {
+    char *name;
+    char *featureOption;
+    FieldInfo *switchFieldInfo;
+    CategoryPath *categoryPathHash;
+    FeatureField *featureFieldHash;
+    AudioType *audioType;
+    UT_hash_handle hh;
+};
+
+struct _TreeRoot {
+    char *name;                     /* Key */
+    FieldInfo *switchFieldInfo;
+    xmlNode *treeRootNode;          /* Used to traversal tree */
+    Feature *featureHash;           /* Used to opt feature information */
+    ParamTreeView *paramTreeView;   /* Belong to which paramTreeView */
+    UT_hash_handle hh;
+};
+
+struct _ParamTreeView {
+    int verMaj;
+    int verMin;
+    AudioType *audioType;
+    TreeRoot *treeRootHash;
+};
+
+/* Hash the Param & Field info from ParamUnitDesc.xml */
+struct _FieldInfo {
+    char *name;                         /* key */
+    size_t arrayIndex;
+    int startBit;
+    int endBit;
+    char *checkListStr;                 /* check list string array */
+    struct _ParamInfo *paramInfo;       /* Link to parent ParamInfo */
+    UT_hash_handle hh;                  /* hash handle */
+};
+
+struct _ParamInfo {
+    char *name;                         /* key */
+    DATA_TYPE dataType;
+    struct _FieldInfo *fieldInfoHash;
+    AudioType *audioType;               /* Link to parent AudioType */
+    UT_hash_handle hh;                  /* hash handle */
+};
+
+/* Hash the param name with value from AudioParam.xml */
+struct _Param {
+    char *name;                         /* key */
+    void *data;                         /* raw data */
+    size_t arraySize;                   /* Array size if the data is the array pointer */
+    ParamInfo *paramInfo;
+    struct _ParamUnit *paramUnit;       /* Link to it's ParamUnit */
+    UT_hash_handle hh;                  /* hash handle */
+};
+
+/* Hash the id with ParamUnit from AudioParam.xml */
+struct _ParamUnit {
+    int paramId;                        /* key */
+    int refCount;
+    AudioType *audioType;               /* Link to it's AudioType */
+    struct _Param *paramHash;           /* ParamUnit's params */
+    UT_hash_handle hh;
+};
+
+/* Hash ParamTree info from AudioParam.xml */
+typedef struct {
+    char *categoryPath;                 /* key */
+    int paramId;                        /* Param id */
+    UT_hash_handle hh;
+} ParamTree;
+
+struct _Category {
+    char *wording;                      /* key */
+    char *name;
+    int visible;
+    CategoryParent parent;
+    CATEGORY_PARENT_TYPE parentType;
+    UT_hash_handle hh;                 /* Used to handle CategoryType->categoryHash */
+    UT_hash_handle hh2;                 /* Used to handle CategoryType->allCategoryHash */
+};
+
+struct _CategoryAlias {
+    char *alias;                        /* key */
+    Category *category;
+    UT_hash_handle hh;
+};
+
+struct _CategoryGroup {
+    char *wording;                      /* key */
+    char *name;
+    int visible;
+    Category *categoryHash;             /* Link to children */
+    CategoryType *categoryType;         /* Link to parent */
+    UT_hash_handle hh;
+};
+
+struct _CategoryType {
+    char *wording;                      /* key */
+    char *name;
+    int visible;
+    CategoryGroup *categoryGroupHash;   /* Link to children */
+    Category *categoryHash;             /* Link to children (not include these category under CategoryGroup) */
+    Category *allCategoryHash;          /* Link to children (include these category under CategoryGroup) */
+    CategoryAlias *categoryAliasHash;   /* Save category alias information */
+    AudioType *audioType;               /* Link to parent */
+    UT_hash_handle hh;
+};
+
+struct _AudioType {
+    char *name;
+    char *tabName;
+    int paramUnitDescVerMaj;            /* ParamUniDesc version */
+    int paramUnitDescVerMin;
+    int audioParamVerMaj;               /* AudioParam version */
+    int audioParamVerMin;
+    xmlDocPtr audioParamDoc;
+    xmlDocPtr paramUnitDescDoc;
+    xmlDocPtr paramTreeViewDoc;
+    ParamTree *paramTreeHash;
+    ParamUnit *paramUnitHash;
+    ParamInfo *paramInfoHash;
+    ParamTreeView *paramTreeView;
+    int unusedParamId;
+    int dirty;                          /* Indicate if the audio type modified without saveing*/
+    int allowReload;                    /* Indicate the audio type can be reload since xml updated */
+    CategoryType *categoryTypeHash;
+#ifndef WIN32
+    pthread_rwlock_t lock;
+    const char *lockCallerFun;          /* Used to cache the lock holder */
+#endif
+    AppHandle *appHandle;               /* Link to it's appHandle parent */
+    UT_hash_handle hh;
+};
+
+struct _FeatureOption {
+    char *name;
+    char *value;
+    UT_hash_handle hh;
+};
+
+struct _NotifyCb {
+    NOTIFY_CB_FUN cb;
+    struct _NotifyCb *next, *pre;
+};
+
+struct _AppHandle {
+    const char **xmlDir;
+    char *xmlCusDir;
+    AudioType *audioTypeHash;
+    FeatureOption *featureOptionsHash;
+    xmlDocPtr featureOptionsDoc;
+    int xmlCusDirReady;
+    int xmlChangedNotifyEnabled;        /* Used to identify notify enabled */
+#ifndef WIN32
+    pthread_t appThread;
+    int appThreadExit;                  /* Used to identify thread exit */
+    int inotifyFd;
+    pthread_rwlock_t lock;
+    pthread_rwlock_t notifyLock;
+    const char *lockCallerFun;          /* Used to cache the lock holder */
+#endif
+    NotifyCb *noficyCbList;
+    int saveXmlWithHexMode;
+    int normalizeXmlContent;            /* Breakdown all parameter tree element & add category path */
+};
+
+typedef struct AudioTypeVerInfo {
+    const char *audioTypeName;
+    int paramUnitDescVerMaj;
+    int paramUnitDescVerMin;
+    int audioParamVerMaj;
+    int audioParamVerMin;
+} AudioTypeVerInfo;
+
+/*
+   AudioParamParser will built-in ParamUnitDesc/AudioParam's maj number checking,
+   The ParamUnitDesc/AudioParam's min number is checking by client.
+*/
+static const AudioTypeVerInfo audioTypeSupportVerInfo [] = {
+    /* AudioType name, ParamUnitDescVer (maj, min), AudioParamVer (maj, min) */
+    {"AudioCommonSetting",  1, 0, 1, 0},
+    {"PlaybackACF",         1, 0, 1, 0},
+    {"Playback",            1, 0, 1, 0},
+    {"PlaybackDRC",         1, 0, 1, 0},
+    {"PlaybackHCF",         1, 0, 1, 0},
+    {"PlaybackVolAna",      1, 0, 1, 0},
+    {"PlaybackVolDigi",     1, 0, 1, 0},
+    {"PlaybackVolUI",       1, 0, 1, 0},
+    {"Record",              1, 0, 1, 0},
+    {"RecordDMNR",          1, 0, 1, 0},
+    {"RecordFIR",           1, 0, 1, 0},
+    {"RecordUI",            1, 0, 1, 0},
+    {"RecordVol",           1, 0, 1, 0},
+    {"RecordVolUI",         1, 0, 1, 0},
+    {"Speech",              1, 0, 1, 0},
+    {"SpeechDMNR",          1, 0, 1, 0},
+    {"SpeechGeneral",       1, 0, 1, 0},
+    {"SpeechMagiClarity",   1, 0, 1, 0},
+    {"SpeechUI",            1, 0, 1, 0},
+    {"SpeechVol",           1, 0, 1, 0},
+    {"SpeechVolUI",         1, 0, 1, 0},
+    {"VoIP",                1, 0, 1, 0},
+    {"VoIPDMNR",            1, 0, 1, 0},
+    {"VoIPGeneral",         1, 0, 1, 0},
+    {"VoIPUI",              1, 0, 1, 0},
+    {"VoIPVol",             1, 0, 1, 0},
+    {"VoIPVolUI",           1, 0, 1, 0},
+    {"Volume",              1, 0, 1, 0},
+    {"VolumeGainMap",       1, 0, 1, 0},
+    {"SpeechDeReverb",      1, 0, 1, 0},
+    {NULL,                  0, 0, 0, 0}
+};
+
+typedef struct AppOps {
+    void            *handle;
+    AppHandle       *(*appHandleGetInstance)(void);
+
+    int              (*appSetAudioTypeLoadingList)(const char *audioTypeLoadingList[]);
+    const char      *(*appGetAudioTypeLoadingList)(void);
+
+    void             (*appSetDebugLevel)(MSG_LEVEL level);
+    MSG_LEVEL        (*appGetDebugLevel)(void);
+
+    APP_STATUS       (*appHandleInit)(AppHandle *appHandle);
+    APP_STATUS       (*appHandleUninit)(AppHandle *appHandle);
+    void             (*appHandleRedirectIOToConsole)(void);
+    size_t           (*appHandleGetNumOfAudioType)(AppHandle *appHandle);
+    AudioType       *(*appHandleGetAudioTypeByIndex)(AppHandle *appHandle, size_t index);
+    AudioType       *(*appHandleGetAudioTypeByName)(AppHandle *appHandle, const char *name);
+    const char      *(*appHandleGetFeatureOptionValue)(AppHandle *appHandle, const char *featureOptionName);
+    int              (*appHandleIsFeatureOptionEnabled)(AppHandle *appHandle, const char *featureOptionName);
+    size_t           (*appHandleGetNumOfFeatureOption)(AppHandle *appHandle);
+    FeatureOption   *(*appHandleGetFeatureOptionByIndex)(AppHandle *appHandle, size_t index);
+    const char      *(*appHandleGetBuildTimeStamp)(void);
+    APP_STATUS       (*appHandleCompressFiles)(const char *srcDir, const char *destFile);
+    APP_STATUS       (*appHandleUncompressFile)(const char *srcFile, const char *destDir);
+
+    /* Following 2 APIs will acquire app handle write lock automatically */
+    APP_STATUS       (*appHandleParseXml)(AppHandle *appHandle, const char *dir[], const char *cusDir);
+    APP_STATUS       (*appHandleReloadAudioType)(AppHandle *appHandle, const char *audioTypeName);
+
+    /* AudioType API */
+    APP_STATUS       (*audioTypeIsTuningToolSupportedXmlVer)(AudioType *audioType);
+    APP_STATUS       (*audioTypeIsDeviceSupportedXmlVer)(AudioType *audioType);
+    size_t           (*audioTypeGetNumOfCategoryType)(AudioType *audioType);
+    CategoryType    *(*audioTypeGetCategoryTypeByIndex)(AudioType *audioType, size_t idnex);
+    CategoryType    *(*audioTypeGetCategoryTypeByName)(AudioType *audioType, const char *categoryTypeName);
+    CategoryType    *(*audioTypeGetCategoryTypeByWording)(AudioType *audioType, const char *categoryTypeWording);
+    xmlNode         *(*audioTypeGetCategoryTypeListNode)(AudioType *audioType);
+    xmlNode         *(*audioTypeGetParamUnitNode)(AudioType *audioType);
+    ParamUnit       *(*audioTypeGetParamUnit)(AudioType *audioType, const char *categoryPath);
+    size_t           (*audioTypeGetNumOfParamInfo)(AudioType *audioType);
+    ParamInfo       *(*audioTypeGetParamInfoByIndex)(AudioType *audioType, size_t index);
+    ParamInfo       *(*audioTypeGetParamInfoByName)(AudioType *audioType, const char *paramName);
+    APP_STATUS       (*audioTypeSaveAudioParamXml)(AudioType *audioType, const char *saveDir, int clearDirtyBit);
+    int              (*audioTypeReadLock)(AudioType *audioType, const char *callerFun);
+    int              (*audioTypeWriteLock)(AudioType *audioType, const char *callerFun);
+    int              (*audioTypeUnlock)(AudioType *audioType);
+    TreeRoot        *(*audioTypeGetTreeRoot)(AudioType *audioType, const char *treeRootName);
+
+    /* Following 3 write APIs will acquire write lock automatically */
+    APP_STATUS       (*audioTypeSetParamData)(AudioType *audioType, const char *categoryPath, ParamInfo *paramName, void *dataPtr, int arraySize);
+    APP_STATUS       (*audioTypeSetFieldData)(AudioType *audioType, const char *categoryPath, FieldInfo *fieldInfo, unsigned int val);
+    APP_STATUS       (*audioTypeParamUnitCopy)(AudioType *audioType, const char *srcCategoryPath, const char *dstCategoryPath);
+
+    /* CategoryType API */
+    size_t           (*categoryTypeGetNumOfCategoryGroup)(CategoryType *categoryType);
+    CategoryGroup   *(*categoryTypeGetCategoryGroupByIndex)(CategoryType *categoryType, size_t index);
+    CategoryGroup   *(*categoryTypeGetCategoryGroupByWording)(CategoryType *categoryType, const char *wording);
+    size_t           (*categoryTypeGetNumOfCategory)(CategoryType *categoryType);
+    Category        *(*categoryTypeGetCategoryByIndex)(CategoryType *categoryType, size_t index);
+    Category        *(*categoryTypeGetCategoryByWording)(CategoryType *categoryType, const char *wording);
+    Category        *(*categoryTypeGetCategoryByName)(CategoryType *categoryType, const char *name);
+
+    /* CategoryGroup API */
+    size_t           (*categoryGroupGetNumOfCategory)(CategoryGroup *categoryGroup);
+    Category        *(*categoryGroupGetCategoryByIndex)(CategoryGroup *categoryGroup, size_t index);
+    Category        *(*categoryGroupGetCategoryByWording)(CategoryGroup *categoryGroup, const char *index);
+
+    /* CategoryAlias API */
+    CategoryAlias   *(*categoryAliasCreate)(const char *alias, Category *category);
+    void             (*categoryAliasRelease)(CategoryAlias *categoryAlias);
+
+    /* ParamInfo API */
+    size_t           (*paramInfoGetNumOfFieldInfo)(ParamInfo *paramInfo);
+    FieldInfo       *(*paramInfoGetFieldInfoByIndex)(ParamInfo *paramInfo, size_t index);
+    FieldInfo       *(*paramInfoGetFieldInfoByName)(ParamInfo *paramInfo, const char *fieldName);
+    char            *(*paramNewDataStr)(Param *param);
+    char            *(*paramNewDataStrWithMode)(Param *param, int uArrayHexMode);
+
+    /* ParamUnit API */
+    size_t           (*paramUnitGetNumOfParam)(ParamUnit *paramUnit);
+    Param           *(*paramUnitGetParamByIndex)(ParamUnit *paramUnit, size_t index);
+    Param           *(*paramUnitGetParamByName)(ParamUnit *paramUnit, const char *paramName);
+    ParamInfo       *(*paramUnitGetParamInfo)(ParamUnit *paramUnit, const char *paramInfoName);
+    FieldInfo       *(*paramUnitGetFieldInfo)(ParamUnit *paramUnit, const char *paramName, const char *fieldName);
+    APP_STATUS       (*paramUnitGetFieldVal)(ParamUnit *paramUnit, const char *paramName, const char *fieldName, unsigned int *val);
+
+    /* Param API */
+    size_t           (*paramGetArraySizeFromString)(const char *str);
+    size_t           (*paramGetNumOfBytes)(Param *param);
+    APP_STATUS       (*paramGetFieldVal)(Param *param, FieldInfo *fieldInfo, unsigned int *val);
+    APP_STATUS       (*paramSetFieldVal)(Param *param, FieldInfo *fieldInfo, unsigned int val);
+    DATA_TYPE        (*paramDataTypeToEnum)(const char *dataType);
+    const char      *(*paramDataTypeToStr)(DATA_TYPE dataType);
+
+    /* Field API */
+    APP_STATUS       (*fieldInfoGetCheckListValue)(FieldInfo *fieldInfo, const char *checkName, unsigned int *checkVal);
+
+    /* TreeRoot API */
+    Feature         *(*treeRootGetFeatureByName)(TreeRoot *treeRoot, const char *featureName);
+    int              (*featureIsCategoryPathSupport)(Feature *feature, const char *categoryPath);
+
+    /* Xml Node related APIs */
+    xmlNode         *(*findXmlNodeByElemName)(xmlNode *node, const char *elemName);
+    xmlChar         *(*xmlNodeGetProp)(xmlNode *node, const char *prop);
+    xmlChar         *(*xmlNodeGetWording)(xmlNode *node);
+
+    /* Control cust XML enabl API */
+    void             (*appHandleCustXmlEnableChanged)(AppHandle* appHandle, int enable);
+
+    /* XML changed callback APIs */
+    void             (*appHandleRegXmlChangedCb)(AppHandle *appHandle, NOTIFY_CB_FUN nofiyCallback);
+    void             (*appHandleUnregXmlChangedCb)(AppHandle *appHandle, NOTIFY_CB_FUN nofiyCallback);
+
+    /* Utils APIs */
+    APP_STATUS       (*utilConvDataStringToNative)(DATA_TYPE dataType, const char *paramDataStr, void **paramData, size_t *arraySize);
+
+    /* Unit test */
+    APP_STATUS       (*unitTest)(AppHandle *appHandle);
+    char            *(*utilGetStdin)(char *buf, int bufSize);
+
+    /* Following APIs is designed for EM tool integration */
+    APP_STATUS       (*utilNativeSetField)(const char *audioTypeName, const char *categoryPath, const char *paramName, const char *fieldName, const char *fieldValueStr);
+    APP_STATUS       (*utilNativeSetParam)(const char *audioTypeName, const char *categoryPath, const char *paramName, const char *paramDataStr);
+    char            *(*utilNativeGetCategory)(const char *audioTypeName, const char *categoryTypeName);
+    char            *(*utilNativeGetParam)(const char *audioTypeName, const char *categoryPath, const char *paramName);
+    unsigned int     (*utilNativeGetField)(const char *audioTypeName, const char *categoryPath, const char *paramName, const char *fieldName);
+    APP_STATUS       (*utilNativeSaveXml)(const char *audioTypeName);
+    const char      *(*utilNativeGetChecklist)(const char *audioTypeName, const char *paramName, const char *fieldName);
+} AppOps;
+
+extern const char **appAudioTypeLoadingList;
+extern int          appDebugLevel;
+static AppOps       appOps;
+static short        appOpsInited = 0;
+
+#ifndef WIN32
+EXPORT static AppOps *appOpsGetInstance(void) {
+const char *error;
+const char *funName = NULL;
+
+if (appOpsInited == 0) {
+    ALOGD("%s(), init AppOps struct, lib is %s", __FUNCTION__, APP_LIB_NAME);
+
+    /* dlopen */
+    appOps.handle = dlopen(APP_LIB_NAME, RTLD_LAZY);
+    if (!appOps.handle) {
+        ALOGE("%s(), dlopen fail! (%s)\n", __FUNCTION__, dlerror());
+        return NULL;
+    }
+    dlerror();    /* Clear any existing error */
+
+    funName = "appHandleGetInstance";
+    appOps.appHandleGetInstance = (AppHandle * ( *)(void)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* dlsym */
+    funName = "appSetAudioTypeLoadingList";
+    appOps.appSetAudioTypeLoadingList = (int ( *)(const char *audioTypeLoadingList[])) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appGetAudioTypeLoadingList";
+    appOps.appGetAudioTypeLoadingList = (const char*( *)(void)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appSetDebugLevel";
+    appOps.appSetDebugLevel = (void ( *)(MSG_LEVEL level)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appGetDebugLevel";
+    appOps.appGetDebugLevel = (MSG_LEVEL( *)(void)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* appHandle API */
+    funName = "appHandleInit";
+    appOps.appHandleInit = (APP_STATUS( *)(AppHandle * appHandle)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleUninit";
+    appOps.appHandleUninit = (APP_STATUS( *)(AppHandle * appHandle)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleRedirectIOToConsole";
+    appOps.appHandleRedirectIOToConsole = (void ( *)(void)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleGetNumOfAudioType";
+    appOps.appHandleGetNumOfAudioType = (size_t ( *)(AppHandle * appHandle)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleGetAudioTypeByIndex";
+    appOps.appHandleGetAudioTypeByIndex = (AudioType * ( *)(AppHandle * appHandle, size_t index)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleGetAudioTypeByName";
+    appOps.appHandleGetAudioTypeByName = (AudioType * ( *)(AppHandle * appHandle, const char * name)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleGetFeatureOptionValue";
+    appOps.appHandleGetFeatureOptionValue = (const char * ( *)(AppHandle * appHandle, const char * featureOptionName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleIsFeatureOptionEnabled";
+    appOps.appHandleIsFeatureOptionEnabled = (int ( *)(AppHandle * appHandle, const char * featureOptionName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleGetNumOfFeatureOption";
+    appOps.appHandleGetNumOfFeatureOption = (size_t ( *)(AppHandle * appHandle)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleGetFeatureOptionByIndex";
+    appOps.appHandleGetFeatureOptionByIndex = (FeatureOption * ( *)(AppHandle * appHandle, size_t index)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleGetBuildTimeStamp";
+    appOps.appHandleGetBuildTimeStamp = (const char * ( *)(void)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleCompressFiles";
+    appOps.appHandleCompressFiles = (APP_STATUS( *)(const char * srcDir, const char * destFile)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleUncompressFile";
+    appOps.appHandleUncompressFile = (APP_STATUS( *)(const char * srcFile, const char * destDir)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* Following 2 APIs will acquire app handle write lock automatically */
+    funName = "appHandleParseXml";
+    appOps.appHandleParseXml = (APP_STATUS( *)(AppHandle * appHandle, const char * dir[], const char * cusDir)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleReloadAudioType";
+    appOps.appHandleReloadAudioType = (APP_STATUS( *)(AppHandle * appHandle, const char * audioTypeName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* AudioType API */
+    funName = "audioTypeIsTuningToolSupportedXmlVer";
+    appOps.audioTypeIsTuningToolSupportedXmlVer = (APP_STATUS( *)(AudioType * audioType)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeIsDeviceSupportedXmlVer";
+    appOps.audioTypeIsDeviceSupportedXmlVer = (APP_STATUS( *)(AudioType * audioType)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeGetNumOfCategoryType";
+    appOps.audioTypeGetNumOfCategoryType = (size_t ( *)(AudioType * audioType)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeGetCategoryTypeByIndex";
+    appOps.audioTypeGetCategoryTypeByIndex = (CategoryType * ( *)(AudioType * audioType, size_t idnex)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeGetCategoryTypeByName";
+    appOps.audioTypeGetCategoryTypeByName = (CategoryType * ( *)(AudioType * audioType, const char * categoryTypeName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeGetCategoryTypeByWording";
+    appOps.audioTypeGetCategoryTypeByWording = (CategoryType * ( *)(AudioType * audioType, const char * categoryTypeWording)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeGetCategoryTypeListNode";
+    appOps.audioTypeGetCategoryTypeListNode = (xmlNode * ( *)(AudioType * audioType)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeGetParamUnitNode";
+    appOps.audioTypeGetParamUnitNode = (xmlNode * ( *)(AudioType * audioType)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeGetParamUnit";
+    appOps.audioTypeGetParamUnit = (ParamUnit * ( *)(AudioType * audioType, const char * categoryPath)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeGetNumOfParamInfo";
+    appOps.audioTypeGetNumOfParamInfo = (size_t ( *)(AudioType * audioType)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeGetParamInfoByIndex";
+    appOps.audioTypeGetParamInfoByIndex = (ParamInfo * ( *)(AudioType * audioType, size_t index)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeGetParamInfoByName";
+    appOps.audioTypeGetParamInfoByName = (ParamInfo * ( *)(AudioType * audioType, const char * paramName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeSaveAudioParamXml";
+    appOps.audioTypeSaveAudioParamXml = (APP_STATUS( *)(AudioType * audioType, const char * saveDir, int clearDirtyBit)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeReadLock";
+    appOps.audioTypeReadLock = (int ( *)(AudioType * audioType, const char * callerFun)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeWriteLock";
+    appOps.audioTypeWriteLock = (int ( *)(AudioType * audioType, const char * callerFun)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeUnlock";
+    appOps.audioTypeUnlock = (int ( *)(AudioType * audioType)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeGetTreeRoot";
+    appOps.audioTypeGetTreeRoot = (TreeRoot * ( *)(AudioType * audioType, const char * treeRootName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* Following 3 write APIs will acquire write lock automatically */
+    funName = "audioTypeSetParamData";
+    appOps.audioTypeSetParamData = (APP_STATUS( *)(AudioType * audioType, const char * categoryPath, ParamInfo * paramName, void * dataPtr, int arraySize)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeSetFieldData";
+    appOps.audioTypeSetFieldData = (APP_STATUS( *)(AudioType * audioType, const char * categoryPath, FieldInfo * fieldInfo, unsigned int val)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "audioTypeParamUnitCopy";
+    appOps.audioTypeParamUnitCopy = (APP_STATUS( *)(AudioType * audioType, const char * srcCategoryPath, const char * dstCategoryPath)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* CategoryType API */
+    funName = "categoryTypeGetNumOfCategoryGroup";
+    appOps.categoryTypeGetNumOfCategoryGroup = (size_t ( *)(CategoryType * categoryType)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "categoryTypeGetCategoryGroupByIndex";
+    appOps.categoryTypeGetCategoryGroupByIndex = (CategoryGroup * ( *)(CategoryType * categoryType, size_t index)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "categoryTypeGetCategoryGroupByWording";
+    appOps.categoryTypeGetCategoryGroupByWording = (CategoryGroup * ( *)(CategoryType * categoryType, const char * wording)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "categoryTypeGetNumOfCategory";
+    appOps.categoryTypeGetNumOfCategory = (size_t ( *)(CategoryType * categoryType)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "categoryTypeGetCategoryByIndex";
+    appOps.categoryTypeGetCategoryByIndex = (Category * ( *)(CategoryType * categoryType, size_t index)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "categoryTypeGetCategoryByWording";
+    appOps.categoryTypeGetCategoryByWording = (Category * ( *)(CategoryType * categoryType, const char * wording)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "categoryTypeGetCategoryByName";
+    appOps.categoryTypeGetCategoryByName = (Category * ( *)(CategoryType * categoryType, const char * name)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* CategoryGroup API */
+    funName = "categoryGroupGetNumOfCategory";
+    appOps.categoryGroupGetNumOfCategory = (size_t ( *)(CategoryGroup * categoryGroup)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "categoryGroupGetCategoryByIndex";
+    appOps.categoryGroupGetCategoryByIndex = (Category * ( *)(CategoryGroup * categoryGroup, size_t index)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "categoryGroupGetCategoryByWording";
+    appOps.categoryGroupGetCategoryByWording = (Category * ( *)(CategoryGroup * categoryGroup, const char * index)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* CategoryAlias API */
+    funName = "categoryAliasCreate";
+    appOps.categoryAliasCreate = (CategoryAlias * ( *)(const char * alias, Category * category)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "categoryAliasRelease";
+    appOps.categoryAliasRelease = (void ( *)(CategoryAlias * categoryAlias)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* ParamInfo API */
+    funName = "paramInfoGetNumOfFieldInfo";
+    appOps.paramInfoGetNumOfFieldInfo = (size_t ( *)(ParamInfo * paramInfo)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramInfoGetFieldInfoByIndex";
+    appOps.paramInfoGetFieldInfoByIndex = (FieldInfo * ( *)(ParamInfo * paramInfo, size_t index)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramInfoGetFieldInfoByName";
+    appOps.paramInfoGetFieldInfoByName = (FieldInfo * ( *)(ParamInfo * paramInfo, const char * fieldName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramNewDataStr";
+    appOps.paramNewDataStr = (char * ( *)(Param * param)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramNewDataStrWithMode";
+    appOps.paramNewDataStrWithMode = (char * ( *)(Param * param, int uArrayHexMode)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* ParamUnit API */
+    funName = "paramUnitGetNumOfParam";
+    appOps.paramUnitGetNumOfParam = (size_t ( *)(ParamUnit * paramUnit)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramUnitGetParamByIndex";
+    appOps.paramUnitGetParamByIndex = (Param * ( *)(ParamUnit * paramUnit, size_t index)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramUnitGetParamByName";
+    appOps.paramUnitGetParamByName = (Param * ( *)(ParamUnit * paramUnit, const char * paramName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramUnitGetParamInfo";
+    appOps.paramUnitGetParamInfo = (ParamInfo * ( *)(ParamUnit * paramUnit, const char * paramInfoName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramUnitGetFieldInfo";
+    appOps.paramUnitGetFieldInfo = (FieldInfo * ( *)(ParamUnit * paramUnit, const char * paramName, const char * fieldName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramUnitGetFieldVal";
+    appOps.paramUnitGetFieldVal = (APP_STATUS( *)(ParamUnit * paramUnit, const char * paramName, const char * fieldName, unsigned int * val)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* Param API */
+    funName = "paramGetArraySizeFromString";
+    appOps.paramGetArraySizeFromString = (size_t ( *)(const char * str)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramGetNumOfBytes";
+    appOps.paramGetNumOfBytes = (size_t ( *)(Param * param)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramGetFieldVal";
+    appOps.paramGetFieldVal = (APP_STATUS( *)(Param * param, FieldInfo * fieldInfo, unsigned int * val)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramSetFieldVal";
+    appOps.paramSetFieldVal = (APP_STATUS( *)(Param * param, FieldInfo * fieldInfo, unsigned int val)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramDataTypeToEnum";
+    appOps.paramDataTypeToEnum = (DATA_TYPE( *)(const char * dataType)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "paramDataTypeToStr";
+    appOps.paramDataTypeToStr = (const char * ( *)(DATA_TYPE dataType)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* Field API */
+    funName = "fieldInfoGetCheckListValue";
+    appOps.fieldInfoGetCheckListValue = (APP_STATUS( *)(FieldInfo * fieldInfo, const char * checkName, unsigned int * checkVal)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* TreeRoot API */
+    funName = "treeRootGetFeatureByName";
+    appOps.treeRootGetFeatureByName = (Feature * ( *)(TreeRoot * treeRoot, const char * featureName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "featureIsCategoryPathSupport";
+    appOps.featureIsCategoryPathSupport = (int ( *)(Feature * feature, const char * categoryPath)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* Xml Node related APIs */
+    funName = "findXmlNodeByElemName";
+    appOps.findXmlNodeByElemName = (xmlNode * ( *)(xmlNode * node, const char * elemName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "xmlNodeGetProp";
+    appOps.xmlNodeGetProp = (xmlChar * ( *)(xmlNode * node, const char * prop)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "xmlNodeGetWording";
+    appOps.xmlNodeGetWording = (xmlChar * ( *)(xmlNode * node)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleCustXmlEnableChanged";
+    appOps.appHandleCustXmlEnableChanged = (void ( *)(AppHandle * appHandle, int enable)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* XML changed callback APIs */
+    funName = "appHandleRegXmlChangedCb";
+    appOps.appHandleRegXmlChangedCb = (void ( *)(AppHandle * appHandle, NOTIFY_CB_FUN nofiyCallback)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "appHandleUnregXmlChangedCb";
+    appOps.appHandleUnregXmlChangedCb = (void ( *)(AppHandle * appHandle, NOTIFY_CB_FUN nofiyCallback)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* Utils APIs */
+    funName = "utilConvDataStringToNative";
+    appOps.utilConvDataStringToNative = (APP_STATUS( *)(DATA_TYPE dataType, const char * paramDataStr, void **paramData, size_t * arraySize)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* Unit test */
+    funName = "unitTest";
+    appOps.unitTest = (APP_STATUS( *)(AppHandle * appHandle)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "utilGetStdin";
+    appOps.utilGetStdin = (char * ( *)(char * buf, int bufSize)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    /* Following APIs is designed for EM tool integration */
+    funName = "utilNativeSetField";
+    appOps.utilNativeSetField = (APP_STATUS( *)(const char * audioTypeName, const char * categoryPath, const char * paramName, const char * fieldName, const char * fieldValueStr)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "utilNativeSetParam";
+    appOps.utilNativeSetParam = (APP_STATUS( *)(const char * audioTypeName, const char * categoryPath, const char * paramName, const char * paramDataStr)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "utilNativeGetCategory";
+    appOps.utilNativeGetCategory = (char * ( *)(const char * audioTypeName, const char * categoryTypeName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "utilNativeGetParam";
+    appOps.utilNativeGetParam = (char * ( *)(const char * audioTypeName, const char * categoryPath, const char * paramName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "utilNativeGetField";
+    appOps.utilNativeGetField = (unsigned int ( *)(const char * audioTypeName, const char * categoryPath, const char * paramName, const char * fieldName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "utilNativeSaveXml";
+    appOps.utilNativeSaveXml = (APP_STATUS( *)(const char * audioTypeName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    funName = "utilNativeGetChecklist";
+    appOps.utilNativeGetChecklist = (const char * ( *)(const char * audioTypeName, const char * paramName, const char * fieldName)) dlsym(appOps.handle, funName);
+    error = dlerror();
+    if (error != NULL) {
+        ALOGE("%s(), dlsym %s fail. (%s)\n", __FUNCTION__, funName, error);
+        return NULL;
+    }
+
+    appOpsInited = 1;
+}
+
+return &appOps;
+}
+
+EXPORT static __attribute__((unused)) int appIsFeatureOptionEnabled(const char* fo) {
+    AppOps* appOps = appOpsGetInstance();
+    if (appOps == NULL) {
+        ALOGE("%s(), AppOps is NULL!\n", __FUNCTION__);
+        return -1;
+    }
+
+    AppHandle *appHandle = appOps->appHandleGetInstance();
+    if (appHandle == NULL) {
+        ALOGE("%s(), AppHandle is NULL!\n", __FUNCTION__);
+        return -1;
+    }
+
+    return appOps->appHandleIsFeatureOptionEnabled(appHandle, fo);
+}
+
+EXPORT static __attribute__((unused)) const char* appGetFeatureOptionValue(const char* fo) {
+    AppOps* appOps = appOpsGetInstance();
+    if (appOps == NULL) {
+        ALOGE("%s(), AppOps is NULL!\n", __FUNCTION__);
+        return NULL;
+    }
+
+    AppHandle *appHandle = appOps->appHandleGetInstance();
+    if (appHandle == NULL) {
+        ALOGE("%s(), AppHandle is NULL!\n", __FUNCTION__);
+        return NULL;
+    }
+
+    return appOps->appHandleGetFeatureOptionValue(appHandle, fo);
+}
+
+static __attribute__((unused)) void appOpsDelInstance() {
+if (appOpsInited == 1) {
+    dlclose(appOps.handle);
+    appOps.handle = NULL;
+    appOpsInited = 0;
+}
+}
+#endif
+
+#ifndef WIN32
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif