libvideorender: CB2 fix nplb crash [1/1]

PD#SWPL-159621

Problem:
crash happend when invoking resMgrTerm immediately
after resMgrReleaseDecoder. essos manager post semaphore
to release resource in thread. but resMgrTerm destroy essos
instance.so crashed

Solution:
1.add callback to process essos event
2.resMgrReleaseDecoder at libvideorender release

Verify:
ap222

Change-Id: I68fd48963237268354cd7fd2ae6b0069294c5409
Signed-off-by: fei.deng <fei.deng@amlogic.com>
diff --git a/westeros/Makefile b/westeros/Makefile
index 9f5ddd2..08a5eff 100644
--- a/westeros/Makefile
+++ b/westeros/Makefile
@@ -76,6 +76,7 @@
 	-I../ \
 	-I$(TOOLS_PATH) \
 	-I$(STAGING_DIR)/usr/include \
+	-I./essos \
 	$(VERSION_CFLAGS) \
 
 OBJ_CLIENT_LIB += \
@@ -94,8 +95,8 @@
 
 all: $(GENERATED_SOURCES) $(TARGET)
 
-LD_FLAG = -g -fPIC -O -Wcpp -lm -lpthread -lz -Wl,-Bsymbolic -ldl
-LD_FLAG_LIB = $(LD_FLAG) -shared $(LD_SUPPORT) -llog
+LD_FLAG = -L./essos -g -fPIC -O -Wcpp -lm -lpthread -lz -Wl,-Bsymbolic -ldl
+LD_FLAG_LIB = $(LD_FLAG) -shared $(LD_SUPPORT) -llog -lessosrmgr
 
 %.o:%.c $(DEPS)
 	echo CC $@ $< $(FLAGS)
diff --git a/westeros/essos/essos-resmgr.h b/westeros/essos/essos-resmgr.h
new file mode 100644
index 0000000..841561e
--- /dev/null
+++ b/westeros/essos/essos-resmgr.h
@@ -0,0 +1,304 @@
+/*
+ * If not stated otherwise in this file or this component's Licenses.txt file the
+ * following copyright and licenses apply:
+ *
+ * Copyright 2019 RDK Management
+ *
+ * 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 __ESSOS_RESMGR__
+#define __ESSOS_RESMGR__
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef struct _EssRMgr EssRMgr;
+
+typedef enum _EssRMgrResType
+{
+   EssRMgrResType_videoDecoder,
+   EssRMgrResType_audioDecoder,
+   EssRMgrResType_frontEnd,
+   EssRMgrResType_svpAllocator
+} EssRMgrResType;
+
+typedef enum _EssRMgrVideoDecoderCaps
+{
+   EssRMgrVidCap_none=                (0),
+   EssRMgrVidCap_limitedResolution=   (1<<0),
+   EssRMgrVidCap_limitedQuality=      (1<<1),
+   EssRMgrVidCap_limitedPerformance=  (1<<2),
+   EssRMgrVidCap_hardware=            (1<<16),
+   EssRMgrVidCap_software=            (1<<17),
+
+} EssRMgrVideoDecoderCaps;
+
+typedef enum _EssRMgrVideoUsage
+{
+   EssRMgrVidUse_none=                (0),
+   EssRMgrVidUse_fullResolution=      (1<<0),
+   EssRMgrVidUse_fullQuality=         (1<<1),
+   EssRMgrVidUse_fullPerformance=     (1<<2),
+
+} EssRMgrVideoUsage;
+
+typedef enum _EssRMgrAudioDecoderCaps
+{
+   EssRMgrAudCap_none=                (0),
+} EssRMgrAudioDecoderCaps;
+
+typedef enum _EssRMgrAudioUsage
+{
+   EssRMgrAudUse_none=                (0),
+} EssRMgrAudioUsage;
+
+typedef enum _EssRMgrFrontEndCaps
+{
+   EssRMgrFECap_none=                 (0),
+} EssRMgrFrontEndCaps;
+
+typedef enum _EssRMgrFrontEndUsage
+{
+   EssRMgrFEUse_none=                 (0),
+} EssRMgrFrontEndUsage;
+
+typedef enum _EssRMgrSVPAllocCaps
+{
+   EssRMgrSVPACap_none=               (0),
+} EssRMgrSVPAllocCaps;
+
+typedef enum _EssRMgrSVPAllocUsage
+{
+   EssRMgrSVPAUse_none=               (0),
+} EssRMgrSVPAllocUsage;
+
+typedef enum _EssRMgrResState
+{
+   EssRMgrRes_idle= 0,
+   EssRMgrRes_paused= 1,
+   EssRMgrRes_active= 2,
+   EssRMgrRes_max= 3
+} EssRMgrResState;
+
+typedef enum _EssRMgrEvent
+{
+   /*
+    * Received when a resource is granted asynchronusly.
+    */
+   EssRMgrEvent_granted,
+
+   /*
+    * Received when a resource is being revoked.  When received,
+    * the application should release the resource and then call
+    * EssRMgrReleaseResource.
+    */
+   EssRMgrEvent_revoked
+} EssRMgrEvent;
+
+typedef void (*EssRMgrNotifyCB)( EssRMgr *rm, int event, int type, int id, void* userData );
+
+typedef struct _EssRMgrVideoInfo
+{
+   int maxWidth;
+   int maxHeight;
+} EssRMgrVideoInfo;
+
+typedef struct _EssRMgrAudioInfo
+{
+} EssRMgrAudioInfo;
+
+typedef struct _EssRMgrFEInfo
+{
+} EssRMgrFEInfo;
+
+typedef struct _EssRMgrSVPAInfo
+{
+} EssRMgrSVPAInfo;
+
+typedef union EssRMgrUsageInfo
+{
+   EssRMgrVideoInfo video;
+   EssRMgrAudioInfo audio;
+   EssRMgrFEInfo frontEnd;
+   EssRMgrSVPAInfo svpAllocator;
+} EssRMgrUsageInfo;
+
+typedef struct _EssRMgrRequest
+{
+   int type;
+   int usage;
+   int priority;
+   bool asyncEnable;
+   EssRMgrNotifyCB notifyCB;
+   void *notifyUserData;
+   EssRMgrUsageInfo info;
+   int requestId;
+   int assignedId;
+   int assignedCaps;
+} EssRMgrRequest;
+
+typedef struct _EssRMgrCaps
+{
+   int capabilities;
+   EssRMgrUsageInfo info;
+} EssRMgrCaps;
+
+typedef struct _EssRMgrUsage
+{
+   int usage;
+   EssRMgrUsageInfo info;
+} EssRMgrUsage;
+
+
+
+/**
+ * EssRMgrInit
+ *
+ * Initialize resource manager
+ */
+bool EssRMgrInit();
+
+/**
+ * EssRMgrTerm
+ *
+ * Terminate resource manager
+ */
+void EssRMgrTerm();
+
+/**
+ * EssRMgrCreate
+ *
+ * Create an Essos resource manager context.
+ */
+EssRMgr* EssRMgrCreate();
+
+/**
+ * EssRMgrDestroy
+ *
+ * Destroy an Essos resource manager context.
+ */
+void EssRMgrDestroy( EssRMgr *rm );
+
+/**
+ * EssRMgrGetPolicyPriorityTie
+ *
+ * Get the policy for priority ties.  Returns true if requester
+ * wins priority tie, false otherwise
+ */
+bool EssRMgrGetPolicyPriorityTie( EssRMgr *rm );
+
+/**
+ * EssRMgrGetAVState
+ *
+ * Get aggregate AV state.  Specified as value from the enum EssRMgrResState
+ */
+bool EssRMgrGetAVState( EssRMgr *rm, int *state );
+
+/**
+ * EssRMgrResourceGetCount
+ *
+ * Get number of instances of specified resource type
+ */
+int EssRMgrResourceGetCount( EssRMgr *rm, int type );
+
+/**
+ * EssRMgrResourceGetOwner
+ *
+ * Get current owner of specified resource
+ */
+bool EssRMgrResourceGetOwner( EssRMgr *rm, int type, int id, int *client, int *priority );
+
+/**
+ * EssRMgrResourceGetCaps
+ *
+ * Get capabilities info for specified resource
+ */
+bool EssRMgrResourceGetCaps( EssRMgr *rm, int type, int id, EssRMgrCaps *caps );
+
+/**
+ * EssRMgrResourceGetState
+ *
+ * Get state of the specified resource.  Specified as value from the enum EssRMgrResState
+ */
+bool EssRMgrResourceGetState( EssRMgr *rm, int type, int id, int *state );
+
+/**
+ * EssRMgrResourceSetState
+ *
+ * Set state of the specified resource.  Specified as value from the enum EssRMgrResState.
+ * Only the current owner can set the state.
+ */
+bool EssRMgrResourceSetState( EssRMgr *rm, int type, int id, int state );
+
+/**
+ * EssRMgrRequestResource
+ *
+ * Request ownership of an instance of the specified resource.
+ *
+ * The caller provides details of the request in the EssRMgrRequest structure including the intended usage constraints,
+ * request priority, if the request can be asynchronous, and a notification callback.  This call back will be
+ * invoked for asynchronous grant and revocation events. Prior to returning, the requestId field of the supplied EssRMgrRequest
+ * structure is assigned a value.  This value can be used in subsequent calls requiring a requestId until the
+ * id is invalidated by calling EssRMgrReleaseResource or EssRMgrRequestCancel.
+ */
+bool EssRMgrRequestResource( EssRMgr *rm, int type, EssRMgrRequest *req );
+
+/**
+ * EssRMgrReleaseResource
+ *
+ * Release ownership of a resource.
+ */
+void EssRMgrReleaseResource( EssRMgr *rm, int type, int id );
+
+/**
+ * EssRMgrUsageSetPriority
+ *
+ * Update the priority of a resource request.  This may result
+ * in a change of resource ownership.
+ */
+bool EssRMgrRequestSetPriority( EssRMgr *rm, int type, int requestId, int priority );
+
+/**
+ * EssRMgrRequestSetUsage
+ *
+ * Update the usage of a resource request.  This may result
+ * in a change or resource ownership.
+ */
+bool EssRMgrRequestSetUsage( EssRMgr *rm, int type, int requestId, EssRMgrUsage *usage );
+
+/**
+ * EssRMgrRequestCancel
+ *
+ * Cancel a resource request.
+ */
+void EssRMgrRequestCancel( EssRMgr *rm, int type, int requestId );
+
+/**
+ * EssRMgrDumpState
+ *
+ * Emit state data to log output
+ */
+void EssRMgrDumpState( EssRMgr *rm );
+
+#if defined(__cplusplus)
+} //extern "C"
+#endif
+
+#endif
+
diff --git a/westeros/essos/libessosrmgr.so b/westeros/essos/libessosrmgr.so
new file mode 100644
index 0000000..8e9fb19
--- /dev/null
+++ b/westeros/essos/libessosrmgr.so
Binary files differ
diff --git a/westeros/wst_essos.cpp b/westeros/wst_essos.cpp
index c1e2a0a..7259a39 100644
--- a/westeros/wst_essos.cpp
+++ b/westeros/wst_essos.cpp
@@ -6,8 +6,6 @@
 
 #define TAG "rlib:wst_essos"
 
-#define ESSRES_LIB_NAME "libessosrmgr.so.0"
-
 #define DEFAULT_WINDOW_WIDTH (1280)
 #define DEFAULT_WINDOW_HEIGHT (720)
 #define DEFAULT_USAGE (EssRMgrVidUse_fullResolution|EssRMgrVidUse_fullQuality|EssRMgrVidUse_fullPerformance)
@@ -22,26 +20,30 @@
         case EssRMgrResType_videoDecoder:
             switch ( event )
             {
-                case EssRMgrEvent_granted:{
+                case EssRMgrEvent_granted: {
                     rMgrOps->mResAssignedId = id;
                     memset( &rMgrOps->mResCurrCaps, 0, sizeof(EssRMgrCaps) );
-                    if ( !rMgrOps->EssRMgrResourceGetCaps( rMgrOps->mEssRmgr, EssRMgrResType_videoDecoder, rMgrOps->mResAssignedId, &rMgrOps->mResCurrCaps ) )
+                    if ( !EssRMgrResourceGetCaps( rMgrOps->mEssRmgr, EssRMgrResType_videoDecoder, rMgrOps->mResAssignedId, &rMgrOps->mResCurrCaps ) )
                     {
                         ERROR(rMgrOps->mLogCategory,"resMgrNotify: failed to get caps of assigned decoder");
                     }
-                    DEBUG(rMgrOps->mLogCategory,"async assigned id %d caps %X (%dx%d)",
+                    DEBUG(rMgrOps->mLogCategory,"essos notify granted,async assigned id %d caps %X (%dx%d)",
                             rMgrOps->mResAssignedId,
                             rMgrOps->mResCurrCaps.capabilities,
                             rMgrOps->mResCurrCaps.info.video.maxWidth,
                             rMgrOps->mResCurrCaps.info.video.maxHeight);
+                    if (rMgrOps->mUserCallback) {
+                        rMgrOps->mUserCallback(EssRMgrEvent_granted, rMgrOps->mUserData);
+                    }
                 } break;
-                case EssRMgrEvent_revoked:
-                {
+                case EssRMgrEvent_revoked: {
                     memset( &rMgrOps->mResCurrCaps, 0, sizeof(EssRMgrCaps) );
-                    WARNING(rMgrOps->mLogCategory,"releasing video decoder %d", id);
-                    rMgrOps->EssRMgrReleaseResource( rMgrOps->mEssRmgr, EssRMgrResType_videoDecoder, id );
+                    WARNING(rMgrOps->mLogCategory,"essos notify revoked , releasing video decoder %d", id);
+                    if (rMgrOps->mUserCallback) {
+                        rMgrOps->mUserCallback(EssRMgrEvent_revoked, rMgrOps->mUserData);
+                    }
                     rMgrOps->mResAssignedId = -1;
-                    WARNING(rMgrOps->mLogCategory,"done releasing video decoder %d,request again", id);
+                    WARNING(rMgrOps->mLogCategory,"done releasing video decoder %d", id);
                 } break;
             default:
                 break;
@@ -53,100 +55,35 @@
    DEBUG(rMgrOps->mLogCategory,"resMgrNotify: exit");
 }
 
-WstEssRMgrOps::WstEssRMgrOps(WstClientPlugin *plugin,int logCategory) {
-    mPlugin = plugin;
-    mLibHandle = NULL;
+WstEssRMgrOps::WstEssRMgrOps(int logCategory) {
+    mUserData = NULL;
     mResPriority = 0;
     mResAssignedId = -1;
     mResUsage = DEFAULT_USAGE;
     mEssRmgr = NULL;
     mLogCategory = logCategory;
+    mUserCallback = NULL;
 };
 
 WstEssRMgrOps::~WstEssRMgrOps() {
-    mLibHandle = NULL;
 };
 
+void WstEssRMgrOps::setCallback(essMgrCallback essCallback, void *userData)
+{
+    mUserData = userData;
+    mUserCallback = essCallback;
+}
+
 void WstEssRMgrOps::resMgrInit()
 {
-    if (mLibHandle == NULL) {
-        mLibHandle = dlopen(ESSRES_LIB_NAME, RTLD_NOW);
-        if (mLibHandle == NULL) {
-            ERROR(mLogCategory,"unable to dlopen %s : %s",ESSRES_LIB_NAME, dlerror());
-            goto err_tag;
-        }
-    }
-
-    EssRMgrCreate =
-        (essRMgrCreate)dlsym(mLibHandle, "EssRMgrCreate");
-    if (EssRMgrCreate == NULL) {
-        ERROR(mLogCategory,"dlsym EssRMgrCreate failed, err=%s \n", dlerror());
-        goto err_tag;
-    }
-
-    EssRMgrDestroy =
-        (essRMgrDestroy)dlsym(mLibHandle, "EssRMgrDestroy");
-    if (EssRMgrDestroy == NULL) {
-        ERROR(mLogCategory,"dlsym EssRMgrDestroy failed, err=%s \n", dlerror());
-        goto err_tag;
-    }
-
-    EssRMgrRequestResource =
-        (essRMgrRequestResource)dlsym(mLibHandle, "EssRMgrRequestResource");
-    if (EssRMgrRequestResource == NULL) {
-        ERROR(mLogCategory,"dlsym EssRMgrRequestResource failed, err=%s \n", dlerror());
-        goto err_tag;
-    }
-
-    EssRMgrReleaseResource =
-        (essRMgrReleaseResource)dlsym(mLibHandle, "EssRMgrReleaseResource");
-    if (EssRMgrReleaseResource == NULL) {
-        ERROR(mLogCategory,"dlsym EssRMgrReleaseResource failed, err=%s \n", dlerror());
-        goto err_tag;
-    }
-
-    EssRMgrDumpState =
-        (essRMgrDumpStates)dlsym(mLibHandle, "EssRMgrDumpState");
-    if (EssRMgrDumpState == NULL) {
-        ERROR(mLogCategory,"dlsym EssRMgrDumpState failed, err=%s \n", dlerror());
-        goto err_tag;
-    }
-
-    EssRMgrResourceGetCaps =
-        (essRMgrResourceGetCaps)dlsym(mLibHandle, "EssRMgrResourceGetCaps");
-    if (EssRMgrResourceGetCaps == NULL) {
-        ERROR(mLogCategory,"dlsym EssRMgrResourceGetCaps failed, err=%s \n", dlerror());
-        goto err_tag;
-    }
-
-    EssRMgrGetPolicyPriorityTie =
-        (essRMgrGetPolicyPriorityTie)dlsym(mLibHandle, "EssRMgrGetPolicyPriorityTie");
-    if (EssRMgrGetPolicyPriorityTie == NULL) {
-        ERROR(mLogCategory,"dlsym EssRMgrGetPolicyPriorityTie failed, err=%s \n", dlerror());
-        goto err_tag;
-    }
-
-    EssRMgrResourceSetState =
-        (essRMgrResourceSetState)dlsym(mLibHandle, "EssRMgrResourceSetState");
-    if (EssRMgrResourceSetState == NULL) {
-        ERROR(mLogCategory,"dlsym EssRMgrResourceSetState failed, err=%s \n", dlerror());
-        goto err_tag;
-    }
-
     mEssRmgr = EssRMgrCreate();
     if (!mEssRmgr) {
         ERROR(mLogCategory,"EssRMgrCreate failed");
-        goto err_tag;
+        return;
     }
     memset( &mResCurrCaps, 0, sizeof(EssRMgrCaps) );
     INFO(mLogCategory,"resMgrInit,ok");
     return;
-err_tag:
-    if (mLibHandle) {
-        dlclose(mLibHandle);
-        mLibHandle = NULL;
-    }
-    return;
 }
 
 void WstEssRMgrOps::resMgrTerm()
@@ -156,11 +93,6 @@
         mEssRmgr = NULL;
         memset( &mResCurrCaps, 0, sizeof(EssRMgrCaps) );
     }
-
-    if (mLibHandle) {
-        dlclose(mLibHandle);
-        mLibHandle = NULL;
-    }
     INFO(mLogCategory,"resMgrTerm, ok");
 }
 
diff --git a/westeros/wst_essos.h b/westeros/wst_essos.h
index d2cc643..f8d6b25 100644
--- a/westeros/wst_essos.h
+++ b/westeros/wst_essos.h
@@ -1,124 +1,18 @@
 #ifndef _WST_ESSOS_H_
 #define _WST_ESSOS_H_
 
-typedef void EssRMgr;
-
-typedef enum _EssRMgrAudioUsage
-{
-   EssRMgrAudUse_none=                (0),
-} EssRMgrAudioUsage;
-
-typedef enum _EssRMgrResType
-{
-   EssRMgrResType_videoDecoder,
-   EssRMgrResType_audioDecoder,
-   EssRMgrResType_frontEnd,
-   EssRMgrResType_svpAllocator
-} EssRMgrResType;
-
-typedef enum _EssRMgrResState
-{
-   EssRMgrRes_idle= 0,
-   EssRMgrRes_paused= 1,
-   EssRMgrRes_active= 2,
-   EssRMgrRes_max= 3
-} EssRMgrResState;
-
-typedef enum _EssRMgrEvent
-{
-   /*
-    * Received when a resource is granted asynchronusly.
-    */
-   EssRMgrEvent_granted,
-
-   /*
-    * Received when a resource is being revoked.  When received,
-    * the application should release the resource and then call
-    * EssRMgrReleaseResource.
-    */
-   EssRMgrEvent_revoked
-} EssRMgrEvent;
-
-typedef enum _EssRMgrVideoUsage
-{
-   EssRMgrVidUse_none=                (0),
-   EssRMgrVidUse_fullResolution=      (1<<0),
-   EssRMgrVidUse_fullQuality=         (1<<1),
-   EssRMgrVidUse_fullPerformance=     (1<<2),
-
-} EssRMgrVideoUsage;
-
-
-typedef void (*EssRMgrNotifyCB)(EssRMgr *rm, int event, int type, int id, void* userData);
-
-typedef struct _EssRMgrVideoInfo
-{
-   int maxWidth;
-   int maxHeight;
-} EssRMgrVideoInfo;
-
-typedef struct _EssRMgrAudioInfo
-{
-} EssRMgrAudioInfo;
-
-typedef struct _EssRMgrFEInfo
-{
-} EssRMgrFEInfo;
-
-typedef struct _EssRMgrSVPAInfo
-{
-} EssRMgrSVPAInfo;
-
-typedef union EssRMgrUsageInfo
-{
-   EssRMgrVideoInfo video;
-   EssRMgrAudioInfo audio;
-   EssRMgrFEInfo frontEnd;
-   EssRMgrSVPAInfo svpAllocator;
-} EssRMgrUsageInfo;
-
-typedef struct _EssRMgrRequest
-{
-   int type;
-   int usage;
-   int priority;
-   bool asyncEnable;
-   EssRMgrNotifyCB notifyCB;
-   void *notifyUserData;
-   EssRMgrUsageInfo info;
-   int requestId;
-   int assignedId;
-   int assignedCaps;
-} EssRMgrRequest;
-
-typedef struct _EssRMgrCaps
-{
-   int capabilities;
-   EssRMgrUsageInfo info;
-} EssRMgrCaps;
-
-typedef struct _EssRMgrUsage
-{
-   int usage;
-   EssRMgrUsageInfo info;
-} EssRMgrUsage;
-
-typedef EssRMgr* (*essRMgrCreate)(void);
-typedef void (*essRMgrDestroy)(EssRMgr *rm);
-typedef bool (*essRMgrRequestResource)(EssRMgr *rm, int type, EssRMgrRequest *req);
-typedef void (*essRMgrReleaseResource)(EssRMgr *rm, int type, int id);
-typedef void (*essRMgrDumpStates)(EssRMgr *rm);
-typedef bool (*essRMgrResourceGetCaps)( EssRMgr *rm, int type, int id, EssRMgrCaps *caps);
-typedef bool (*essRMgrGetPolicyPriorityTie)( EssRMgr *rm );
-typedef bool (*essRMgrResourceSetState)( EssRMgr *rm, int type, int id, int state );
+#include "essos-resmgr.h"
 
 class WstClientPlugin;
 
+typedef void (*essMgrCallback)(int event, void *userData);
+
 class WstEssRMgrOps {
 public:
-   WstEssRMgrOps(WstClientPlugin *plugin,int logCategory);
+   WstEssRMgrOps(int logCategory);
    virtual ~WstEssRMgrOps();
 
+   void setCallback(essMgrCallback essCallback, void *userData);
    void resMgrInit();
    void resMgrTerm();
    void resMgrRequestDecoder(bool pip);
@@ -128,8 +22,7 @@
    static void resMgrNotify( EssRMgr *rm, int event, int type, int id, void* userData );
 private:
    int mLogCategory;
-   WstClientPlugin *mPlugin;
-   void *mLibHandle;
+   void *mUserData;
    EssRMgr *mEssRmgr;
    uint mResPriority;
    uint mResUsage;
@@ -137,13 +30,6 @@
    EssRMgrCaps mResCurrCaps;
    EssRMgrRequest mResReq;
 
-   essRMgrCreate EssRMgrCreate;
-   essRMgrDestroy EssRMgrDestroy;
-   essRMgrRequestResource EssRMgrRequestResource;
-   essRMgrReleaseResource EssRMgrReleaseResource;
-   essRMgrDumpStates EssRMgrDumpState;
-   essRMgrResourceGetCaps EssRMgrResourceGetCaps;
-   essRMgrGetPolicyPriorityTie EssRMgrGetPolicyPriorityTie;
-   essRMgrResourceSetState EssRMgrResourceSetState;
+   essMgrCallback mUserCallback;
 };
 #endif //_WST_ESSOS_H_
diff --git a/westeros/wstclient_plugin.cpp b/westeros/wstclient_plugin.cpp
index 3d4db21..4988af2 100644
--- a/westeros/wstclient_plugin.cpp
+++ b/westeros/wstclient_plugin.cpp
@@ -45,7 +45,8 @@
     mFrameRateFractionNum = 0;
     mFrameRateFractionDenom = 0;
     mFrameRateChanged = false;
-    mWstEssRMgrOps = new WstEssRMgrOps(this,logCategory);
+    mWstEssRMgrOps = new WstEssRMgrOps(logCategory);
+    mWstEssRMgrOps->setCallback(WstClientPlugin::essMgrCallback, this);
 }
 
 WstClientPlugin::~WstClientPlugin()
@@ -88,11 +89,13 @@
             BUILD_TIME,
             BUILD_NAME
     );
+    mWstEssRMgrOps->resMgrInit();
 }
 
 void WstClientPlugin::release()
 {
     DEBUG(mLogCategory,"release");
+    mWstEssRMgrOps->resMgrTerm();
 }
 
 void WstClientPlugin::setCallback(void *userData, PluginCallback *callback)
@@ -107,7 +110,6 @@
 
     DEBUG(mLogCategory,"openDisplay");
 
-    mWstEssRMgrOps->resMgrInit();
     mWstEssRMgrOps->resMgrRequestDecoder(mIsVideoPip);
 
     //connect video server first
@@ -321,8 +323,6 @@
 {
     INFO(mLogCategory,"closeDisplay, in");
     mWayland->disconnectFromWayland();
-    mWstEssRMgrOps->resMgrReleaseDecoder();
-    mWstEssRMgrOps->resMgrTerm();
     INFO(mLogCategory,"closeDisplay, out");
     return NO_ERROR;
 }
@@ -359,6 +359,7 @@
         }
     }
     mWstEssRMgrOps->resMgrUpdateState(EssRMgrRes_idle);
+    mWstEssRMgrOps->resMgrReleaseDecoder();
     mRenderBuffersMap.clear();
     mDisplayedFrameMap.clear();
     mCommitFrameCnt = 0;
@@ -528,6 +529,26 @@
     }
 }
 
+void WstClientPlugin::essMgrCallback(int event, void *userData)
+{
+    WstClientPlugin *plugin = static_cast<WstClientPlugin *>(userData);
+    switch ( event )
+    {
+        case EssRMgrEvent_granted: {
+            DEBUG(plugin->mLogCategory,"essmgr notify granted");
+            plugin->openDisplay();
+            plugin->openWindow();
+        } break;
+        case EssRMgrEvent_revoked: {
+            WARNING(plugin->mLogCategory,"essos notify revoked ");
+            plugin->closeWindow();
+            plugin->closeDisplay();
+        } break;
+        default:
+            break;
+    }
+}
+
 void WstClientPlugin::setVideoRect(int videoX, int videoY, int videoWidth, int videoHeight)
 {
     if (mWstClientSocket) {
diff --git a/westeros/wstclient_plugin.h b/westeros/wstclient_plugin.h
index 4c276d3..9d5787c 100644
--- a/westeros/wstclient_plugin.h
+++ b/westeros/wstclient_plugin.h
@@ -56,6 +56,7 @@
     int getLogCategory() {
         return mLogCategory;
     };
+    static void essMgrCallback(int event, void *userData);
   private:
     typedef struct {
         bool isSet;