Introducing ServiceConnect and ServiceDisconnect.
authorMichael Schuldt <michael.schuldt@bmw-carit.de>
Thu, 8 Dec 2011 10:01:17 +0000 (11:01 +0100)
committerMichael Schuldt <michael.schuldt@bmw-carit.de>
Thu, 8 Dec 2011 10:01:41 +0000 (11:01 +0100)
Due to the fact, that it should be possible to get information
which application is running and the Service should run a
internal cleanup, if a registered application crashes. This
functionality is needed.

LayerManagerClient/ilmClient/src/ilm_client.c
LayerManagerPlugins/Communicators/DBUSCommunicator/include/DBUSCommunicator.h
LayerManagerPlugins/Communicators/DBUSCommunicator/src/DBUSCommunicator.cpp
LayerManagerPlugins/Communicators/DBUSCommunicator/src/DBUSMessageHandler.cpp
LayerManagerPlugins/Communicators/DBUSCommunicator/test/mock_CommandExecutor.h
LayerManagerService/include/ApplicationReferenceMap.h [new file with mode: 0644]
LayerManagerService/include/IApplicationReference.h [new file with mode: 0644]
LayerManagerService/include/ICommandExecutor.h
LayerManagerService/include/Layermanager.h
LayerManagerService/src/Layermanager.cpp

index a9ec783..15bc8dc 100644 (file)
@@ -22,6 +22,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #define INVALID_ID 0xFFFFFFFF
 
@@ -57,7 +59,32 @@ ilmErrorTypes ilm_init()
             }
             else
             {
-                result = ILM_SUCCESS;
+                /* Connect to Service */              
+                DBusMessage *message;
+                int pid = getpid();
+                // Setup parameter to send
+                t_ilm_param layerParam[1];
+                
+                _ilm_setup_param(layerParam, DBUS_TYPE_UINT32, &pid);
+                // Setup Call
+                message = _ilm_dbus_method_call(g_ilm_client->dbus_connection, "ServiceConnect", layerParam, 1);
+
+                if (message)
+                {
+                    result = ILM_SUCCESS;                    
+                    t_ilm_int messageType = dbus_message_get_type(message);
+                    if (messageType == DBUS_MESSAGE_TYPE_ERROR) 
+                    { 
+                        ILM_ERROR("ilm_init","Can not connect to service\n");
+                        result = ILM_ERROR_ON_CONNECTION;
+                    } 
+                    _ilm_close_dbus_method_call(message);
+                }
+                else
+                {
+                    ILM_ERROR("ilm_init","Can not connect to service\n");
+                    result = ILM_ERROR_ON_CONNECTION;
+                }
             }
         }
     }
@@ -2078,6 +2105,27 @@ ilmErrorTypes ilm_destroy()
 
     if (g_ilm_client && g_ilm_init == ILM_TRUE)
     {
+        /* Connect to Service */              
+        DBusMessage *message;
+        int pid = getpid();
+        // Setup parameter to send
+        t_ilm_param layerParam[1];
+        
+        _ilm_setup_param(layerParam, DBUS_TYPE_UINT32, &pid);
+        // Setup Call
+        message = _ilm_dbus_method_call(g_ilm_client->dbus_connection, "ServiceDisconnect", layerParam, 1);
+
+        if (message)
+        {
+            ILM_CHECK_METHOD_ERROR(message);
+            _ilm_close_dbus_method_call(message);
+            result = ILM_SUCCESS;                    
+        }
+        else
+        {
+            ILM_ERROR("ilm_deinit","Can'not disconnect from service\n");
+        }
+        
         if (g_ilm_client->dbus_connection)
         {
             dbus_connection_unref(g_ilm_client->dbus_connection);
index d3e248c..e364767 100644 (file)
@@ -23,6 +23,8 @@
 #include "Log.h"
 
 #include "ICommandExecutor.h"
+#include "IApplicationReference.h"
+#include "ApplicationReferenceMap.h"
 #include "CommitCommand.h"
 #include "LayerCreateCommand.h"
 #include "LayergroupCreateCommand.h"
@@ -96,7 +98,8 @@ public:
     virtual void stop();
     virtual void process(int timeout_ms);
     virtual void setdebug(bool onoff);
-
+    void ServiceConnect(DBusConnection* conn, DBusMessage* msg);
+    void ServiceDisconnect(DBusConnection* conn, DBusMessage* msg);    
     void Debug(DBusConnection* conn, DBusMessage* msg);
     void ScreenShot(DBusConnection* conn, DBusMessage* msg);
     void ScreenShotOfLayer(DBusConnection* conn, DBusMessage* msg);
index da0313a..d647a92 100644 (file)
@@ -44,6 +44,8 @@ static DBUSMessageHandler* g_pDbusMessage;
 
 static MethodTable manager_methods[] =
 {
+    { "ServiceConnect",                   "u",     "",            &DBUSCommunicator::ServiceConnect },
+    { "ServiceDisconnect",                "u",     "",            &DBUSCommunicator::ServiceDisconnect },    
     { "Debug",                            "b",     "",            &DBUSCommunicator::Debug },
     { "ScreenShot",                       "us",    "",            &DBUSCommunicator::ScreenShot },
     { "ScreenShotOfLayer",                "su",    "",            &DBUSCommunicator::ScreenShotOfLayer },
@@ -174,6 +176,37 @@ void DBUSCommunicator::stop()
     delete g_pDbusMessage;
 }
 
+void DBUSCommunicator::ServiceConnect(DBusConnection* conn, DBusMessage* msg)
+{
+   (void)conn; // TODO: remove, only prevents warning
+    g_pDbusMessage->initReceive(msg);
+    u_int32_t processId = g_pDbusMessage->getUInt();
+    char* owner = strdup(dbus_message_get_sender(msg));   
+    m_executor->addApplicationReference(new IApplicationReference(owner,processId));    
+    g_pDbusMessage->initReply(msg);
+    g_pDbusMessage->closeReply();
+}
+
+
+void DBUSCommunicator::ServiceDisconnect(DBusConnection* conn, DBusMessage* msg)   
+{
+   IApplicationReference* reference = NULL;
+   (void)conn; // TODO: remove, only prevents warning
+    g_pDbusMessage->initReceive(msg);
+    char* owner = strdup(dbus_message_get_sender(msg));
+    u_int32_t processId = g_pDbusMessage->getUInt();
+    ApplicationReferenceMapIterator iter = m_executor->getApplicationReferenceMap()->find(IApplicationReference::generateApplicationHash(owner));
+    ApplicationReferenceMapIterator iterEnd = m_executor->getApplicationReferenceMap()->end();
+
+    if ( iter != iterEnd ) 
+    {
+        m_executor->removeApplicationReference((*iter).second);
+    }
+    
+    g_pDbusMessage->initReply(msg);
+    g_pDbusMessage->closeReply();
+}
+
 void DBUSCommunicator::Debug(DBusConnection* conn, DBusMessage* msg)
 {
     (void)conn; // TODO: remove, only prevents warning
index e75040a..a9e56da 100644 (file)
@@ -91,6 +91,7 @@ bool DBUSMessageHandler::registerPathFunction(  DBusObjectPathMessageFunction fM
 
 void DBUSMessageHandler::initReceive(DBusMessage* msg)
 {
+    LOG_DEBUG("DBUSCommunicator","Message " << dbus_message_get_member(msg) << " was sent by " << dbus_message_get_sender(msg) );
     if (!dbus_message_iter_init(msg, &m_MessageIter))
     {
         LOG_ERROR("DBUSCommunicator", "Message has no arguments!");
index a8e57c4..a666bdd 100644 (file)
@@ -47,6 +47,9 @@ class MockCommandExecutor : public ICommandExecutor {
   MOCK_METHOD1(addSceneProvider, void(ISceneProvider* provider));
   MOCK_METHOD1(removeSceneProvider, void(ISceneProvider* provider));
 
+  MOCK_METHOD0(getApplicationReferenceMap, ApplicationReferenceMap*());
+  MOCK_METHOD1(addApplicationReference, void(IApplicationReference* reference));
+  MOCK_METHOD1(removeApplicationReference, void(IApplicationReference* reference));
 
   MOCK_CONST_METHOD1(getLayerTypeCapabilities, uint(LayerType));
   MOCK_CONST_METHOD1(getNumberOfHardwareLayers, uint(uint));
diff --git a/LayerManagerService/include/ApplicationReferenceMap.h b/LayerManagerService/include/ApplicationReferenceMap.h
new file mode 100644 (file)
index 0000000..1fedc1d
--- /dev/null
@@ -0,0 +1,30 @@
+/***************************************************************************
+*
+* Copyright 2010,2011 BMW Car IT GmbH
+*
+*
+* 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 _APPLICATION_REFERENCE_MAP_H_
+#define _APPLICATION_REFERENCE_MAP_H_
+
+#include <map>
+#include "IApplicationReference.h"
+#include <string.h>
+
+typedef std::map<long, IApplicationReference*> ApplicationReferenceMap;
+typedef std::map<long, IApplicationReference*>::iterator ApplicationReferenceMapIterator;
+typedef std::map<long, IApplicationReference*>::const_iterator ApplicationReferenceMapConstIterator;
+
+#endif /* _APPLICATION_REFERENCE_MAP_H_ */
diff --git a/LayerManagerService/include/IApplicationReference.h b/LayerManagerService/include/IApplicationReference.h
new file mode 100644 (file)
index 0000000..005eab1
--- /dev/null
@@ -0,0 +1,75 @@
+
+/***************************************************************************
+ *
+ * Copyright 2010,2011 BMW Car IT GmbH
+ *
+ *
+ * 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 _IAPPLICATION_REFERENCE_H_
+#define _IAPPLICATION_REFERENCE_H_
+#include <locale>
+#include <string.h>
+/**
+ * Abstract Base Class for all Application References 
+ */
+class IApplicationReference
+{
+public:
+    /**
+     * Constructor: Contructs a Object with the provided Application id and SerialId
+     * 
+     */
+    IApplicationReference(char* applicationUid, unsigned int processId);
+    virtual ~IApplicationReference() {}
+
+     virtual char* getApplicationUid();
+     static long generateApplicationHash(char* applicationUid);
+     virtual long getApplicationHash();
+     virtual unsigned int getProcessId();
+
+protected:
+    char* m_applicationUid;
+    unsigned int m_processId;
+};
+
+inline IApplicationReference::IApplicationReference(char* applicationUid, unsigned int processId)
+: m_applicationUid(applicationUid)
+, m_processId(processId)
+{
+}
+
+inline char* IApplicationReference::getApplicationUid()
+{
+    return m_applicationUid;
+}
+
+inline unsigned int IApplicationReference::getProcessId()
+{
+    return m_processId;
+}
+
+inline long IApplicationReference::getApplicationHash() 
+{
+    return generateApplicationHash(m_applicationUid);
+}
+inline long IApplicationReference::generateApplicationHash(char* applicationUid) 
+{
+  std::locale loc; 
+  const std::collate<char>& colHash = std::use_facet<std::collate<char> >(loc);
+  long result = colHash.hash(applicationUid,applicationUid+strlen(applicationUid)); 
+  return result;
+}
+#endif /* _IAPPLICATION_REFERENCE_H_ */
index 67cad37..7f13c89 100644 (file)
@@ -23,6 +23,7 @@
 #include "RendererList.h"
 #include "CommunicatorList.h"
 #include "SceneProviderList.h"
+#include "ApplicationReferenceMap.h"
 #include "LayerType.h"
 
 class ICommand;
@@ -64,6 +65,10 @@ public:
     virtual void addSceneProvider(ISceneProvider* sceneProvider) = 0;
     virtual void removeSceneProvider(ISceneProvider* sceneProvider) = 0;
 
+    virtual ApplicationReferenceMap* getApplicationReferenceMap(void) = 0;
+    virtual void addApplicationReference(IApplicationReference* applicationReference) = 0;
+    virtual void removeApplicationReference(IApplicationReference* applicationReference) = 0;
+
     virtual unsigned int getLayerTypeCapabilities(const LayerType layertype) const = 0; // TODO: removeable, use default command processing ?
     virtual unsigned int getNumberOfHardwareLayers(const unsigned int screenID) const = 0; // TODO: removeable, use default command processing ?
     virtual unsigned int* getScreenResolution(const unsigned int screenID) const = 0; // TODO: removeable, use default command processing ?
index e92de71..8b0ac87 100644 (file)
@@ -27,6 +27,7 @@ class ICommand;
 class IRenderer;
 class ICommunicator;
 class ISceneProvider;
+class IApplicationReference;
 
 class Layermanager: public ICommandExecutor
 {
@@ -48,6 +49,9 @@ public:
     virtual void removeCommunicator(ICommunicator* communicator);
     virtual void addSceneProvider(ISceneProvider* sceneProvider);
     virtual void removeSceneProvider(ISceneProvider* sceneProvider);
+    virtual void addApplicationReference(IApplicationReference* reference);
+    virtual void removeApplicationReference(IApplicationReference* reference);
+    
     virtual bool startManagement(const int width, const int height, const char* displayName);
     virtual bool stopManagement();
 
@@ -55,6 +59,7 @@ public:
     virtual RendererList* getRendererList(void);
     virtual CommunicatorList* getCommunicatorList(void);
     virtual SceneProviderList* getSceneProviderList(void);
+    virtual ApplicationReferenceMap* getApplicationReferenceMap(void);
 
 private:
     void printDebugInformation() const;
@@ -71,6 +76,7 @@ private:
     RendererList* m_pRendererList;
     CommunicatorList* m_pCommunicatorList;
     SceneProviderList* m_pSceneProviderList;
+    ApplicationReferenceMap* m_pApplicationReferenceMap;
 };
 
 inline Scene* Layermanager::getScene(void)
@@ -93,5 +99,8 @@ inline SceneProviderList* Layermanager::getSceneProviderList(void)
     return m_pSceneProviderList;
 }
 
-
+inline ApplicationReferenceMap* Layermanager::getApplicationReferenceMap(void)
+{
+    return m_pApplicationReferenceMap;
+}
 #endif /* _LAYERMANAGER_H_ */
index 4960c59..76ad4b8 100644 (file)
@@ -32,6 +32,7 @@ Layermanager::Layermanager()
     m_pRendererList = new RendererList();
     m_pCommunicatorList = new CommunicatorList();
     m_pSceneProviderList = new SceneProviderList();
+    m_pApplicationReferenceMap = new ApplicationReferenceMap();
 }
 
 Layermanager::~Layermanager()
@@ -157,6 +158,26 @@ void Layermanager::removeSceneProvider(ISceneProvider* sceneProvider)
         m_pSceneProviderList->remove(sceneProvider);
     }
 }
+void Layermanager::addApplicationReference(IApplicationReference* reference)
+{
+    if (reference)
+    {
+        LOG_INFO("LayerManagerService", "Connect from application hash :" << reference->getApplicationHash() << " pid : " << reference->getProcessId()); 
+        (*m_pApplicationReferenceMap)[reference->getApplicationHash()]=reference;
+    }
+
+}
+
+void Layermanager::removeApplicationReference(IApplicationReference* reference)
+{
+    if (reference)
+    {
+        LOG_INFO("LayerManagerService", "Disconnect from application with hash :" << reference->getApplicationHash() << " pid : " << reference->getProcessId());         
+        m_pApplicationReferenceMap->erase(reference->getApplicationHash());
+    }
+}
+
+
 
 void Layermanager::addCommunicator(ICommunicator* communicator)
 {