--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sensorservices/sensorserver/src/server/sensrvproxymanager.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,1482 @@
+/*
+* Copyright (c) 2006-2008 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: Sensor server proxy manager
+*
+*/
+
+
+#include <centralrepository.h>
+#include "sensrvdefines.h"
+#include "sensrvproxymanager.h"
+#include "sensrvsession.h"
+#include "sensrvserver.h"
+#include "sensrvtrace.h"
+#include "ssycontrol.h"
+#include "sensrvtransactionqueue.h"
+#include "sensrvmessage.h"
+#include "sensrvclientserver.h"
+#include "sensrvtransaction.h"
+#include "sensrvtypes.h"
+#include "sensrvprivatecrkeys.h"
+
+#ifdef __WINS__
+// Multiplier to avoid out of memory in emulator
+const TInt KSensrvSsyMaxHeapWinsMultiplier = 2;
+#endif // __WINS__
+
+
+// ---------------------------------------------------------------------------
+// 2-phase constructor
+// ---------------------------------------------------------------------------
+//
+CSensrvProxyManager* CSensrvProxyManager::NewL(CSensrvServer& aServer)
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::CSensrvProxyManager()" ) ) );
+
+ CSensrvProxyManager* self = new( ELeave ) CSensrvProxyManager(aServer);
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::CSensrvProxyManager - return 0x%x" ), self ) );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// C++ constructor
+// ---------------------------------------------------------------------------
+//
+CSensrvProxyManager::CSensrvProxyManager(CSensrvServer& aServer)
+ : iServer(aServer),
+ iTransactionTimeout(KSensrvDefaultTransactionTimeout),
+ iSsyStackSize(KSensrvDefaultSsyStackSize),
+ iSsyHeapMaxSize(KSensrvDefaultSsyHeapMaxSize),
+ iThreadTerminationGracePeriod(KSensrvSsyGracefulCleanupTime),
+ iSsyInactivityPeriod(KSensrvSsyInactivityPeriod),
+ iBufferSizeMultiplier(KSensrvDefaultDataRateMultiplier),
+ iTerminationPeriod(KSensrvDefaultTerminationPeriod)
+ {
+ // Nothing to do
+ }
+
+// ---------------------------------------------------------------------------
+// 2nd phase of construction
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::ConstructL()
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ConstructL()" ) ) );
+
+ User::LeaveIfError(iServerThread.Open(iServerThread.Id()));
+
+ iHeap = &User::Heap();
+
+ User::LeaveIfError(iProxyManagerMutex.CreateLocal());
+
+ // Get configurable settings
+ GetSettings();
+
+ iServerShutdown = CSensrvShutdown::NewL( *this );
+
+ iWaitQueueQueryChannels = CSensrvTransactionQueue::NewL(ETrue);
+ iWaitQueueOpenChannel = CSensrvTransactionQueue::NewL(ETrue);
+
+ // Create ecom changelistener, which will make the initial check for plugins
+ iEcomChangeListener = CSensrvEcomChangeListener::NewL(*this);
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ConstructL - return" ) ) );
+ }
+
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CSensrvProxyManager::~CSensrvProxyManager()
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::~CSensrvProxyManager()" ) ) );
+
+ if (iProxyCleaner)
+ {
+ iProxyCleaner->Cancel();
+ delete iProxyCleaner;
+ }
+
+ delete iEcomChangeListener;
+
+ // Cleanup iProxyList
+ TInt count = iProxyList.Count();
+ for(TInt i = 0; i < count; i++)
+ {
+ delete iProxyList[i];
+ }
+
+ iProxyList.Reset();
+
+ // Cleanup iWaitQueue
+ delete iWaitQueueQueryChannels;
+ delete iWaitQueueOpenChannel;
+
+ iProxyManagerMutex.Close();
+
+ iServerThread.Close();
+
+ if (iShutdownMessage.Handle())
+ {
+ iShutdownMessage.Complete(KErrCancel);
+ }
+
+ if (iSsyImplInfoArray)
+ {
+ iSsyImplInfoArray->ResetAndDestroy();
+ delete iSsyImplInfoArray;
+ }
+
+ delete iServerShutdown;
+
+ // iHeap not owned
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::~CSensrvProxyManager - return") ) );
+ }
+
+// -----------------------------------------------------------------------------
+// Handles message according to message type
+// -----------------------------------------------------------------------------
+//
+void CSensrvProxyManager::DispatchMessage( CSensrvMessage& aMessage )
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DispatchMessage(aMessage.Function(): %d), client SID: 0x%x" ), aMessage.Function(), aMessage.SecureId().iId ) );
+
+ // Check command code and call appropriate function
+ switch ( aMessage.Function() )
+ {
+ case ESensrvSrvReqQueryChannels:
+ {
+ QueryChannels(aMessage);
+ break;
+ }
+
+ case ESensrvSrvReqOpenChannel:
+ {
+ // Get channel ID from message
+ // No need to check error value, we already made sure the message function is correct
+
+ TSensrvChannelId channelId(0);
+ aMessage.GetChannelId(channelId);
+
+ // Determine which proxy handles this channel
+ CSensrvPluginProxy* proxy = GetProxyForChannel(channelId);
+
+ if( proxy != NULL &&
+ (proxy->PluginState() == CSensrvPluginProxy::EPluginStateUnloaded ||
+ proxy->PluginState() == CSensrvPluginProxy::EPluginStateUninitialized ) )
+ {
+ TRAPD(err, proxy->InitializePluginL());
+ if ( err != KErrNone )
+ {
+ // If proxy initialization fails, it means that proxy will not provide any channels.
+ // Since SSY thread has not been resumed yet (resume is the last thing in InitializeL), proxy
+ // can be safely deleted without risk for memory leak.
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged - ERROR: Proxy initialization failed, error %d" ), err) );
+ TInt pos( iProxyList.Find( proxy ) );
+ delete proxy;
+ proxy = NULL;
+ if ( pos >= 0 && pos < iProxyList.Count() )
+ {
+ iProxyList.Remove(pos);
+ }
+ }
+ }
+
+ // Dispatch the message for found proxy to be handled
+ if (proxy != NULL)
+ {
+ proxy->DispatchMessage(aMessage, channelId); // Transfer ownership of message
+ }
+ else
+ {
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DispatchMessage - ERROR: Proxy not found" )) );
+ // Complete with error
+ aMessage.Complete(KErrNotFound);
+ }
+ break;
+ }
+
+ case ESensrvSrvReqCloseChannel:
+ case ESensrvSrvReqStartListening:
+ case ESensrvSrvReqStopListening:
+ case ESensrvSrvReqAsyncChannelData:
+ case ESensrvSrvReqGetProperty:
+ case ESensrvSrvReqSetProperty:
+ case ESensrvSrvReqAsyncPropertyData:
+ case ESensrvSrvReqStopPropertyListening:
+ case ESensrvSrvReqGetAllProperties:
+ case ESensrvSrvReqAddConditionSet:
+ case ESensrvSrvReqRemoveConditionSet:
+ case ESensrvSrvReqStartConditionListening:
+ case ESensrvSrvReqStopConditionListening:
+ case ESensrvSrvReqAsyncConditionMet:
+ {
+ // Get channel ID from message
+ // No need to check error value, we already made sure the message function is correct
+ TSensrvChannelId channelId(0);
+ aMessage.GetChannelId(channelId);
+
+ // Determine which proxy handles this channel
+ CSensrvPluginProxy* proxy = GetProxyForChannel(channelId);
+
+ // Dispatch the message for found proxy to be handled
+ if (proxy != NULL)
+ {
+ proxy->DispatchMessage(aMessage, channelId); // Transfer ownership of message
+ }
+ else
+ {
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DispatchMessage - ERROR: Proxy not found" )) );
+ // Complete with error
+ aMessage.Complete(KErrNotFound);
+ }
+ break;
+ }
+
+ // Cannot identify the message
+ default:
+ {
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DispatchMessage - ERROR: unknown command" )) );
+ aMessage.Complete(KErrArgument);
+ break;
+ }
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DispatchMessage - return" )) );
+ }
+
+
+// ---------------------------------------------------------------------------
+// Generate new unique id.
+// ---------------------------------------------------------------------------
+//
+TInt CSensrvProxyManager::GenerateUniqueId()
+ {
+ iProxyManagerMutex.Wait();
+
+ iIdCounter++;
+
+ // Realistically, there will never be so many ids generated that the counter will roll over, but
+ // check just in case. No checking for duplicate ids, as chance of that happening is truly
+ // astronomical.
+ if (iIdCounter == KMaxTInt)
+ {
+ iIdCounter = 1;
+ }
+
+ iProxyManagerMutex.Signal();
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::GenerateUniqueId - generated new id: 0x%x" ), iIdCounter ) );
+
+ return iIdCounter;
+ }
+
+// ---------------------------------------------------------------------------
+// Checks waitqueue and if there are queued transactions,
+// checks if all proxies have constructed successfully.
+// If so, starts executing queued transactions.
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::NotifyProxyInitialized()
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::NotifyProxyInitialized()") ) );
+
+ TInt count = iProxyList.Count();
+ iAllProxiesInitialized = ETrue;
+
+ for(TInt i=0; i<count; i++)
+ {
+ if (!iProxyList[i]->IsInitialized())
+ {
+ iAllProxiesInitialized = EFalse;
+ break;
+ }
+ }
+
+ if (iAllProxiesInitialized)
+ {
+ HandleTransactionsQueryChannels();
+ HandleTransactionsOpenChannel();
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::NotifyProxyInitialized - All proxies not yet initialized") ) );
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::NotifyProxyInitialized - return" )) );
+ }
+
+// ---------------------------------------------------------------------------
+// Duplicates source handle to destination handle.
+// Source handle must be held by Server Main Thread
+// ---------------------------------------------------------------------------
+//
+TInt CSensrvProxyManager::DuplicateMutexHandle(const RMutex& aSrc, RMutex& aDst) const
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DuplicateMutexHandle(aSrc.Handle(): 0x%x, aDst.Handle(): 0x%x)"),aSrc.Handle(), aDst.Handle() ) );
+
+ aDst.SetHandle(aSrc.Handle());
+ TInt err = aDst.Duplicate(iServerThread);
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DuplicateMutexHandle - return %d" ), err) );
+
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// shuts down server gracefully
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::ShutdownServer(const RMessage2& aMessage)
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer(<RMessage2>)") ) );
+
+ if (iShutdownMessage.Handle())
+ {
+ // Already shutting down, complete
+ aMessage.Complete(KErrNone);
+ }
+ else
+ {
+ iShutdownMessage = aMessage;
+ ShutdownServer();
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer - return" )) );
+ }
+
+// ---------------------------------------------------------------------------
+// shuts down server gracefully
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::ShutdownServer()
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer()") ) );
+
+ if (!iShutdown)
+ {
+ iShutdown = ETrue;
+ iShuttingDownCount = 0;
+
+ // Cleanup proxies and solve amount of proxies to shutdown
+ TInt proxyCount = iProxyList.Count();
+ for (TInt i = 0; i < proxyCount; i++)
+ {
+ // Set deletion flag to disable usage attempts if shutdown was requested by client.
+ // Othwerwise usage attempt is allowed to cancel shutdown.
+ if (iShutdownMessage.Handle())
+ {
+ iProxyList[i]->SetDeletionFlag();
+ }
+
+ CSensrvPluginProxy::TPluginState pluginState = iProxyList[i]->PluginState();
+ if (pluginState == CSensrvPluginProxy::EPluginStateLoaded ||
+ pluginState == CSensrvPluginProxy::EPluginStateThreadInitializing ||
+ pluginState == CSensrvPluginProxy::EPluginStateThreadInitialized)
+ {
+ iProxyList[i]->CleanupPlugin();
+ iShuttingDownCount++;
+ }
+ else if (pluginState == CSensrvPluginProxy::EPluginStateUnloading)
+ {
+ // Plugin already unloading
+ iShuttingDownCount++;
+ }
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer - proxies to shutdown %d" ),
+ iShuttingDownCount ) );
+
+ // Shutdown right away, if no proxies to unload
+ if (!iShuttingDownCount)
+ {
+ SsyThreadTerminated();
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer - Already shutting down" )) );
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer - return" )) );
+ }
+
+// ---------------------------------------------------------------------------
+// Handles proxy thread termination
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::SsyThreadTerminated()
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SsyThreadTerminated() shutdown status %d"), iShutdown ) );
+
+ if (iShutdown)
+ {
+ if (iShuttingDownCount > 0)
+ {
+ --iShuttingDownCount;
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SsyThreadTerminated - proxies left %d "), iShuttingDownCount ) );
+ }
+ else
+ {
+ iShuttingDownCount = 0;
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SsyThreadTerminated - Proxies already shutdown") ) );
+ }
+
+ if (!iShuttingDownCount)
+ {
+ if (iShutdownMessage.Handle())
+ {
+ iShutdownMessage.Complete(KErrNone);
+ }
+ if (CActiveScheduler::Current())
+ {
+ CActiveScheduler::Stop();
+ CActiveScheduler::Install(NULL);
+ }
+ }
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SsyThreadTerminated - return" )) );
+ }
+
+// ---------------------------------------------------------------------------
+// Compares current implementation infos to new implementation infos
+// and determines if new proxies need to be loaded or old ones deleted.
+// ---------------------------------------------------------------------------
+//
+TBool CSensrvProxyManager::EcomChanged( RImplInfoPtrArray* aImplementationInfos )
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged(<array>)") ) );
+
+ TBool changes(EFalse);
+ TInt i(0);
+ TInt j(0);
+ TInt found(KErrNotFound);
+ TInt err(KErrNone);
+ TBool changeOk(ETrue);
+
+ __ASSERT_ALWAYS(aImplementationInfos, User::Panic(KSensrvPanicCategory, ESensrvPanicNullImplInfos));
+
+ // If no array previously registered this is first registration.
+ if (!iSsyImplInfoArray)
+ {
+ // First registration should always have some plugins or it is considered an error, although
+ // there might be devices that do not have any sensors as default. Since we only trace the
+ // error, this is not a problem.
+ if (!aImplementationInfos->Count())
+ {
+ ERROR_TRACE( ( _L("Sensor Server - CSensrvProxyManager::EcomChanged - Possible ERROR: No SSY plugins found. (This might be ok for some devices with no internal sensors)" ) ) );
+ }
+ }
+ else
+ {
+ // If still loading initial plugins, do not allow new changes until initial loads have completed.
+ if (!iAllProxiesInitialized)
+ {
+ changeOk = EFalse;
+ }
+ }
+
+ if (changeOk)
+ {
+ // Compare current implementation infos to new ones to find new plugins
+ for (i = 0; i < aImplementationInfos->Count(); i++)
+ {
+ found = KErrNotFound;
+
+ // Skip comparisons on the first time when there is no array to compare
+ if (iSsyImplInfoArray)
+ {
+ for (j = 0; found == KErrNotFound && j < iSsyImplInfoArray->Count(); j++)
+ {
+ if ((*iSsyImplInfoArray)[j]->ImplementationUid() == (*aImplementationInfos)[i]->ImplementationUid())
+ {
+ found = j;
+ }
+ }
+ }
+
+ // Create and initialize new proxy
+ if (found == KErrNotFound)
+ {
+ changes = ETrue;
+ CSensrvPluginProxy* proxy = AddProxy((*aImplementationInfos)[i]->ImplementationUid());
+
+ if (proxy)
+ {
+ CImplementationInformation* implInfo = (*aImplementationInfos)[i];
+ err = proxy->InitializeChannelData( *implInfo );
+ if ( err != KErrNone )
+ {
+ // If proxy initialization fails, it means that proxy will not provide any channels.
+ // Since SSY thread has not been resumed yet (resume is the last thing in InitializeL), proxy
+ // can be safely deleted without risk for memory leak.
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged - ERROR: Proxy initialization failed, error %d" ), err) );
+ TInt pos( iProxyList.Find( proxy ) );
+ delete proxy;
+ proxy = NULL;
+ if ( pos >= 0 && pos < iProxyList.Count() )
+ {
+ iProxyList.Remove(pos);
+ }
+ }
+ // Note: New channels are notified to interested clients after they are registered.
+ }
+ }
+ }
+
+ NotifyProxyInitialized();
+
+ // Skip the following comparisons entirely on the first time
+ if (iSsyImplInfoArray)
+ {
+ // Compare current implementation infos to new ones to find removed plugins
+ for (i = 0; i < iSsyImplInfoArray->Count(); i++)
+ {
+ found = KErrNotFound;
+
+ for (j = 0; found == KErrNotFound && j < aImplementationInfos->Count(); j++)
+ {
+ if ((*iSsyImplInfoArray)[i]->ImplementationUid() == (*aImplementationInfos)[j]->ImplementationUid())
+ {
+ found = j;
+ }
+ }
+
+ // Delete obsolete proxy
+ if (found == KErrNotFound)
+ {
+ changes = ETrue;
+
+ // Find proxy from proxy list
+ for (TInt z=0; found == KErrNotFound && z < iProxyList.Count(); z++)
+ {
+ if (iProxyList[z]->ImplementationUid() == (*iSsyImplInfoArray)[i]->ImplementationUid())
+ {
+ // Mark proxy for deletion.
+ iProxyList[z]->SetDeletionFlag();
+
+ // Notify channel removal
+ for (TInt x = 0; x < iProxyList[z]->ChannelInfoList().Count(); x++)
+ {
+ NotifyChannelChange((iProxyList[z]->ChannelInfoList())[x], ESensrvChannelChangeTypeRemoved);
+ }
+
+ // Clear any channels provided by proxy, so that it will not
+ // show up in further finds.
+ iProxyList[z]->ChannelInfoList().Reset();
+
+ // If plugin is not unloaded, it cannot be deleted without cleaning it up properly.
+ // Actual delete is done in ProxyCleanerCallback() in this case
+ if (iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateLoaded
+ || iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateThreadInitializing
+ || iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateThreadInitialized
+ || iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateUnloading)
+ {
+ // Cleanup plugin unless it is already unloading
+ if (iProxyList[z]->PluginState() != CSensrvPluginProxy::EPluginStateUnloading)
+ {
+ iProxyList[z]->CleanupPlugin();
+ }
+
+ if (!iProxyCleaner)
+ {
+ iProxyCleaner = CPeriodic::New(CActive::EPriorityStandard);
+
+ if (iProxyCleaner)
+ {
+ iProxyCleaner->Start(TTimeIntervalMicroSeconds32( KSensrvEcomRescanTimerPeriod ),
+ TTimeIntervalMicroSeconds32( KSensrvEcomRescanTimerPeriod ),
+ TCallBack( ProxyCleanerCallback, this ));
+ }
+ else
+ {
+ // Since cleaner cannot be constructed, proxy is left alive. Since it is marked
+ // for deletion, it will be quite unusable, however.
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged - Unable to create proxy cleaner" ) ) );
+ }
+ }
+ }
+ else
+ {
+ // Delete plugin outright, plugin is unloaded or uninitialized
+ delete iProxyList[z];
+ iProxyList.Remove(z);
+ }
+
+ found = z;
+ }
+ }
+ }
+ }
+ }
+
+ // Update iSsyImplInfoArray
+ if (!iSsyImplInfoArray)
+ {
+ // First time always assign the array
+ iSsyImplInfoArray = aImplementationInfos;
+ }
+ else if (changes)
+ {
+ iSsyImplInfoArray->ResetAndDestroy();
+ delete iSsyImplInfoArray;
+ iSsyImplInfoArray = aImplementationInfos;
+ }
+ else
+ {
+ // No changes, just destroy new infos
+ aImplementationInfos->ResetAndDestroy();
+ delete aImplementationInfos;
+ }
+
+ // If no proxies were successfully initialized,
+ // set initialized flag so that finds will not wait forever.
+ if (!iProxyList.Count())
+ {
+ iAllProxiesInitialized = ETrue;
+ }
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged - return %d" ), changeOk) );
+
+ return changeOk;
+ }
+
+// ---------------------------------------------------------------------------
+// Orders server to notify all interested client sessions. Notifications
+// are not sent until all proxies have finished initializing to
+// avoid notifications about initial plugin loads.
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::NotifyChannelChange(const TSensrvResourceChannelInfo& aChangedChannel,
+ TSensrvChannelChangeType aChangeType )
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::NotifyChannelChange(aChangedChannel.iChannelId: %d, aChangeType: %d)"), aChangedChannel.iChannelId, aChangeType ) );
+
+ if (iAllProxiesInitialized)
+ {
+ iServer.NotifyChannelChange(aChangedChannel, aChangeType);
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::NotifyChannelChange - return" )) );
+ }
+
+// ---------------------------------------------------------------------------
+// Cleans up everything related to terminated session.
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::SessionTerminated( CSensrvSession* aSession )
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SessionTerminated(aSession: 0x%x)"),aSession ) );
+
+ // Cleanup any waiting transactions for this session
+ iWaitQueueQueryChannels->Remove(aSession);
+ iWaitQueueOpenChannel->Remove(aSession);
+
+ if (iSessionCounter > 0)
+ {
+ iSessionCounter--;
+ }
+ else
+ {
+ iSessionCounter = 0;
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SessionTerminated - Already no sessions") ) );
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SessionTerminated - Amount of sessions %d"), iSessionCounter ) );
+
+ if (!iSessionCounter)
+ {
+ // Shutdown server after timer since no more clients
+ iServerShutdown->Start();
+ }
+
+ // Call session cleanup on each proxy
+ TInt proxyCount = iProxyList.Count();
+ for(TInt i = 0; i < proxyCount; i++)
+ {
+ iProxyList[i]->SessionTerminated(aSession);
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SessionTerminated - return" )) );
+ }
+
+
+// ---------------------------------------------------------------------------
+// Executes queued transactions.
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::HandleTransactionsQueryChannels()
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactionsQueryChannels()") ) );
+
+ if (iWaitQueueQueryChannels)
+ {
+ while (!iWaitQueueQueryChannels->IsEmpty())
+ {
+ TInt err(KErrNone);
+
+ CSensrvTransaction* transaction = iWaitQueueQueryChannels->First();
+
+ if (transaction->State() == CSensrvTransaction::ETransStateQueued)
+ {
+ // Read required channel information from message
+ TSensrvResourceChannelInfoPckgBuf pckg;
+
+ __ASSERT_ALWAYS(transaction->Message(), User::Panic(KSensrvPanicCategory, ESensrvPanicNullMessage));
+
+ err = transaction->Message()->Read( KSensrvQueryChannelsQueryParametersSlot, pckg );
+ if(err == KErrNone && transaction->Message()->Handle())
+ {
+ TSensrvResourceChannelInfo queryInfo = pckg();
+ const RMessage2& queryMessage(transaction->Message()->GetMessage());
+
+ if (LoadDynamicChannelSsysIfNeeded(queryInfo, queryMessage, EFalse))
+ {
+ // Continue wait queue processing after the required SSYs are loaded
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactionsQueryChannels() - Waiting for SSYs to be loaded") ) );
+ break;
+ }
+
+ transaction->SetState(CSensrvTransaction::ETransStateExecuting);
+
+ // Go through all proxies and add matches to return array.
+ RSensrvChannelInfoList matchingInfos;
+ TInt proxyCount = iProxyList.Count();
+ for (TInt i = 0; i < proxyCount; ++i)
+ {
+ CSensrvPluginProxy* proxy = iProxyList[i];
+ TInt channelCount = proxy->ChannelInfoList().Count();
+ for (TInt j = 0; j < channelCount; ++j)
+ {
+ const TSensrvResourceChannelInfo& info(proxy->ChannelInfoList()[j]);
+ if (info.IsMatch(queryInfo, queryMessage))
+ {
+ err = matchingInfos.Append(info);
+ if (err != KErrNone)
+ {
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactionsQueryChannels - ERROR: Append of matching info failed, error %d" ), err) );
+ break;
+ }
+ }
+ }
+ }
+#ifdef COMPONENT_TRACE_DEBUG
+ COMPONENT_TRACE( ( _L( "### Found channels:" )) );
+ TraceChannelInfoList(matchingInfos);
+#endif
+ if (err == KErrNone)
+ {
+ // Write found infos to message
+ err = transaction->SetMessageData(&matchingInfos);
+ }
+
+ matchingInfos.Reset();
+ }
+ else
+ {
+ transaction->SetState(CSensrvTransaction::ETransStateExecuting);
+ }
+
+ if (err != KErrNone)
+ {
+ transaction->SetErrorCode(err);
+ }
+
+ // Complete transaction
+ iWaitQueueQueryChannels->Remove(transaction, CSensrvTransactionQueue::ERemovalTypeComplete);
+ transaction = NULL;
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactionsQueryChannels - Transaction already executing, do nothing." )) );
+ }
+ } // end while
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactionsQueryChannels - return" )) );
+ }
+
+// ---------------------------------------------------------------------------
+// Executes queued transactions.
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::HandleTransactionsOpenChannel()
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactions()") ) );
+
+ if (iWaitQueueOpenChannel)
+ {
+ while (!iWaitQueueOpenChannel->IsEmpty())
+ {
+ TInt err(KErrNone);
+
+ CSensrvTransaction* transaction = iWaitQueueOpenChannel->First();
+
+ if (transaction->State() == CSensrvTransaction::ETransStateQueued)
+ {
+ transaction->SetState(CSensrvTransaction::ETransStateExecuting);
+
+ __ASSERT_ALWAYS(transaction->Message(), User::Panic(KSensrvPanicCategory, ESensrvPanicNullMessage));
+
+ // Get channel ID from message
+ // No need to check error value, we already made sure the message function is correct
+ TSensrvChannelId channelId(0);
+ err = transaction->Message()->GetChannelId(channelId);
+
+ if(err == KErrNone)
+ {
+
+ // Determine which proxy handles this channel
+ CSensrvPluginProxy* proxy = GetProxyForChannel(channelId);
+
+ if( proxy != NULL &&
+ ( proxy->PluginState() == CSensrvPluginProxy::EPluginStateUnloaded ||
+ proxy->PluginState() == CSensrvPluginProxy::EPluginStateUninitialized ) )
+ {
+ TRAPD(err, proxy->InitializePluginL());
+ if ( err != KErrNone )
+ {
+ // If proxy initialization fails, it means that proxy will not provide any channels.
+ // Since SSY thread has not been resumed yet (resume is the last thing in InitializeL), proxy
+ // can be safely deleted without risk for memory leak.
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged - ERROR: Proxy initialization failed, error %d" ), err) );
+ TInt pos( iProxyList.Find( proxy ) );
+ delete proxy;
+ proxy = NULL;
+ if ( pos >= 0 && pos < iProxyList.Count() )
+ {
+ iProxyList.Remove(pos);
+ }
+ }
+ }
+
+ // Dispatch the message for found proxy to be handled
+ if (proxy != NULL)
+ {
+ proxy->DispatchMessage(*transaction->Message(), channelId); // Transfer ownership of message
+ }
+ }
+ else
+ {
+ transaction->SetErrorCode(err);
+ }
+ // Complete transaction
+ iWaitQueueOpenChannel->Remove(transaction, CSensrvTransactionQueue::ERemovalTypeComplete);
+ transaction = NULL;
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactions - Transaction already executing, do nothing." )) );
+ }
+ } // end while
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactions - return" )) );
+ }
+
+// ---------------------------------------------------------------------------
+// Checks all channels provided by proxies and returns information matching
+// the query parameters.
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::QueryChannels(CSensrvMessage& aMessage)
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels(aMessage: 0x%x, <aQueryParams>)" ), &aMessage ) );
+
+ // Create transaction
+ CSensrvTransaction* queryTransaction = NULL;
+ TRAPD(err, queryTransaction = CSensrvTransaction::NewL(
+ &aMessage,
+ NULL,
+ NULL,
+ CSensrvTransaction::ETransTypeClientQueryChannels));
+
+ if (err == KErrNone)
+ {
+ // queue transaction
+ queryTransaction->SetState(CSensrvTransaction::ETransStateQueued);
+
+ err = iWaitQueueQueryChannels->Add(queryTransaction);
+
+ if (err == KErrNone)
+ {
+ // Execute transaction if all proxies initialized
+ if (iAllProxiesInitialized)
+ {
+ HandleTransactionsQueryChannels();
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - All proxies not yet initialized") ) );
+ }
+ }
+ else
+ {
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - ERROR: Transaction adding to queue failed" )) );
+ }
+ }
+ else
+ {
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - ERROR: Transaction creation failed" )) );
+ }
+
+ // Handle error
+ if (err != KErrNone)
+ {
+ if(queryTransaction)
+ {
+ queryTransaction->SetErrorCode(err);
+ queryTransaction->Complete();
+ delete queryTransaction;
+ queryTransaction = NULL;
+ }
+ else
+ {
+ // Do nothing, message gets deleted and completed with KErrGeneral on transaction desctructor.
+ }
+ }
+
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - return" )) );
+ }
+
+// ---------------------------------------------------------------------------
+// Checks all channels provided by proxies and returns information matching
+// the query parameters.
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::OpenChannel(CSensrvMessage& aMessage)
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels(aMessage: 0x%x, <aQueryParams>)" ), &aMessage ) );
+
+ // Create transaction
+ CSensrvTransaction* queryTransaction = NULL;
+ TRAPD(err, queryTransaction = CSensrvTransaction::NewL(
+ &aMessage,
+ NULL,
+ NULL,
+ CSensrvTransaction::ETransTypeOpenChannel));
+
+ if (err == KErrNone)
+ {
+ // queue transaction
+ queryTransaction->SetState(CSensrvTransaction::ETransStateQueued);
+
+ err = iWaitQueueOpenChannel->Add(queryTransaction);
+
+ if (err == KErrNone)
+ {
+ // Execute transaction if all proxies initialized
+ if (iAllProxiesInitialized)
+ {
+ HandleTransactionsOpenChannel();
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - All proxies not yet initialized") ) );
+ }
+ }
+ else
+ {
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - ERROR: Transaction adding to queue failed" )) );
+ }
+ }
+ else
+ {
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - ERROR: Transaction creation failed" )) );
+ }
+
+ // Handle error
+ if (err != KErrNone)
+ {
+ if(queryTransaction)
+ {
+ queryTransaction->SetErrorCode(err);
+ queryTransaction->Complete();
+ delete queryTransaction;
+ queryTransaction = NULL;
+ }
+ else
+ {
+ // Do nothing, message gets deleted and completed with KErrGeneral on transaction desctructor.
+ }
+ }
+
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - return" )) );
+ }
+
+// ---------------------------------------------------------------------------
+// Gets the proxy that handles the specified channel.
+// NULL is returned if channel is not found.
+// ---------------------------------------------------------------------------
+//
+CSensrvPluginProxy* CSensrvProxyManager::GetProxyForChannel(TSensrvChannelId aChannelId) const
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::GetProxyForChannel(aChannelId: %d)" ), aChannelId ) );
+
+ CSensrvPluginProxy* returnProxy = NULL;
+
+ TInt proxyCount = iProxyList.Count();
+ for(TInt i = 0; !returnProxy && i < proxyCount; i++)
+ {
+ if (iProxyList[i]->IsChannelSupported(aChannelId))
+ {
+ returnProxy = iProxyList[i];
+ }
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::GetProxyForChannel - return 0x%x" ), returnProxy) );
+
+ return returnProxy;
+ }
+
+// ---------------------------------------------------------------------------
+// Fetches configurable settings from cenrep
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::GetSettings()
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvChannel::GetSettings()" ) ) );
+
+ TInt err(KErrNone);
+
+ // Open settings repository and get necessary values
+ CRepository* repository = NULL;
+ TRAP( err, repository = CRepository::NewL(KCRUidSensorServerSettings) );
+
+ if ( err == KErrNone )
+ {
+ TInt value(0);
+ err = repository->Get(KSensrvTransactionTimeoutKey, value);
+ if ( err == KErrNone )
+ {
+ if ( value > 0 )
+ {
+ iTransactionTimeout = value*KSecondsToMicros;
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvTransactionTimeoutKey value getting failed: %d, using default value." ), err) );
+ }
+
+ err = repository->Get(KSensrvSsyThreadStackSizeKey, value);
+ if ( err == KErrNone )
+ {
+ if ( value > 0 )
+ {
+ iSsyStackSize = value;
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvSsyThreadStackSizeKey value getting failed: %d, using default value." ), err) );
+ }
+
+ err = repository->Get(KSensrvSsyThreadHeapMaxSizeKey, value);
+ if ( err == KErrNone )
+ {
+#ifdef __WINS__
+ value *= KSensrvSsyMaxHeapWinsMultiplier;
+#endif // __WINS__
+ if ( value < KSensrvSsyHeapInitialSize )
+ {
+ iSsyHeapMaxSize = KSensrvSsyHeapInitialSize;
+ }
+ else if (value > 0)
+ {
+ iSsyHeapMaxSize = value;
+ }
+ else
+ {
+ // Do nothing, default is used
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvSsyThreadHeapMaxSizeKey value getting failed: %d, using default value." ), err) );
+ }
+
+ err = repository->Get(KSensrvThreadTerminationPeriodKey, value);
+ if ( err == KErrNone )
+ {
+ if ( value > 0 )
+ {
+ iThreadTerminationGracePeriod = value*KSecondsToMicros;
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvThreadTerminationPeriodKey value getting failed: %d, using default value." ), err) );
+ }
+
+ err = repository->Get(KSensrvSsyInactivityPeriodKey, value);
+ if ( err == KErrNone )
+ {
+ if ( value > 0 )
+ {
+ iSsyInactivityPeriod = value*KSecondsToMicros;
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvSsyInactivityPeriodKey value getting failed: %d, using default value." ), err) );
+ }
+
+ err = repository->Get(KSensrvBufferSizeMultiplierKey, value);
+ if ( err == KErrNone )
+ {
+ if ( value > 0 )
+ {
+ iBufferSizeMultiplier = value;
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvBufferSizeMultiplierKey value getting failed: %d, using default value." ), err) );
+ }
+ err = repository->Get(KSensrvTerminationPeriodKey, value);
+ if ( err == KErrNone )
+ {
+ if ( value >= 0 )
+ {
+ iTerminationPeriod = value*KSecondsToMicros;
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvTerminationPeriodKey value getting failed: %d, using default value." ), err) );
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - Settings repository opening failed: %d" ), err) );
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iTransactionTimeout: %d" ), iTransactionTimeout.Int()) );
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iSsyStackSize: %d" ), iSsyStackSize) );
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iSsyHeapMaxSize: %d" ), iSsyHeapMaxSize) );
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iThreadTerminationGracePeriod: %d" ), iThreadTerminationGracePeriod.Int()) );
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iSsyInactivityPeriod: %d" ), iSsyInactivityPeriod.Int()) );
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iBufferSizeMultiplier: %d" ), iBufferSizeMultiplier) );
+
+ // Cleanup repository
+ delete repository;
+ repository = NULL;
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvChannel::GetSettings - return" ) ) );
+ }
+
+// ---------------------------------------------------------------------------
+// Create new proxy and add it to proxy list
+// ---------------------------------------------------------------------------
+//
+CSensrvPluginProxy* CSensrvProxyManager::AddProxy(const TUid& aProxyUid)
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddProxy(0x%x)" ), aProxyUid.iUid ) );
+
+ // Create proxy
+ TInt err(KErrNone);
+ CSensrvPluginProxy* proxy = NULL;
+ TRAP(err, proxy = CSensrvPluginProxy::NewL(*this,aProxyUid));
+
+ if ( err != KErrNone )
+ {
+ // Error loading a plugin is not critical, it just means
+ // that channels provided by plugin are unavailable.
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddProxy - ERROR: creating proxy failed, implementationUid: 0x%x, error: %d" ), aProxyUid.iUid , err ) );
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddProxy - Proxy for implementation 0x%x created successfully." ), aProxyUid.iUid ) );
+
+ // Add proxy to list
+ err = iProxyList.Append(proxy);
+ if ( err != KErrNone )
+ {
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddProxy - ERROR: Saving plugin info failed, implementationUid: 0x%x, error %d" ), aProxyUid.iUid , err) );
+ delete proxy;
+ proxy = NULL;
+ }
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddProxy - return 0x%x" ), proxy ) );
+
+ return proxy;
+ }
+
+// ---------------------------------------------------------------------------
+// CSensrvProxyManager::ProxyCleanerCallback
+// ---------------------------------------------------------------------------
+//
+TInt CSensrvProxyManager::ProxyCleanerCallback( TAny* aObject )
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ProxyCleanerCallback(this)" ) ) );
+
+ __ASSERT_ALWAYS(aObject, User::Panic(KSensrvPanicCategory, ESensrvPanicNullCallback));
+
+ CSensrvProxyManager* manager = reinterpret_cast<CSensrvProxyManager*>( aObject );
+ TBool noMore(ETrue);
+
+ for (TInt z = manager->iProxyList.Count() - 1; z >= 0; z--)
+ {
+ if (manager->iProxyList[z]->IsMarkedForDeletion())
+ {
+ if (manager->iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateLoaded
+ || manager->iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateThreadInitializing
+ || manager->iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateThreadInitialized
+ || manager->iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateUnloading)
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ProxyCleanerCallback - Proxy still not unloaded, try deletion again later" ) ) );
+ noMore = EFalse;
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ProxyCleanerCallback - Proxy unloaded, deleting..." ) ) );
+ delete manager->iProxyList[z];
+ manager->iProxyList.Remove(z);
+ }
+ }
+ }
+
+ // Delete iProxyCleaner if no more
+ if (noMore)
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ProxyCleanerCallback - No more proxies to unload, deleting cleaner..." ) ) );
+ delete manager->iProxyCleaner;
+ manager->iProxyCleaner = NULL;
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ProxyCleanerCallback - return " ) ) );
+
+ return KErrNone;
+ }
+
+#ifdef COMPONENT_TRACE_DEBUG
+// ---------------------------------------------------------------------------
+// Traces channel info list contents
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::TraceChannelInfoList(const RSensrvResourceChannelInfoList& aInfoList)
+ {
+ // Debug found channels
+ if (aInfoList.Count())
+ {
+ for(TInt z = 0; z < aInfoList.Count(); z++)
+ {
+ // Convert location and vendorID from 8bit to 16 bit for proper printing
+ TInt len = aInfoList[z].iVendorId.Length();
+ HBufC16* vidBuf16 = HBufC16::New(len);
+ if( vidBuf16 )
+ {
+ vidBuf16->Des().Copy(aInfoList[z].iVendorId);
+ }
+
+ len = aInfoList[z].iLocation.Length();
+ HBufC16* locBuf16 = HBufC16::New(len);
+ if( locBuf16 )
+ {
+ locBuf16->Des().Copy(aInfoList[z].iLocation);
+ }
+ COMPONENT_TRACE( ( _L( "### Info %d: iChannelId: %d, iContextType: 0x%x, iQuantity: 0x%x, iChannelType: 0x%x, iLocation: \"%S\", iVendorId: \"%S\", iDataItemSize: %d " ),
+ z,
+ aInfoList[z].iChannelId,
+ aInfoList[z].iContextType,
+ aInfoList[z].iQuantity,
+ aInfoList[z].iChannelType,
+ locBuf16 ? locBuf16 : &KSensrvNullString,
+ vidBuf16 ? vidBuf16 : &KSensrvNullString,
+ aInfoList[z].iDataItemSize) );
+ if( locBuf16 )
+ delete locBuf16;
+ if( vidBuf16 )
+ delete vidBuf16;
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "### List is empty." ) ));
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Traces channel info list contents
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::TraceChannelInfoList(const RSensrvChannelInfoList& aInfoList)
+ {
+ // Debug found channels
+ if (aInfoList.Count())
+ {
+ for(TInt z = 0; z < aInfoList.Count(); z++)
+ {
+ // Convert location and vendorID from 8bit to 16 bit for proper printing
+ TInt len = aInfoList[z].iVendorId.Length();
+ HBufC16* vidBuf16 = HBufC16::New(len);
+ if( vidBuf16 )
+ {
+ vidBuf16->Des().Copy(aInfoList[z].iVendorId);
+ }
+
+ len = aInfoList[z].iLocation.Length();
+ HBufC16* locBuf16 = HBufC16::New(len);
+ if( locBuf16 )
+ {
+ locBuf16->Des().Copy(aInfoList[z].iLocation);
+ }
+
+ COMPONENT_TRACE( ( _L( "### Info %d: iChannelId: %d, iContextType: 0x%x, iQuantity: 0x%x, iChannelType: 0x%x, iLocation: \"%S\", iVendorId: \"%S\", iDataItemSize: %d " ),
+ z,
+ aInfoList[z].iChannelId,
+ aInfoList[z].iContextType,
+ aInfoList[z].iQuantity,
+ aInfoList[z].iChannelType,
+ locBuf16 ? locBuf16 : &KSensrvNullString,
+ vidBuf16 ? vidBuf16 : &KSensrvNullString,
+ aInfoList[z].iDataItemSize) );
+ if( locBuf16 )
+ delete locBuf16;
+ if( vidBuf16 )
+ delete vidBuf16;
+
+ }
+ }
+ else
+ {
+ COMPONENT_TRACE( ( _L( "### List is empty." ) ));
+ }
+ }
+#endif
+
+// ---------------------------------------------------------------------------
+// Cleanup item implementation for plugin initialization
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::AddSession()
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddSession" ) ) );
+
+ if ( iServerShutdown->IsActive( ) )
+ {
+ iServerShutdown->Cancel();
+ }
+ iSessionCounter++;
+
+ // Cancel shutdown if it was not requested by client
+ if ( !iShutdownMessage.Handle() )
+ {
+ iShutdown = EFalse;
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddSession sessions: %d - return" ), iSessionCounter ) );
+ }
+
+// ---------------------------------------------------------------------------
+// Loads the dynamic channel SSYs that matches to given query if not loaded
+// ---------------------------------------------------------------------------
+//
+TBool CSensrvProxyManager::LoadDynamicChannelSsysIfNeeded(const TSensrvResourceChannelInfo& aQueryInfo,
+ const RMessage2& aQueryMessage,
+ TBool aAddChannelChangeListener)
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::LoadDynamicChannelSsysIfNeeded" ) ) );
+ TBool ssyLoadPending = EFalse;
+ TInt proxyCount = iProxyList.Count();
+ for (TInt i = 0; i < proxyCount; ++i)
+ {
+ CSensrvPluginProxy* proxy = iProxyList[i];
+ TInt channelCount = proxy->DynamicChannelInfoList().Count();
+ for (TInt j = 0; j < channelCount; ++j)
+ {
+ if (proxy->DynamicChannelInfoList()[j].IsMatch(aQueryInfo, aQueryMessage))
+ {
+ CSensrvPluginProxy::TPluginState pluginState = proxy->PluginState();
+ if (pluginState == CSensrvPluginProxy::EPluginStateUninitialized ||
+ pluginState == CSensrvPluginProxy::EPluginStateUnloaded ||
+ pluginState == CSensrvPluginProxy::EPluginStateUnloading)
+ {
+ if (!proxy->PreviousSsyLoadFailed()) // If loading failed earlier, ignore new attempt to avoid query deadlocks
+ {
+ TRAPD(err, proxy->InitializePluginL());
+ if (err == KErrNone)
+ {
+ ssyLoadPending = ETrue;
+ }
+ else
+ {
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::LoadDynamicChannelSsysIfNeeded - ERROR: SSY 0x%x initialization failed, error %d" ),
+ proxy->ImplementationUid().iUid, err ) );
+ }
+ }
+ else
+ {
+ ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::LoadDynamicChannelSsysIfNeeded - Ignoring SSY 0x%x initialization" ),
+ proxy->ImplementationUid().iUid ) );
+ }
+ }
+ else if (pluginState == CSensrvPluginProxy::EPluginStateThreadInitializing)
+ {
+ ssyLoadPending = ETrue;
+ }
+ if (aAddChannelChangeListener)
+ {
+ proxy->AddChannelChangeListener();
+ }
+ break; // Move on to next proxy
+ }
+ }
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::LoadDynamicChannelSsysIfNeeded - return %d" ), ssyLoadPending ) );
+ return ssyLoadPending;
+ }
+
+// ---------------------------------------------------------------------------
+// Removes channel change listener from the matching dynamic channel SSYs to allow unloading
+// ---------------------------------------------------------------------------
+//
+void CSensrvProxyManager::RemoveChannelChangeListenerFromDynamicChannelSsys(const TSensrvResourceChannelInfo& aQueryInfo,
+ const RMessage2& aQueryMessage)
+ {
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::RemoveChannelChangeListenerFromDynamicChannelSsys" ) ) );
+
+ TInt proxyCount = iProxyList.Count();
+ for(TInt i = 0; i < proxyCount; ++i)
+ {
+ CSensrvPluginProxy* proxy = iProxyList[i];
+ TInt channelCount = proxy->DynamicChannelInfoList().Count();
+ for(TInt j = 0; j < channelCount; ++j)
+ {
+ if (proxy->DynamicChannelInfoList()[j].IsMatch(aQueryInfo, aQueryMessage))
+ {
+ proxy->RemoveChannelChangeListener();
+ break; // Move on to next proxy
+ }
+ }
+ }
+
+ COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::RemoveChannelChangeListenerFromDynamicChannelSsys - return" ) ) );
+ }
+
+// End of file