khronosfws/openmax_al/src/common/xadynintmgmtitf.c
changeset 12 5a06f39ad45b
child 25 6f7ceef7b1d1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/khronosfws/openmax_al/src/common/xadynintmgmtitf.c	Fri Apr 16 15:29:42 2010 +0300
@@ -0,0 +1,467 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "openmaxalwrapper.h"
+#include "xadynintmgmtitf.h"
+#include "xadebug.h"
+
+/* XADIMItfImpl* GetImpl(XADIMItf self)
+ * Description: Validate interface pointer and cast it to implementation pointer.
+ */
+static XADIMItfImpl* GetImpl(XADynamicInterfaceManagementItf self)
+{
+    if( self )
+    {
+        XADIMItfImpl* impl = (XADIMItfImpl*)(*self);
+        if( impl && (impl == impl->self) )
+        {
+            return impl;
+        }
+    }
+    return NULL;
+}
+
+/**
+ * Base Interface XADynamicInterfaceManagementItf implementation
+ **/
+
+/* XAresult XADIMItfImpl_AddInterface
+ * Optionally asynchronous method for exposing an interface on an object.
+ */
+XAresult XADIMItfImpl_AddInterface(XADynamicInterfaceManagementItf self,
+                                   const XAInterfaceID iid,
+                                   XAboolean async)
+{
+    XADIMItfImpl* impl = GetImpl(self);
+    XAresult retval = XA_RESULT_SUCCESS;
+    DEBUG_API("->XADIMItfImpl_AddInterface");
+    if( !impl )
+    {
+        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+        DEBUG_API("<-XADIMItfImpl_AddInterface");
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+
+    if( async )
+    {
+        /* invoke asynchronously */
+        /* check if another async operation is processed */
+        if(impl->asyncOngoing)
+        {
+            /* abort ongoing operation */
+            XAImpl_CancelThread(impl->asyncThr);
+        }
+        impl->asyncOngoing = XA_BOOLEAN_TRUE;
+        impl->asyncID = iid;
+        if(XAImpl_StartThread(impl->asyncThr, NULL,
+                &XADIMItfImpl_AsyncAddItf,(void*)(self)))
+        {
+            impl->asyncOngoing = XA_BOOLEAN_FALSE;
+            retval = XA_RESULT_RESOURCE_ERROR;
+        }
+        else
+        {
+            retval = XA_RESULT_SUCCESS;
+        }
+    }
+    else
+    {
+        /* invoke synchronously */
+        retval = XADIMItfImpl_DoAddItf(impl, iid);
+    }
+
+    DEBUG_API_A1("<-XADIMItfImpl_AddInterface %lu", retval);
+    return retval;
+}
+
+/* XAresult XADIMItfImpl_RemoveInterface
+ * Synchronous method for removing a dynamically exposed interface on an object.
+ */
+XAresult XADIMItfImpl_RemoveInterface(XADynamicInterfaceManagementItf self,
+                                          const XAInterfaceID iid)
+{
+    XADIMItfImpl* impl = GetImpl(self);
+    XAresult retval = XA_RESULT_SUCCESS;
+    DEBUG_API("->XADIMItfImpl_RemoveInterface");
+
+    if( impl )
+    {
+        XAObjItfMapEntry *mapEntry = NULL;
+        if(impl->parent)
+        {
+            mapEntry = XAObjectItfImpl_GetItfEntry(impl->parent, iid);
+        }
+        if( mapEntry && mapEntry->isDynamic )
+        {
+            if( (mapEntry->pItf) )
+            {
+                if( impl->DoRemoveItfImpl )
+                {
+                    retval = impl->DoRemoveItfImpl(impl->parent, mapEntry);
+                }
+                else
+                {
+                    DEBUG_ERR("XADIMItfImpl_RemoveInterface: Object has specified dynamic itfs but not implemented DoRemoveItfImpl!!!");
+                    retval = XA_RESULT_INTERNAL_ERROR;
+                }
+            }
+            else
+            {
+                DEBUG_ERR("XADIMItfImpl_RemoveInterface interface not exposed");
+                retval = XA_RESULT_PRECONDITIONS_VIOLATED;
+            }
+        }
+        else /*( mapEntry && mapEntry->isDynamic )*/
+        {   /* interface is not supported for dynamic management */
+            DEBUG_ERR("XADIMItfImpl_RemoveInterface interface not supported");
+            retval = XA_RESULT_FEATURE_UNSUPPORTED;
+        }
+    }
+    else
+    {
+        retval = XA_RESULT_PARAMETER_INVALID;
+        DEBUG_ERR("XADIMItfImpl_RemoveInterface: INVALID args");
+    }
+
+    DEBUG_API_A1("<-XADIMItfImpl_RemoveInterface %lu", retval);
+    return retval;
+}
+
+/* XAresult XADIMItfImpl_ResumeInterface
+ * Optionally asynchronous method for resuming a dynamically exposed interface on the object.
+ */
+XAresult XADIMItfImpl_ResumeInterface(XADynamicInterfaceManagementItf self,
+                                      const XAInterfaceID iid,
+                                      XAboolean async)
+{
+    XADIMItfImpl* impl = GetImpl(self);
+    XAresult retval = XA_RESULT_SUCCESS;
+    DEBUG_API("->XADIMItfImpl_ResumeInterface");
+
+    if( !impl )
+    {
+        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+        DEBUG_API("<-XADIMItfImpl_ResumeInterface");
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+
+    if( async )
+    {
+        /* invoke asynchronously */
+        /* check if another async operation is processed */
+        if(impl->asyncOngoing)
+        {
+            /* abort ongoing operation */
+            XAImpl_CancelThread(impl->asyncThr);
+        }
+        impl->asyncOngoing = XA_BOOLEAN_TRUE;
+        impl->asyncID = iid;
+        if(XAImpl_StartThread(impl->asyncThr, NULL,
+                &XADIMItfImpl_AsyncResumeItf,(void*)(self)))
+        {
+            impl->asyncOngoing = XA_BOOLEAN_FALSE;
+            retval = XA_RESULT_RESOURCE_ERROR;
+        }
+        else
+        {
+            retval = XA_RESULT_SUCCESS;
+        }
+    }
+    else
+    {
+        /* invoke synchronously */
+        retval = XADIMItfImpl_DoResumeItf(impl, iid);
+    }
+
+    DEBUG_API_A1("<-XADIMItfImpl_ResumeInterface %lu", retval);
+    return retval;
+}
+
+/* XAresult XADIMItfImpl_RegisterCallback
+ * Registers a callback on the object
+ */
+XAresult XADIMItfImpl_RegisterCallback(XADynamicInterfaceManagementItf self,
+                                       xaDynamicInterfaceManagementCallback callback,
+                                       void * pContext)
+{
+    XADIMItfImpl* impl = GetImpl(self);
+    DEBUG_API("->XADIMItfImpl_RegisterCallback");
+
+    if( !impl )
+    {
+        DEBUG_ERR("XA_RESULT_PARAMETER_INVALID");
+        DEBUG_API("<-XADIMItfImpl_RegisterCallback");
+        return XA_RESULT_PARAMETER_INVALID;
+    }
+    impl->dimCb = callback;
+    impl->dimCbContext = pContext;
+    impl->dimCbPtrToSelf = self;
+
+    DEBUG_API("<-XADIMItfImpl_RegisterCallback");
+    return XA_RESULT_SUCCESS;
+}
+
+/**
+ * XADIMItfImpl -specific methods
+ **/
+
+/* XADIMItfImpl* XADIMItfImpl_Create()
+ * Description: Allocate and initialize DIMItfImpl
+ */
+XADIMItfImpl* XADIMItfImpl_Create()
+{
+    XADIMItfImpl *self = (XADIMItfImpl*)calloc(1,sizeof(XADIMItfImpl));
+    DEBUG_API("->XADIMItfImpl_Create");
+
+    if( self )
+    {
+        /* init itf default implementation */
+        self->itf.AddInterface = XADIMItfImpl_AddInterface;
+        self->itf.RemoveInterface = XADIMItfImpl_RemoveInterface;
+        self->itf.ResumeInterface = XADIMItfImpl_ResumeInterface;
+        self->itf.RegisterCallback = XADIMItfImpl_RegisterCallback;
+
+        /* init variables */
+        self->asyncOngoing = XA_BOOLEAN_FALSE;
+        self->dimCbPtrToSelf = NULL;
+
+        self->self = self;
+        if( XAImpl_CreateThreadHandle(&(self->asyncThr)) != XA_RESULT_SUCCESS )
+        {
+            free(self);
+            self = NULL;
+        }
+    }
+    DEBUG_API("<-XADIMItfImpl_Create");
+    return self;
+}
+
+/* void XADIMItfImpl_Free(XADIMItfImpl* self)
+ * Description: Free all resources reserved at XADIMItfImpl_Create
+ */
+void XADIMItfImpl_Free(XADIMItfImpl* self)
+{
+    DEBUG_API("->XADIMItfImpl_Free");
+    assert(self==self->self);
+    XAImpl_DeleteThreadHandle(self->asyncThr);
+    free(self);
+    DEBUG_API("<-XADIMItfImpl_Free");
+}
+
+/* void XADIMItfImpl_Init
+ * Description: Initialize DIM interface. Mandatory to call if dynamic
+ * interfaces are supported by object.
+ */
+void XADIMItfImpl_Init( XADIMItfImpl* self,
+                           XAObjectItf parent,
+                           xaDoAddItfImpl doAdd,
+                           xaDoResumeItfImpl doResume,
+                           xaDoRemoveItfImpl doRemove)
+{
+    DEBUG_API("->XADIMItfImpl_Init");
+
+    assert(self==self->self && parent && doAdd && doResume && doRemove);
+    self->parent = parent;
+    self->DoAddItfImpl = doAdd;
+    self->DoResumeItfImpl = doResume;
+    self->DoRemoveItfImpl = doRemove;
+
+    DEBUG_API("<-XADIMItfImpl_Init");
+}
+
+/* void XADIMItfImpl_SendCbEvent
+ * Description: Object can use this method to send resource events
+ */
+void XADIMItfImpl_SendCbEvent( XADIMItfImpl* self,
+                                   XAuint32 event,
+                                   XAresult result,
+                                   const XAInterfaceID iid )
+{
+    DEBUG_API("->XADIMItfImpl_SendCbEvent");
+    if( self->dimCb )
+     {
+        self->dimCb((XADynamicInterfaceManagementItf)(self), self->dimCbContext,
+                      event, result, iid);
+     }
+    DEBUG_API("<-XADIMItfImpl_SendCbEvent");
+}
+
+/* void* XADIMItfImpl_AsyncAddItf
+ * Description: Launch AddItf from async thread.
+ */
+void* XADIMItfImpl_AsyncAddItf(void* args)
+{
+    XAresult retval = XA_RESULT_SUCCESS;
+    XADIMItfImpl* impl = GetImpl(args);
+    DEBUG_API("->XADIMItfImpl_AsyncAddItf");
+
+    if( impl )
+    {
+        retval = XADIMItfImpl_DoAddItf(impl, impl->asyncID);
+        if( impl->dimCb )
+        {
+            impl->dimCb((XADynamicInterfaceManagementItf)(args), impl->dimCbContext,
+                         XA_DYNAMIC_ITF_EVENT_ASYNC_TERMINATION, retval, impl->asyncID);
+        }
+        impl->asyncOngoing = XA_BOOLEAN_FALSE;
+        XAImpl_ExitThread(impl->asyncThr);
+    }
+    else
+    {
+        DEBUG_ERR("XADIMItfImpl_AsyncAddItf: INVALID args");
+    }
+    
+
+    DEBUG_API("<-XADIMItfImpl_AsyncAddItf");
+    return NULL;
+}
+
+/* XAresult XADIMItfImpl_DoAddItf
+ * Description: Handle Itf dynamic addition and call object-specific parts.
+ *              Launched either from async thread or directly.
+ */
+XAresult XADIMItfImpl_DoAddItf(XADIMItfImpl* impl,
+                                const XAInterfaceID iid)
+{
+    XAresult retval = XA_RESULT_SUCCESS;
+    DEBUG_API("->XADIMItfImpl_DoAddItf");
+
+    if( impl )
+    {
+        XAObjItfMapEntry *mapEntry = NULL;
+        if(impl->parent)
+        {
+            mapEntry = XAObjectItfImpl_GetItfEntry(impl->parent, iid);
+        }
+        if( mapEntry && mapEntry->isDynamic )
+        {
+            if( !(mapEntry->pItf) )
+            {
+                if( impl->DoAddItfImpl )
+                {
+                    retval = impl->DoAddItfImpl(impl->parent, mapEntry);
+                }
+                else
+                {
+                    DEBUG_ERR("XADIMItfImpl_DoAddItf: Object has specified dynamic itfs but not implemented DoAddItfImpl!!!");
+                    retval = XA_RESULT_INTERNAL_ERROR;
+                }
+            }
+            else
+            {
+                DEBUG_ERR("XADIMItfImpl_DoAddItf interface already exposed");
+                retval = XA_RESULT_PRECONDITIONS_VIOLATED;
+            }
+        }
+        else /*( mapEntry && mapEntry->isDynamic )*/
+        {   /* interface is not supported for dynamic management */
+            DEBUG_ERR("XADIMItfImpl_DoAddItf interface not supported");
+            retval = XA_RESULT_FEATURE_UNSUPPORTED;
+        }
+    }
+    else
+    {
+        retval = XA_RESULT_INTERNAL_ERROR;
+        DEBUG_ERR("XADIMItfImpl_DoAddItf: INVALID args");
+    }
+
+    DEBUG_API("<-XADIMItfImpl_DoAddItf");
+    return retval;
+}
+
+/* void* XADIMItfImpl_AsyncResumeItf
+ * Description: Launch ResumeItf from async thread.
+ */
+void* XADIMItfImpl_AsyncResumeItf(void* args)
+{
+    XAresult retval = XA_RESULT_SUCCESS;
+    XADIMItfImpl* impl = GetImpl(args);
+    DEBUG_API("->XADIMItfImpl_AsyncResumeItf");
+
+    if( impl )
+    {
+        retval = XADIMItfImpl_DoResumeItf(impl, impl->asyncID);
+        if( impl->dimCb )
+        {
+            impl->dimCb((XADynamicInterfaceManagementItf)(args), impl->dimCbContext,
+                         XA_DYNAMIC_ITF_EVENT_ASYNC_TERMINATION, retval, impl->asyncID);
+        }
+        impl->asyncOngoing = XA_BOOLEAN_FALSE;
+        XAImpl_ExitThread(impl->asyncThr);
+    }
+    else
+    {
+        DEBUG_ERR("XADIMItfImpl_AsyncResumeItf: INVALID args");
+    }
+    
+
+    DEBUG_API("<-XADIMItfImpl_AsyncResumeItf");
+    return NULL;
+}
+
+/* void XADIMItfImpl_DoResumeItf
+ * Description: Handle Itf dynamic resuming and call object-specific parts.
+ *              Launched either from async thread or directly.
+ */
+XAresult XADIMItfImpl_DoResumeItf(XADIMItfImpl* impl,
+                                const XAInterfaceID iid)
+{
+    XAresult retval = XA_RESULT_SUCCESS;
+    DEBUG_API("->XADIMItfImpl_DoResumeItf");
+
+    if( impl )
+    {
+        XAObjItfMapEntry *mapEntry = XAObjectItfImpl_GetItfEntry(impl->parent, iid);
+        if( mapEntry && mapEntry->isDynamic )
+        {
+            if( (!mapEntry->pItf) )
+            {
+                if( impl->DoResumeItfImpl )
+                {
+                    retval = impl->DoResumeItfImpl(impl->parent, mapEntry);
+                }
+                else
+                {
+                    DEBUG_ERR("XADIMItfImpl_DoResumeItf: Object has specified dynamic itfs but not implemented DoResumeItfImpl!!!");
+                    retval = XA_RESULT_INTERNAL_ERROR;
+                }
+            }
+            else
+            {
+                DEBUG_ERR("XADIMItfImpl_DoResumeItf interface already exposed");
+                retval = XA_RESULT_PRECONDITIONS_VIOLATED;
+            }
+        }
+        else /*( mapEntry && mapEntry->isDynamic )*/
+        {   /* interface is not supported for dynamic management */
+            DEBUG_ERR("XADIMItfImpl_DoResumeItf interface not supported");
+            retval = XA_RESULT_FEATURE_UNSUPPORTED;
+        }
+    }
+    else
+    {
+        retval = XA_RESULT_INTERNAL_ERROR;
+        DEBUG_ERR("XADIMItfImpl_DoResumeItf: INVALID args");
+    }
+
+    DEBUG_API("<-XADIMItfImpl_DoResumeItf");
+    return retval;
+}
+