sensorservices/sensorserver/src/server/sensrvproxymanager.cpp
changeset 0 4e1aa6a622a0
child 59 0f7422b6b602
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 /*
       
     2 * Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Sensor server proxy manager
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <centralrepository.h>
       
    20 #include "sensrvdefines.h"
       
    21 #include "sensrvproxymanager.h"
       
    22 #include "sensrvsession.h"
       
    23 #include "sensrvserver.h"
       
    24 #include "sensrvtrace.h"
       
    25 #include "ssycontrol.h"
       
    26 #include "sensrvtransactionqueue.h"
       
    27 #include "sensrvmessage.h"
       
    28 #include "sensrvclientserver.h"
       
    29 #include "sensrvtransaction.h"
       
    30 #include "sensrvtypes.h"
       
    31 #include "sensrvprivatecrkeys.h"
       
    32 
       
    33 #ifdef __WINS__
       
    34 // Multiplier to avoid out of memory in emulator
       
    35 const TInt KSensrvSsyMaxHeapWinsMultiplier = 2;
       
    36 #endif // __WINS__
       
    37 
       
    38 
       
    39 // ---------------------------------------------------------------------------
       
    40 // 2-phase constructor
       
    41 // ---------------------------------------------------------------------------
       
    42 //
       
    43 CSensrvProxyManager* CSensrvProxyManager::NewL(CSensrvServer& aServer)
       
    44     {
       
    45     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::CSensrvProxyManager()" ) ) );
       
    46 
       
    47     CSensrvProxyManager* self = new( ELeave ) CSensrvProxyManager(aServer);
       
    48 
       
    49     CleanupStack::PushL( self );
       
    50     self->ConstructL();
       
    51     CleanupStack::Pop( self );
       
    52 
       
    53     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::CSensrvProxyManager - return 0x%x" ), self ) );
       
    54     return self;
       
    55     }
       
    56 
       
    57 // ---------------------------------------------------------------------------
       
    58 // C++ constructor
       
    59 // ---------------------------------------------------------------------------
       
    60 //
       
    61 CSensrvProxyManager::CSensrvProxyManager(CSensrvServer& aServer)
       
    62     : iServer(aServer),
       
    63       iTransactionTimeout(KSensrvDefaultTransactionTimeout),
       
    64       iSsyStackSize(KSensrvDefaultSsyStackSize),
       
    65       iSsyHeapMaxSize(KSensrvDefaultSsyHeapMaxSize),
       
    66       iThreadTerminationGracePeriod(KSensrvSsyGracefulCleanupTime),
       
    67       iSsyInactivityPeriod(KSensrvSsyInactivityPeriod),
       
    68       iBufferSizeMultiplier(KSensrvDefaultDataRateMultiplier),
       
    69       iTerminationPeriod(KSensrvDefaultTerminationPeriod)
       
    70     {
       
    71     // Nothing to do
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // 2nd phase of construction
       
    76 // ---------------------------------------------------------------------------
       
    77 //
       
    78 void CSensrvProxyManager::ConstructL()
       
    79     {
       
    80     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ConstructL()" ) ) );
       
    81 
       
    82     User::LeaveIfError(iServerThread.Open(iServerThread.Id()));
       
    83 
       
    84     iHeap = &User::Heap();
       
    85 
       
    86     User::LeaveIfError(iProxyManagerMutex.CreateLocal());
       
    87 
       
    88     // Get configurable settings
       
    89     GetSettings();
       
    90 
       
    91     iServerShutdown = CSensrvShutdown::NewL( *this );
       
    92 
       
    93     iWaitQueueQueryChannels = CSensrvTransactionQueue::NewL(ETrue);
       
    94     iWaitQueueOpenChannel   = CSensrvTransactionQueue::NewL(ETrue);
       
    95 
       
    96     // Create ecom changelistener, which will make the initial check for plugins
       
    97     iEcomChangeListener = CSensrvEcomChangeListener::NewL(*this);
       
    98 
       
    99     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ConstructL - return" ) ) );
       
   100     }
       
   101 
       
   102 
       
   103 // -----------------------------------------------------------------------------
       
   104 // Destructor
       
   105 // -----------------------------------------------------------------------------
       
   106 //
       
   107 CSensrvProxyManager::~CSensrvProxyManager()
       
   108     {
       
   109     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::~CSensrvProxyManager()" ) ) );
       
   110 
       
   111     if (iProxyCleaner)
       
   112         {
       
   113         iProxyCleaner->Cancel();
       
   114         delete iProxyCleaner;
       
   115         }
       
   116 
       
   117     delete iEcomChangeListener;
       
   118 
       
   119     // Cleanup iProxyList
       
   120     TInt count = iProxyList.Count();
       
   121     for(TInt i = 0; i < count; i++)
       
   122         {
       
   123         delete iProxyList[i];
       
   124         }
       
   125 
       
   126     iProxyList.Reset();
       
   127 
       
   128     // Cleanup iWaitQueue
       
   129     delete iWaitQueueQueryChannels;
       
   130     delete iWaitQueueOpenChannel;
       
   131 
       
   132     iProxyManagerMutex.Close();
       
   133 
       
   134     iServerThread.Close();
       
   135 
       
   136     if (iShutdownMessage.Handle())
       
   137         {
       
   138         iShutdownMessage.Complete(KErrCancel);
       
   139         }
       
   140 
       
   141     if (iSsyImplInfoArray)
       
   142         {
       
   143         iSsyImplInfoArray->ResetAndDestroy();
       
   144         delete iSsyImplInfoArray;
       
   145         }
       
   146 
       
   147     delete iServerShutdown;
       
   148 
       
   149     // iHeap not owned
       
   150 
       
   151     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::~CSensrvProxyManager - return") ) );
       
   152     }
       
   153 
       
   154 // -----------------------------------------------------------------------------
       
   155 // Handles message according to message type
       
   156 // -----------------------------------------------------------------------------
       
   157 //
       
   158 void CSensrvProxyManager::DispatchMessage( CSensrvMessage& aMessage )
       
   159     {
       
   160     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DispatchMessage(aMessage.Function(): %d), client SID: 0x%x" ), aMessage.Function(), aMessage.SecureId().iId ) );
       
   161 
       
   162     // Check command code and call appropriate function
       
   163     switch ( aMessage.Function() )
       
   164         {
       
   165         case ESensrvSrvReqQueryChannels:
       
   166             {
       
   167             QueryChannels(aMessage);
       
   168             break;
       
   169             }
       
   170 
       
   171         case ESensrvSrvReqOpenChannel:
       
   172             {
       
   173             // Get channel ID from message
       
   174             // No need to check error value, we already made sure the message function is correct
       
   175 
       
   176             TSensrvChannelId channelId(0);
       
   177             aMessage.GetChannelId(channelId);
       
   178 
       
   179             // Determine which proxy handles this channel
       
   180             CSensrvPluginProxy* proxy = GetProxyForChannel(channelId);
       
   181 
       
   182             if( proxy != NULL &&
       
   183                 (proxy->PluginState() == CSensrvPluginProxy::EPluginStateUnloaded ||
       
   184                  proxy->PluginState() == CSensrvPluginProxy::EPluginStateUninitialized ) )
       
   185                 {
       
   186                 TRAPD(err, proxy->InitializePluginL());
       
   187                 if ( err != KErrNone )
       
   188                     {
       
   189                     // If proxy initialization fails, it means that proxy will not provide any channels.
       
   190                     // Since SSY thread has not been resumed yet (resume is the last thing in InitializeL), proxy
       
   191                     // can be safely deleted without risk for memory leak.
       
   192                     ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged - ERROR: Proxy initialization failed, error %d" ),  err) );
       
   193                     TInt pos( iProxyList.Find( proxy ) );
       
   194                     delete proxy;
       
   195                     proxy = NULL;
       
   196                     if ( pos >= 0 && pos < iProxyList.Count() )
       
   197                         {
       
   198                         iProxyList.Remove(pos);
       
   199                         }
       
   200                     }
       
   201                 }
       
   202 
       
   203             // Dispatch the message for found proxy to be handled
       
   204             if (proxy != NULL)
       
   205                 {
       
   206                 proxy->DispatchMessage(aMessage, channelId); // Transfer ownership of message
       
   207                 }
       
   208             else
       
   209                 {
       
   210                 ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DispatchMessage - ERROR: Proxy not found" )) );
       
   211                 // Complete with error
       
   212                 aMessage.Complete(KErrNotFound);
       
   213                 }
       
   214             break;
       
   215             }
       
   216 
       
   217         case ESensrvSrvReqCloseChannel:
       
   218         case ESensrvSrvReqStartListening:
       
   219         case ESensrvSrvReqStopListening:
       
   220         case ESensrvSrvReqAsyncChannelData:
       
   221         case ESensrvSrvReqGetProperty:
       
   222         case ESensrvSrvReqSetProperty:
       
   223         case ESensrvSrvReqAsyncPropertyData:
       
   224         case ESensrvSrvReqStopPropertyListening:
       
   225         case ESensrvSrvReqGetAllProperties:
       
   226         case ESensrvSrvReqAddConditionSet:
       
   227         case ESensrvSrvReqRemoveConditionSet:
       
   228         case ESensrvSrvReqStartConditionListening:
       
   229         case ESensrvSrvReqStopConditionListening:
       
   230         case ESensrvSrvReqAsyncConditionMet:
       
   231             {
       
   232             // Get channel ID from message
       
   233             // No need to check error value, we already made sure the message function is correct
       
   234             TSensrvChannelId channelId(0);
       
   235             aMessage.GetChannelId(channelId);
       
   236 
       
   237             // Determine which proxy handles this channel
       
   238             CSensrvPluginProxy* proxy = GetProxyForChannel(channelId);
       
   239 
       
   240             // Dispatch the message for found proxy to be handled
       
   241             if (proxy != NULL)
       
   242                 {
       
   243                 proxy->DispatchMessage(aMessage, channelId); // Transfer ownership of message
       
   244                 }
       
   245             else
       
   246                 {
       
   247                 ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DispatchMessage - ERROR: Proxy not found" )) );
       
   248                 // Complete with error
       
   249                 aMessage.Complete(KErrNotFound);
       
   250                 }
       
   251             break;
       
   252             }
       
   253 
       
   254         // Cannot identify the message
       
   255         default:
       
   256             {
       
   257             ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DispatchMessage - ERROR: unknown command" )) );
       
   258             aMessage.Complete(KErrArgument);
       
   259             break;
       
   260             }
       
   261         }
       
   262 
       
   263     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DispatchMessage - return" )) );
       
   264     }
       
   265 
       
   266 
       
   267 // ---------------------------------------------------------------------------
       
   268 // Generate new unique id.
       
   269 // ---------------------------------------------------------------------------
       
   270 //
       
   271 TInt CSensrvProxyManager::GenerateUniqueId()
       
   272     {
       
   273     iProxyManagerMutex.Wait();
       
   274 
       
   275     iIdCounter++;
       
   276 
       
   277     // Realistically, there will never be so many ids generated that the counter will roll over, but
       
   278     // check just in case. No checking for duplicate ids, as chance of that happening is truly
       
   279     // astronomical.
       
   280     if (iIdCounter == KMaxTInt)
       
   281         {
       
   282         iIdCounter = 1;
       
   283         }
       
   284 
       
   285     iProxyManagerMutex.Signal();
       
   286 
       
   287     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::GenerateUniqueId - generated new id: 0x%x" ), iIdCounter ) );
       
   288 
       
   289     return iIdCounter;
       
   290     }
       
   291 
       
   292 // ---------------------------------------------------------------------------
       
   293 // Checks waitqueue and if there are queued transactions,
       
   294 // checks if all proxies have constructed successfully.
       
   295 // If so, starts executing queued transactions.
       
   296 // ---------------------------------------------------------------------------
       
   297 //
       
   298 void CSensrvProxyManager::NotifyProxyInitialized()
       
   299     {
       
   300     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::NotifyProxyInitialized()") ) );
       
   301 
       
   302     TInt count = iProxyList.Count();
       
   303     iAllProxiesInitialized = ETrue;
       
   304 
       
   305     for(TInt i=0; i<count; i++)
       
   306         {
       
   307         if (!iProxyList[i]->IsInitialized())
       
   308             {
       
   309             iAllProxiesInitialized = EFalse;
       
   310             break;
       
   311             }
       
   312         }
       
   313 
       
   314     if (iAllProxiesInitialized)
       
   315         {
       
   316         HandleTransactionsQueryChannels();
       
   317         HandleTransactionsOpenChannel();
       
   318         }
       
   319     else
       
   320         {
       
   321         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::NotifyProxyInitialized - All proxies not yet initialized") ) );
       
   322         }
       
   323 
       
   324     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::NotifyProxyInitialized - return" )) );
       
   325     }
       
   326 
       
   327 // ---------------------------------------------------------------------------
       
   328 // Duplicates source handle to destination handle.
       
   329 // Source handle must be held by Server Main Thread
       
   330 // ---------------------------------------------------------------------------
       
   331 //
       
   332 TInt CSensrvProxyManager::DuplicateMutexHandle(const RMutex& aSrc, RMutex& aDst) const
       
   333     {
       
   334     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DuplicateMutexHandle(aSrc.Handle(): 0x%x, aDst.Handle(): 0x%x)"),aSrc.Handle(), aDst.Handle() ) );
       
   335 
       
   336     aDst.SetHandle(aSrc.Handle());
       
   337     TInt err = aDst.Duplicate(iServerThread);
       
   338 
       
   339     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::DuplicateMutexHandle - return %d" ), err) );
       
   340 
       
   341     return err;
       
   342     }
       
   343 
       
   344 // ---------------------------------------------------------------------------
       
   345 // shuts down server gracefully
       
   346 // ---------------------------------------------------------------------------
       
   347 //
       
   348 void CSensrvProxyManager::ShutdownServer(const RMessage2& aMessage)
       
   349     {
       
   350     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer(<RMessage2>)") ) );
       
   351 
       
   352     if (iShutdownMessage.Handle())
       
   353         {
       
   354         // Already shutting down, complete
       
   355         aMessage.Complete(KErrNone);
       
   356         }
       
   357     else
       
   358         {
       
   359         iShutdownMessage = aMessage;
       
   360         ShutdownServer();
       
   361         }
       
   362 
       
   363     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer - return" )) );
       
   364     }
       
   365 
       
   366 // ---------------------------------------------------------------------------
       
   367 // shuts down server gracefully
       
   368 // ---------------------------------------------------------------------------
       
   369 //
       
   370 void CSensrvProxyManager::ShutdownServer()
       
   371     {
       
   372     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer()") ) );
       
   373 
       
   374     if (!iShutdown)
       
   375         {
       
   376         iShutdown = ETrue;
       
   377         iShuttingDownCount = 0;
       
   378 
       
   379         // Cleanup proxies and solve amount of proxies to shutdown
       
   380         TInt proxyCount = iProxyList.Count();
       
   381         for (TInt i = 0; i < proxyCount; i++)
       
   382             {
       
   383             // Set deletion flag to disable usage attempts if shutdown was requested by client.
       
   384             // Othwerwise usage attempt is allowed to cancel shutdown.
       
   385             if (iShutdownMessage.Handle())
       
   386                 {
       
   387                 iProxyList[i]->SetDeletionFlag();
       
   388                 }
       
   389 
       
   390             CSensrvPluginProxy::TPluginState pluginState = iProxyList[i]->PluginState();
       
   391             if (pluginState == CSensrvPluginProxy::EPluginStateLoaded ||
       
   392                 pluginState == CSensrvPluginProxy::EPluginStateThreadInitializing ||
       
   393                 pluginState == CSensrvPluginProxy::EPluginStateThreadInitialized)
       
   394                 {
       
   395                 iProxyList[i]->CleanupPlugin();
       
   396                 iShuttingDownCount++;
       
   397                 }
       
   398             else if (pluginState == CSensrvPluginProxy::EPluginStateUnloading)
       
   399                 {
       
   400                 // Plugin already unloading
       
   401                 iShuttingDownCount++;
       
   402                 }
       
   403             }
       
   404 
       
   405         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer - proxies to shutdown %d" ),
       
   406             iShuttingDownCount ) );
       
   407 
       
   408         // Shutdown right away, if no proxies to unload
       
   409         if (!iShuttingDownCount)
       
   410             {
       
   411             SsyThreadTerminated();
       
   412             }
       
   413         }
       
   414     else
       
   415         {
       
   416         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer - Already shutting down" )) );
       
   417         }
       
   418 
       
   419     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ShutdownServer - return" )) );
       
   420     }
       
   421 
       
   422 // ---------------------------------------------------------------------------
       
   423 // Handles proxy thread termination
       
   424 // ---------------------------------------------------------------------------
       
   425 //
       
   426 void CSensrvProxyManager::SsyThreadTerminated()
       
   427     {
       
   428     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SsyThreadTerminated() shutdown status %d"), iShutdown ) );
       
   429 
       
   430     if (iShutdown)
       
   431     	{
       
   432         if (iShuttingDownCount > 0)
       
   433             {
       
   434             --iShuttingDownCount;
       
   435             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SsyThreadTerminated - proxies left %d "), iShuttingDownCount ) );
       
   436             }
       
   437         else
       
   438             {
       
   439             iShuttingDownCount = 0;
       
   440             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SsyThreadTerminated - Proxies already shutdown") ) );
       
   441             }
       
   442 
       
   443         if (!iShuttingDownCount)
       
   444             {
       
   445             if (iShutdownMessage.Handle())
       
   446                 {
       
   447                 iShutdownMessage.Complete(KErrNone);
       
   448                 }
       
   449             if (CActiveScheduler::Current())
       
   450                 {
       
   451                 CActiveScheduler::Stop();
       
   452                 CActiveScheduler::Install(NULL);
       
   453                 }
       
   454             }
       
   455     	}
       
   456 
       
   457     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SsyThreadTerminated - return" )) );
       
   458     }
       
   459 
       
   460 // ---------------------------------------------------------------------------
       
   461 // Compares current implementation infos to new implementation infos
       
   462 // and determines if new proxies need to be loaded or old ones deleted.
       
   463 // ---------------------------------------------------------------------------
       
   464 //
       
   465 TBool CSensrvProxyManager::EcomChanged( RImplInfoPtrArray* aImplementationInfos )
       
   466     {
       
   467     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged(<array>)") ) );
       
   468 
       
   469     TBool changes(EFalse);
       
   470     TInt i(0);
       
   471     TInt j(0);
       
   472     TInt found(KErrNotFound);
       
   473     TInt err(KErrNone);
       
   474     TBool changeOk(ETrue);
       
   475 
       
   476     __ASSERT_ALWAYS(aImplementationInfos, User::Panic(KSensrvPanicCategory, ESensrvPanicNullImplInfos));
       
   477 
       
   478     // If no array previously registered this is first registration.
       
   479     if (!iSsyImplInfoArray)
       
   480         {
       
   481         // First registration should always have some plugins or it is considered an error, although
       
   482         // there might be devices that do not have any sensors as default. Since we only trace the
       
   483         // error, this is not a problem.
       
   484         if (!aImplementationInfos->Count())
       
   485             {
       
   486             ERROR_TRACE( ( _L("Sensor Server - CSensrvProxyManager::EcomChanged - Possible ERROR: No SSY plugins found. (This might be ok for some devices with no internal sensors)" ) ) );
       
   487             }
       
   488         }
       
   489     else
       
   490         {
       
   491         // If still loading initial plugins, do not allow new changes until initial loads have completed.
       
   492         if (!iAllProxiesInitialized)
       
   493             {
       
   494             changeOk = EFalse;
       
   495             }
       
   496         }
       
   497 
       
   498     if (changeOk)
       
   499         {
       
   500         // Compare current implementation infos to new ones to find new plugins
       
   501         for (i = 0; i < aImplementationInfos->Count(); i++)
       
   502             {
       
   503             found = KErrNotFound;
       
   504 
       
   505             // Skip comparisons on the first time when there is no array to compare
       
   506             if (iSsyImplInfoArray)
       
   507                 {
       
   508                 for (j = 0; found == KErrNotFound && j < iSsyImplInfoArray->Count(); j++)
       
   509                     {
       
   510                     if ((*iSsyImplInfoArray)[j]->ImplementationUid() == (*aImplementationInfos)[i]->ImplementationUid())
       
   511                         {
       
   512                         found = j;
       
   513                         }
       
   514                     }
       
   515                 }
       
   516 
       
   517             // Create and initialize new proxy
       
   518             if (found == KErrNotFound)
       
   519                 {
       
   520                 changes = ETrue;
       
   521                 CSensrvPluginProxy* proxy = AddProxy((*aImplementationInfos)[i]->ImplementationUid());
       
   522 
       
   523                 if (proxy)
       
   524                     {
       
   525                     CImplementationInformation* implInfo = (*aImplementationInfos)[i];
       
   526                     err = proxy->InitializeChannelData( *implInfo );
       
   527                     if ( err != KErrNone )
       
   528                         {
       
   529                         // If proxy initialization fails, it means that proxy will not provide any channels.
       
   530                         // Since SSY thread has not been resumed yet (resume is the last thing in InitializeL), proxy
       
   531                         // can be safely deleted without risk for memory leak.
       
   532                         ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged - ERROR: Proxy initialization failed, error %d" ),  err) );
       
   533                         TInt pos( iProxyList.Find( proxy ) );
       
   534                         delete proxy;
       
   535                         proxy = NULL;
       
   536                         if ( pos >= 0 && pos < iProxyList.Count() )
       
   537                             {
       
   538                             iProxyList.Remove(pos);
       
   539                             }
       
   540                         }
       
   541                     // Note: New channels are notified to interested clients after they are registered.
       
   542                     }
       
   543                 }
       
   544             }
       
   545 
       
   546         NotifyProxyInitialized();
       
   547 
       
   548         // Skip the following comparisons entirely on the first time
       
   549         if (iSsyImplInfoArray)
       
   550             {
       
   551             // Compare current implementation infos to new ones to find removed plugins
       
   552             for (i = 0; i < iSsyImplInfoArray->Count(); i++)
       
   553                 {
       
   554                 found = KErrNotFound;
       
   555 
       
   556                 for (j = 0; found == KErrNotFound  && j < aImplementationInfos->Count(); j++)
       
   557                     {
       
   558                     if ((*iSsyImplInfoArray)[i]->ImplementationUid() == (*aImplementationInfos)[j]->ImplementationUid())
       
   559                         {
       
   560                         found = j;
       
   561                         }
       
   562                     }
       
   563 
       
   564                 // Delete obsolete proxy
       
   565                 if (found == KErrNotFound)
       
   566                     {
       
   567                     changes = ETrue;
       
   568 
       
   569                     // Find proxy from proxy list
       
   570                     for (TInt z=0; found == KErrNotFound && z < iProxyList.Count(); z++)
       
   571                         {
       
   572                         if (iProxyList[z]->ImplementationUid() == (*iSsyImplInfoArray)[i]->ImplementationUid())
       
   573                             {
       
   574                             // Mark proxy for deletion.
       
   575                             iProxyList[z]->SetDeletionFlag();
       
   576 
       
   577                             // Notify channel removal
       
   578                             for (TInt x = 0; x < iProxyList[z]->ChannelInfoList().Count(); x++)
       
   579                                 {
       
   580                                 NotifyChannelChange((iProxyList[z]->ChannelInfoList())[x], ESensrvChannelChangeTypeRemoved);
       
   581                                 }
       
   582 
       
   583                             // Clear any channels provided by proxy, so that it will not
       
   584                             // show up in further finds.
       
   585                             iProxyList[z]->ChannelInfoList().Reset();
       
   586 
       
   587                             // If plugin is not unloaded, it cannot be deleted without cleaning it up properly.
       
   588                             // Actual delete is done in ProxyCleanerCallback() in this case
       
   589                             if (iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateLoaded
       
   590                                 || iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateThreadInitializing
       
   591                                 || iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateThreadInitialized
       
   592                                 || iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateUnloading)
       
   593                                 {
       
   594                                 // Cleanup plugin unless it is already unloading
       
   595                                 if (iProxyList[z]->PluginState() != CSensrvPluginProxy::EPluginStateUnloading)
       
   596                                     {
       
   597                                     iProxyList[z]->CleanupPlugin();
       
   598                                     }
       
   599 
       
   600                                 if (!iProxyCleaner)
       
   601                                     {
       
   602                                     iProxyCleaner = CPeriodic::New(CActive::EPriorityStandard);
       
   603 
       
   604                                     if (iProxyCleaner)
       
   605                                         {
       
   606                                         iProxyCleaner->Start(TTimeIntervalMicroSeconds32( KSensrvEcomRescanTimerPeriod ),
       
   607                                                              TTimeIntervalMicroSeconds32( KSensrvEcomRescanTimerPeriod ),
       
   608                                                              TCallBack( ProxyCleanerCallback, this ));
       
   609                                         }
       
   610                                     else
       
   611                                         {
       
   612                                         // Since cleaner cannot be constructed, proxy is left alive. Since it is marked
       
   613                                         // for deletion, it will be quite unusable, however.
       
   614                                         ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged - Unable to create proxy cleaner" ) ) );
       
   615                                         }
       
   616                                     }
       
   617                                 }
       
   618                             else
       
   619                                 {
       
   620                                 // Delete plugin outright, plugin is unloaded or uninitialized
       
   621                                 delete iProxyList[z];
       
   622                                 iProxyList.Remove(z);
       
   623                                 }
       
   624 
       
   625                             found = z;
       
   626                             }
       
   627                         }
       
   628                     }
       
   629                 }
       
   630             }
       
   631 
       
   632         // Update iSsyImplInfoArray
       
   633         if (!iSsyImplInfoArray)
       
   634             {
       
   635             // First time always assign the array
       
   636             iSsyImplInfoArray = aImplementationInfos;
       
   637             }
       
   638         else if (changes)
       
   639             {
       
   640             iSsyImplInfoArray->ResetAndDestroy();
       
   641             delete iSsyImplInfoArray;
       
   642             iSsyImplInfoArray = aImplementationInfos;
       
   643             }
       
   644         else
       
   645             {
       
   646             // No changes, just destroy new infos
       
   647             aImplementationInfos->ResetAndDestroy();
       
   648             delete aImplementationInfos;
       
   649             }
       
   650 
       
   651         // If no proxies were successfully initialized,
       
   652         // set initialized flag so that finds will not wait forever.
       
   653         if (!iProxyList.Count())
       
   654             {
       
   655             iAllProxiesInitialized = ETrue;
       
   656             }
       
   657         }
       
   658 
       
   659     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged - return %d" ), changeOk) );
       
   660 
       
   661     return changeOk;
       
   662     }
       
   663 
       
   664 // ---------------------------------------------------------------------------
       
   665 // Orders server to notify all interested client sessions. Notifications
       
   666 // are not sent until all proxies have finished initializing to
       
   667 // avoid notifications about initial plugin loads.
       
   668 // ---------------------------------------------------------------------------
       
   669 //
       
   670 void CSensrvProxyManager::NotifyChannelChange(const TSensrvResourceChannelInfo& aChangedChannel,
       
   671                                               TSensrvChannelChangeType aChangeType )
       
   672     {
       
   673     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::NotifyChannelChange(aChangedChannel.iChannelId: %d, aChangeType: %d)"), aChangedChannel.iChannelId, aChangeType ) );
       
   674 
       
   675     if (iAllProxiesInitialized)
       
   676         {
       
   677         iServer.NotifyChannelChange(aChangedChannel, aChangeType);
       
   678         }
       
   679 
       
   680     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::NotifyChannelChange - return" )) );
       
   681     }
       
   682 
       
   683 // ---------------------------------------------------------------------------
       
   684 // Cleans up everything related to terminated session.
       
   685 // ---------------------------------------------------------------------------
       
   686 //
       
   687 void CSensrvProxyManager::SessionTerminated( CSensrvSession* aSession )
       
   688     {
       
   689     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SessionTerminated(aSession: 0x%x)"),aSession ) );
       
   690 
       
   691     // Cleanup any waiting transactions for this session
       
   692     iWaitQueueQueryChannels->Remove(aSession);
       
   693     iWaitQueueOpenChannel->Remove(aSession);
       
   694 
       
   695     if (iSessionCounter > 0)
       
   696         {
       
   697         iSessionCounter--;
       
   698         }
       
   699     else
       
   700         {
       
   701         iSessionCounter = 0;
       
   702         ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SessionTerminated - Already no sessions") ) );
       
   703         }
       
   704 
       
   705     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SessionTerminated - Amount of sessions %d"), iSessionCounter ) );
       
   706 
       
   707     if (!iSessionCounter)
       
   708         {
       
   709         // Shutdown server after timer since no more clients
       
   710         iServerShutdown->Start();
       
   711         }
       
   712 
       
   713     // Call session cleanup on each proxy
       
   714     TInt proxyCount = iProxyList.Count();
       
   715     for(TInt i = 0; i < proxyCount; i++)
       
   716         {
       
   717         iProxyList[i]->SessionTerminated(aSession);
       
   718         }
       
   719 
       
   720     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::SessionTerminated - return" )) );
       
   721     }
       
   722 
       
   723 
       
   724 // ---------------------------------------------------------------------------
       
   725 // Executes queued transactions.
       
   726 // ---------------------------------------------------------------------------
       
   727 //
       
   728 void CSensrvProxyManager::HandleTransactionsQueryChannels()
       
   729     {
       
   730     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactionsQueryChannels()") ) );
       
   731 
       
   732     if (iWaitQueueQueryChannels)
       
   733         {
       
   734         while (!iWaitQueueQueryChannels->IsEmpty())
       
   735             {
       
   736             TInt err(KErrNone);
       
   737 
       
   738             CSensrvTransaction* transaction = iWaitQueueQueryChannels->First();
       
   739 
       
   740             if (transaction->State() == CSensrvTransaction::ETransStateQueued)
       
   741                 {
       
   742                 // Read required channel information from message
       
   743                 TSensrvResourceChannelInfoPckgBuf pckg;
       
   744 
       
   745                 __ASSERT_ALWAYS(transaction->Message(), User::Panic(KSensrvPanicCategory, ESensrvPanicNullMessage));
       
   746 
       
   747                 err = transaction->Message()->Read( KSensrvQueryChannelsQueryParametersSlot, pckg );
       
   748                 if(err == KErrNone && transaction->Message()->Handle())
       
   749                     {
       
   750                     TSensrvResourceChannelInfo queryInfo = pckg();
       
   751                     const RMessage2& queryMessage(transaction->Message()->GetMessage());
       
   752 
       
   753                     if (LoadDynamicChannelSsysIfNeeded(queryInfo, queryMessage, EFalse))
       
   754                         {
       
   755                         // Continue wait queue processing after the required SSYs are loaded
       
   756                         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactionsQueryChannels() - Waiting for SSYs to be loaded") ) );
       
   757                         break;
       
   758                         }
       
   759 
       
   760                     transaction->SetState(CSensrvTransaction::ETransStateExecuting);
       
   761 
       
   762                     // Go through all proxies and add matches to return array.
       
   763                     RSensrvChannelInfoList matchingInfos;
       
   764                     TInt proxyCount = iProxyList.Count();
       
   765                     for (TInt i = 0; i < proxyCount; ++i)
       
   766                         {
       
   767                         CSensrvPluginProxy* proxy = iProxyList[i];
       
   768                         TInt channelCount = proxy->ChannelInfoList().Count();
       
   769                         for (TInt j = 0; j < channelCount; ++j)
       
   770                             {
       
   771                             const TSensrvResourceChannelInfo& info(proxy->ChannelInfoList()[j]);
       
   772                             if (info.IsMatch(queryInfo, queryMessage))
       
   773                                 {
       
   774                                 err = matchingInfos.Append(info);
       
   775                                 if (err != KErrNone)
       
   776                                     {
       
   777                                     ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactionsQueryChannels - ERROR: Append of matching info failed, error %d" ), err) );
       
   778                                     break;
       
   779                                     }
       
   780                                 }
       
   781                             }
       
   782                         }
       
   783 #ifdef COMPONENT_TRACE_DEBUG
       
   784                     COMPONENT_TRACE( ( _L( "### Found channels:" )) );
       
   785                     TraceChannelInfoList(matchingInfos);
       
   786 #endif
       
   787                     if (err == KErrNone)
       
   788                         {
       
   789                         // Write found infos to message
       
   790                         err = transaction->SetMessageData(&matchingInfos);
       
   791                         }
       
   792 
       
   793                     matchingInfos.Reset();
       
   794                     }
       
   795                 else
       
   796                     {
       
   797                     transaction->SetState(CSensrvTransaction::ETransStateExecuting);
       
   798                     }
       
   799 
       
   800                 if (err != KErrNone)
       
   801                     {
       
   802                     transaction->SetErrorCode(err);
       
   803                     }
       
   804 
       
   805                 // Complete transaction
       
   806                 iWaitQueueQueryChannels->Remove(transaction, CSensrvTransactionQueue::ERemovalTypeComplete);
       
   807                 transaction = NULL;
       
   808                 }
       
   809             else
       
   810                 {
       
   811                 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactionsQueryChannels - Transaction already executing, do nothing." )) );
       
   812                 }
       
   813             } // end while
       
   814         }
       
   815 
       
   816     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactionsQueryChannels - return" )) );
       
   817     }
       
   818 
       
   819 // ---------------------------------------------------------------------------
       
   820 // Executes queued transactions.
       
   821 // ---------------------------------------------------------------------------
       
   822 //
       
   823 void CSensrvProxyManager::HandleTransactionsOpenChannel()
       
   824     {
       
   825     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactions()") ) );
       
   826 
       
   827     if (iWaitQueueOpenChannel)
       
   828         {
       
   829         while (!iWaitQueueOpenChannel->IsEmpty())
       
   830             {
       
   831             TInt err(KErrNone);
       
   832 
       
   833             CSensrvTransaction* transaction = iWaitQueueOpenChannel->First();
       
   834 
       
   835             if (transaction->State() == CSensrvTransaction::ETransStateQueued)
       
   836                 {
       
   837                 transaction->SetState(CSensrvTransaction::ETransStateExecuting);
       
   838 
       
   839                 __ASSERT_ALWAYS(transaction->Message(), User::Panic(KSensrvPanicCategory, ESensrvPanicNullMessage));
       
   840 
       
   841                 // Get channel ID from message
       
   842                 // No need to check error value, we already made sure the message function is correct
       
   843                 TSensrvChannelId channelId(0);
       
   844                 err = transaction->Message()->GetChannelId(channelId);
       
   845 
       
   846                 if(err == KErrNone)
       
   847                     {
       
   848 
       
   849                     // Determine which proxy handles this channel
       
   850                     CSensrvPluginProxy* proxy = GetProxyForChannel(channelId);
       
   851 
       
   852                     if( proxy != NULL &&
       
   853                                 ( proxy->PluginState() == CSensrvPluginProxy::EPluginStateUnloaded ||
       
   854                                   proxy->PluginState() == CSensrvPluginProxy::EPluginStateUninitialized ) )
       
   855                         {
       
   856                         TRAPD(err, proxy->InitializePluginL());
       
   857                         if ( err != KErrNone )
       
   858                             {
       
   859                             // If proxy initialization fails, it means that proxy will not provide any channels.
       
   860                             // Since SSY thread has not been resumed yet (resume is the last thing in InitializeL), proxy
       
   861                             // can be safely deleted without risk for memory leak.
       
   862                             ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::EcomChanged - ERROR: Proxy initialization failed, error %d" ),  err) );
       
   863                             TInt pos( iProxyList.Find( proxy ) );
       
   864                             delete proxy;
       
   865                             proxy = NULL;
       
   866                             if ( pos >= 0 && pos < iProxyList.Count() )
       
   867                                 {
       
   868                                 iProxyList.Remove(pos);
       
   869                                 }
       
   870                             }
       
   871                         }
       
   872 
       
   873                     // Dispatch the message for found proxy to be handled
       
   874                     if (proxy != NULL)
       
   875                         {
       
   876                         proxy->DispatchMessage(*transaction->Message(), channelId); // Transfer ownership of message
       
   877                         }
       
   878                     }
       
   879                 else
       
   880                     {
       
   881                     transaction->SetErrorCode(err);
       
   882                     }
       
   883                 // Complete transaction
       
   884                 iWaitQueueOpenChannel->Remove(transaction, CSensrvTransactionQueue::ERemovalTypeComplete);
       
   885                 transaction = NULL;
       
   886                 }
       
   887             else
       
   888                 {
       
   889                 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactions - Transaction already executing, do nothing." )) );
       
   890                 }
       
   891             } // end while
       
   892         }
       
   893 
       
   894     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::HandleTransactions - return" )) );
       
   895     }
       
   896 
       
   897 // ---------------------------------------------------------------------------
       
   898 // Checks all channels provided by proxies and returns information matching
       
   899 // the query parameters.
       
   900 // ---------------------------------------------------------------------------
       
   901 //
       
   902 void CSensrvProxyManager::QueryChannels(CSensrvMessage& aMessage)
       
   903     {
       
   904     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels(aMessage: 0x%x, <aQueryParams>)" ), &aMessage ) );
       
   905 
       
   906     // Create transaction
       
   907     CSensrvTransaction* queryTransaction = NULL;
       
   908     TRAPD(err, queryTransaction = CSensrvTransaction::NewL(
       
   909         &aMessage,
       
   910         NULL,
       
   911         NULL,
       
   912         CSensrvTransaction::ETransTypeClientQueryChannels));
       
   913 
       
   914     if (err == KErrNone)
       
   915         {
       
   916         // queue transaction
       
   917         queryTransaction->SetState(CSensrvTransaction::ETransStateQueued);
       
   918 
       
   919         err = iWaitQueueQueryChannels->Add(queryTransaction);
       
   920 
       
   921         if (err == KErrNone)
       
   922             {
       
   923             // Execute transaction if all proxies initialized
       
   924             if (iAllProxiesInitialized)
       
   925                 {
       
   926                 HandleTransactionsQueryChannels();
       
   927                 }
       
   928             else
       
   929                 {
       
   930                 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - All proxies not yet initialized") ) );
       
   931                 }
       
   932             }
       
   933         else
       
   934             {
       
   935             ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - ERROR: Transaction adding to queue failed" )) );
       
   936             }
       
   937         }
       
   938     else
       
   939         {
       
   940         ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - ERROR: Transaction creation failed" )) );
       
   941         }
       
   942 
       
   943     // Handle error
       
   944     if (err != KErrNone)
       
   945         {
       
   946         if(queryTransaction)
       
   947             {
       
   948             queryTransaction->SetErrorCode(err);
       
   949             queryTransaction->Complete();
       
   950             delete queryTransaction;
       
   951             queryTransaction = NULL;
       
   952             }
       
   953         else
       
   954             {
       
   955             // Do nothing, message gets deleted and completed with KErrGeneral on transaction desctructor.
       
   956             }
       
   957         }
       
   958 
       
   959 
       
   960     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - return" )) );
       
   961     }
       
   962 
       
   963 // ---------------------------------------------------------------------------
       
   964 // Checks all channels provided by proxies and returns information matching
       
   965 // the query parameters.
       
   966 // ---------------------------------------------------------------------------
       
   967 //
       
   968 void CSensrvProxyManager::OpenChannel(CSensrvMessage& aMessage)
       
   969     {
       
   970     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels(aMessage: 0x%x, <aQueryParams>)" ), &aMessage ) );
       
   971 
       
   972     // Create transaction
       
   973     CSensrvTransaction* queryTransaction = NULL;
       
   974     TRAPD(err, queryTransaction = CSensrvTransaction::NewL(
       
   975         &aMessage,
       
   976         NULL,
       
   977         NULL,
       
   978         CSensrvTransaction::ETransTypeOpenChannel));
       
   979 
       
   980     if (err == KErrNone)
       
   981         {
       
   982         // queue transaction
       
   983         queryTransaction->SetState(CSensrvTransaction::ETransStateQueued);
       
   984 
       
   985         err = iWaitQueueOpenChannel->Add(queryTransaction);
       
   986 
       
   987         if (err == KErrNone)
       
   988             {
       
   989             // Execute transaction if all proxies initialized
       
   990             if (iAllProxiesInitialized)
       
   991                 {
       
   992                 HandleTransactionsOpenChannel();
       
   993                 }
       
   994             else
       
   995                 {
       
   996                 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - All proxies not yet initialized") ) );
       
   997                 }
       
   998             }
       
   999         else
       
  1000             {
       
  1001             ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - ERROR: Transaction adding to queue failed" )) );
       
  1002             }
       
  1003         }
       
  1004     else
       
  1005         {
       
  1006         ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - ERROR: Transaction creation failed" )) );
       
  1007         }
       
  1008 
       
  1009     // Handle error
       
  1010     if (err != KErrNone)
       
  1011         {
       
  1012         if(queryTransaction)
       
  1013             {
       
  1014             queryTransaction->SetErrorCode(err);
       
  1015             queryTransaction->Complete();
       
  1016             delete queryTransaction;
       
  1017             queryTransaction = NULL;
       
  1018             }
       
  1019         else
       
  1020             {
       
  1021             // Do nothing, message gets deleted and completed with KErrGeneral on transaction desctructor.
       
  1022             }
       
  1023         }
       
  1024 
       
  1025 
       
  1026     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::QueryChannels - return" )) );
       
  1027     }
       
  1028 
       
  1029 // ---------------------------------------------------------------------------
       
  1030 // Gets the proxy that handles the specified channel.
       
  1031 // NULL is returned if channel is not found.
       
  1032 // ---------------------------------------------------------------------------
       
  1033 //
       
  1034 CSensrvPluginProxy* CSensrvProxyManager::GetProxyForChannel(TSensrvChannelId aChannelId) const
       
  1035     {
       
  1036     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::GetProxyForChannel(aChannelId: %d)" ), aChannelId ) );
       
  1037 
       
  1038     CSensrvPluginProxy* returnProxy = NULL;
       
  1039 
       
  1040     TInt proxyCount = iProxyList.Count();
       
  1041     for(TInt i = 0; !returnProxy && i < proxyCount; i++)
       
  1042         {
       
  1043         if (iProxyList[i]->IsChannelSupported(aChannelId))
       
  1044             {
       
  1045             returnProxy = iProxyList[i];
       
  1046             }
       
  1047         }
       
  1048 
       
  1049     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::GetProxyForChannel - return 0x%x" ), returnProxy) );
       
  1050 
       
  1051     return returnProxy;
       
  1052     }
       
  1053 
       
  1054 // ---------------------------------------------------------------------------
       
  1055 // Fetches configurable settings from cenrep
       
  1056 // ---------------------------------------------------------------------------
       
  1057 //
       
  1058 void CSensrvProxyManager::GetSettings()
       
  1059     {
       
  1060     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvChannel::GetSettings()" ) ) );
       
  1061 
       
  1062     TInt err(KErrNone);
       
  1063 
       
  1064     // Open settings repository and get necessary values
       
  1065     CRepository* repository = NULL;
       
  1066     TRAP( err, repository = CRepository::NewL(KCRUidSensorServerSettings) );
       
  1067 
       
  1068     if ( err == KErrNone )
       
  1069         {
       
  1070         TInt value(0);
       
  1071         err = repository->Get(KSensrvTransactionTimeoutKey, value);
       
  1072         if ( err == KErrNone )
       
  1073             {
       
  1074             if ( value > 0 )
       
  1075                 {
       
  1076                 iTransactionTimeout = value*KSecondsToMicros;
       
  1077                 }
       
  1078             }
       
  1079         else
       
  1080             {
       
  1081             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvTransactionTimeoutKey value getting failed: %d, using default value." ), err) );
       
  1082             }
       
  1083 
       
  1084         err = repository->Get(KSensrvSsyThreadStackSizeKey, value);
       
  1085         if ( err == KErrNone )
       
  1086             {
       
  1087             if ( value > 0 )
       
  1088                 {
       
  1089                 iSsyStackSize = value;
       
  1090                 }
       
  1091             }
       
  1092         else
       
  1093             {
       
  1094             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvSsyThreadStackSizeKey value getting failed: %d, using default value." ), err) );
       
  1095             }
       
  1096 
       
  1097         err = repository->Get(KSensrvSsyThreadHeapMaxSizeKey, value);
       
  1098         if ( err == KErrNone )
       
  1099             {
       
  1100 #ifdef __WINS__ 
       
  1101             value *= KSensrvSsyMaxHeapWinsMultiplier;
       
  1102 #endif // __WINS__
       
  1103             if ( value < KSensrvSsyHeapInitialSize )
       
  1104                 {
       
  1105                 iSsyHeapMaxSize = KSensrvSsyHeapInitialSize;
       
  1106                 }
       
  1107             else if (value > 0)
       
  1108                 {
       
  1109                 iSsyHeapMaxSize = value;
       
  1110                 }
       
  1111             else
       
  1112                 {
       
  1113                 // Do nothing, default is used
       
  1114                 }
       
  1115             }
       
  1116         else
       
  1117             {
       
  1118             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvSsyThreadHeapMaxSizeKey value getting failed: %d, using default value." ), err) );
       
  1119             }
       
  1120 
       
  1121         err = repository->Get(KSensrvThreadTerminationPeriodKey, value);
       
  1122         if ( err == KErrNone )
       
  1123             {
       
  1124             if ( value > 0 )
       
  1125                 {
       
  1126                 iThreadTerminationGracePeriod = value*KSecondsToMicros;
       
  1127                 }
       
  1128             }
       
  1129         else
       
  1130             {
       
  1131             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvThreadTerminationPeriodKey value getting failed: %d, using default value." ), err) );
       
  1132             }
       
  1133 
       
  1134         err = repository->Get(KSensrvSsyInactivityPeriodKey, value);
       
  1135         if ( err == KErrNone )
       
  1136             {
       
  1137             if ( value > 0 )
       
  1138                 {
       
  1139                 iSsyInactivityPeriod = value*KSecondsToMicros;
       
  1140                 }
       
  1141             }
       
  1142         else
       
  1143             {
       
  1144             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvSsyInactivityPeriodKey value getting failed: %d, using default value." ), err) );
       
  1145             }
       
  1146 
       
  1147         err = repository->Get(KSensrvBufferSizeMultiplierKey, value);
       
  1148         if ( err == KErrNone )
       
  1149             {
       
  1150             if ( value > 0 )
       
  1151                 {
       
  1152                 iBufferSizeMultiplier = value;
       
  1153                 }
       
  1154             }
       
  1155         else
       
  1156             {
       
  1157             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvBufferSizeMultiplierKey value getting failed: %d, using default value." ), err) );
       
  1158             }
       
  1159         err = repository->Get(KSensrvTerminationPeriodKey, value);
       
  1160         if ( err == KErrNone )
       
  1161             {
       
  1162             if ( value >= 0 )
       
  1163                 {
       
  1164                 iTerminationPeriod = value*KSecondsToMicros;
       
  1165                 }
       
  1166             }
       
  1167         else
       
  1168             {
       
  1169             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - KSensrvTerminationPeriodKey value getting failed: %d, using default value." ), err) );
       
  1170             }
       
  1171         }
       
  1172     else
       
  1173         {
       
  1174         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - Settings repository opening failed: %d" ), err) );
       
  1175         }
       
  1176 
       
  1177     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iTransactionTimeout: %d" ), iTransactionTimeout.Int()) );
       
  1178     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iSsyStackSize: %d" ), iSsyStackSize) );
       
  1179     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iSsyHeapMaxSize: %d" ), iSsyHeapMaxSize) );
       
  1180     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iThreadTerminationGracePeriod: %d" ), iThreadTerminationGracePeriod.Int()) );
       
  1181     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iSsyInactivityPeriod: %d" ), iSsyInactivityPeriod.Int()) );
       
  1182     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvServer::GetSettings - iBufferSizeMultiplier: %d" ), iBufferSizeMultiplier) );
       
  1183 
       
  1184     // Cleanup repository
       
  1185     delete repository;
       
  1186     repository = NULL;
       
  1187 
       
  1188     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvChannel::GetSettings - return" ) ) );
       
  1189     }
       
  1190 
       
  1191 // ---------------------------------------------------------------------------
       
  1192 // Create new proxy and add it to proxy list
       
  1193 // ---------------------------------------------------------------------------
       
  1194 //
       
  1195 CSensrvPluginProxy* CSensrvProxyManager::AddProxy(const TUid& aProxyUid)
       
  1196     {
       
  1197     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddProxy(0x%x)" ), aProxyUid.iUid ) );
       
  1198 
       
  1199     // Create proxy
       
  1200     TInt err(KErrNone);
       
  1201     CSensrvPluginProxy* proxy =  NULL;
       
  1202     TRAP(err, proxy = CSensrvPluginProxy::NewL(*this,aProxyUid));
       
  1203 
       
  1204     if ( err != KErrNone )
       
  1205         {
       
  1206         // Error loading a plugin is not critical, it just means
       
  1207         // that channels provided by plugin are unavailable.
       
  1208         ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddProxy - ERROR: creating proxy failed, implementationUid: 0x%x, error: %d" ), aProxyUid.iUid , err ) );
       
  1209         }
       
  1210     else
       
  1211         {
       
  1212         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddProxy - Proxy for implementation 0x%x created successfully." ), aProxyUid.iUid ) );
       
  1213 
       
  1214         // Add proxy to list
       
  1215         err = iProxyList.Append(proxy);
       
  1216         if ( err != KErrNone )
       
  1217             {
       
  1218             ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddProxy - ERROR: Saving plugin info failed, implementationUid: 0x%x, error %d" ), aProxyUid.iUid , err) );
       
  1219             delete proxy;
       
  1220             proxy = NULL;
       
  1221             }
       
  1222         }
       
  1223 
       
  1224     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddProxy - return 0x%x" ), proxy ) );
       
  1225 
       
  1226     return proxy;
       
  1227     }
       
  1228 
       
  1229 // ---------------------------------------------------------------------------
       
  1230 // CSensrvProxyManager::ProxyCleanerCallback
       
  1231 // ---------------------------------------------------------------------------
       
  1232 //
       
  1233 TInt CSensrvProxyManager::ProxyCleanerCallback( TAny* aObject )
       
  1234     {
       
  1235     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ProxyCleanerCallback(this)" ) ) );
       
  1236 
       
  1237     __ASSERT_ALWAYS(aObject, User::Panic(KSensrvPanicCategory, ESensrvPanicNullCallback));
       
  1238 
       
  1239     CSensrvProxyManager* manager = reinterpret_cast<CSensrvProxyManager*>( aObject );
       
  1240     TBool noMore(ETrue);
       
  1241 
       
  1242     for (TInt z = manager->iProxyList.Count() - 1; z >= 0; z--)
       
  1243         {
       
  1244         if (manager->iProxyList[z]->IsMarkedForDeletion())
       
  1245             {
       
  1246             if (manager->iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateLoaded
       
  1247                 || manager->iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateThreadInitializing
       
  1248                 || manager->iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateThreadInitialized
       
  1249                 || manager->iProxyList[z]->PluginState() == CSensrvPluginProxy::EPluginStateUnloading)
       
  1250                 {
       
  1251                 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ProxyCleanerCallback - Proxy still not unloaded, try deletion again later" ) ) );
       
  1252                 noMore = EFalse;
       
  1253                 }
       
  1254             else
       
  1255                 {
       
  1256                 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ProxyCleanerCallback - Proxy unloaded, deleting..." ) ) );
       
  1257                 delete manager->iProxyList[z];
       
  1258                 manager->iProxyList.Remove(z);
       
  1259                 }
       
  1260             }
       
  1261         }
       
  1262 
       
  1263     // Delete iProxyCleaner if no more
       
  1264     if (noMore)
       
  1265         {
       
  1266         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ProxyCleanerCallback - No more proxies to unload, deleting cleaner..." ) ) );
       
  1267         delete manager->iProxyCleaner;
       
  1268         manager->iProxyCleaner = NULL;
       
  1269         }
       
  1270 
       
  1271     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::ProxyCleanerCallback - return " ) ) );
       
  1272 
       
  1273     return KErrNone;
       
  1274     }
       
  1275 
       
  1276 #ifdef COMPONENT_TRACE_DEBUG
       
  1277 // ---------------------------------------------------------------------------
       
  1278 // Traces channel info list contents
       
  1279 // ---------------------------------------------------------------------------
       
  1280 //
       
  1281 void CSensrvProxyManager::TraceChannelInfoList(const RSensrvResourceChannelInfoList& aInfoList)
       
  1282     {
       
  1283     // Debug found channels
       
  1284     if (aInfoList.Count())
       
  1285         {
       
  1286         for(TInt z = 0; z < aInfoList.Count(); z++)
       
  1287             {
       
  1288             // Convert location and vendorID from 8bit to 16 bit for proper printing
       
  1289             TInt len = aInfoList[z].iVendorId.Length();
       
  1290             HBufC16* vidBuf16 = HBufC16::New(len);
       
  1291             if( vidBuf16 )
       
  1292                 {
       
  1293                 vidBuf16->Des().Copy(aInfoList[z].iVendorId);
       
  1294                 }
       
  1295 
       
  1296             len = aInfoList[z].iLocation.Length();
       
  1297             HBufC16* locBuf16 = HBufC16::New(len);
       
  1298             if( locBuf16 )
       
  1299                 {
       
  1300                 locBuf16->Des().Copy(aInfoList[z].iLocation);
       
  1301                 }
       
  1302             COMPONENT_TRACE( ( _L( "### Info %d: iChannelId: %d, iContextType: 0x%x, iQuantity: 0x%x, iChannelType: 0x%x, iLocation: \"%S\", iVendorId: \"%S\", iDataItemSize: %d " ),
       
  1303                                z,
       
  1304                                aInfoList[z].iChannelId,
       
  1305                                aInfoList[z].iContextType,
       
  1306                                aInfoList[z].iQuantity,
       
  1307                                aInfoList[z].iChannelType,
       
  1308                                locBuf16 ? locBuf16 : &KSensrvNullString,
       
  1309                                vidBuf16 ? vidBuf16 : &KSensrvNullString,
       
  1310                                aInfoList[z].iDataItemSize) );
       
  1311             if( locBuf16 )
       
  1312                 delete locBuf16;
       
  1313             if( vidBuf16 )
       
  1314                 delete vidBuf16;
       
  1315             }
       
  1316         }
       
  1317     else
       
  1318         {
       
  1319         COMPONENT_TRACE( ( _L( "### List is empty." ) ));
       
  1320         }
       
  1321     }
       
  1322 
       
  1323 // ---------------------------------------------------------------------------
       
  1324 // Traces channel info list contents
       
  1325 // ---------------------------------------------------------------------------
       
  1326 //
       
  1327 void CSensrvProxyManager::TraceChannelInfoList(const RSensrvChannelInfoList& aInfoList)
       
  1328     {
       
  1329     // Debug found channels
       
  1330     if (aInfoList.Count())
       
  1331         {
       
  1332         for(TInt z = 0; z < aInfoList.Count(); z++)
       
  1333             {
       
  1334             // Convert location and vendorID from 8bit to 16 bit for proper printing
       
  1335             TInt len = aInfoList[z].iVendorId.Length();
       
  1336             HBufC16* vidBuf16 = HBufC16::New(len);
       
  1337             if( vidBuf16 )
       
  1338                 {
       
  1339                 vidBuf16->Des().Copy(aInfoList[z].iVendorId);
       
  1340                 }
       
  1341             
       
  1342             len = aInfoList[z].iLocation.Length();
       
  1343             HBufC16* locBuf16 = HBufC16::New(len);
       
  1344             if( locBuf16 )
       
  1345                 {
       
  1346                 locBuf16->Des().Copy(aInfoList[z].iLocation);
       
  1347                 }
       
  1348              
       
  1349             COMPONENT_TRACE( ( _L( "### Info %d: iChannelId: %d, iContextType: 0x%x, iQuantity: 0x%x, iChannelType: 0x%x, iLocation: \"%S\", iVendorId: \"%S\", iDataItemSize: %d " ),
       
  1350                                                z,
       
  1351                                                aInfoList[z].iChannelId,
       
  1352                                                aInfoList[z].iContextType,
       
  1353                                                aInfoList[z].iQuantity,
       
  1354                                                aInfoList[z].iChannelType,
       
  1355                                                locBuf16 ? locBuf16 : &KSensrvNullString,
       
  1356                                                vidBuf16 ? vidBuf16 : &KSensrvNullString,
       
  1357                                                aInfoList[z].iDataItemSize) );
       
  1358              if( locBuf16 )
       
  1359                  delete locBuf16;
       
  1360              if( vidBuf16 )
       
  1361                  delete vidBuf16;
       
  1362                                         
       
  1363             }
       
  1364         }
       
  1365     else
       
  1366         {
       
  1367         COMPONENT_TRACE( ( _L( "### List is empty." ) ));
       
  1368         }
       
  1369     }
       
  1370 #endif
       
  1371 
       
  1372 // ---------------------------------------------------------------------------
       
  1373 // Cleanup item implementation for plugin initialization
       
  1374 // ---------------------------------------------------------------------------
       
  1375 //
       
  1376 void CSensrvProxyManager::AddSession()
       
  1377     {
       
  1378     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddSession" ) ) );
       
  1379 
       
  1380     if ( iServerShutdown->IsActive( ) )
       
  1381     	{
       
  1382     	iServerShutdown->Cancel();
       
  1383     	}
       
  1384 	iSessionCounter++;
       
  1385 
       
  1386 	// Cancel shutdown if it was not requested by client
       
  1387 	if ( !iShutdownMessage.Handle() )
       
  1388 	    {
       
  1389 	    iShutdown = EFalse;
       
  1390 	    }
       
  1391 
       
  1392 	COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::AddSession sessions: %d - return" ), iSessionCounter ) );
       
  1393     }
       
  1394 
       
  1395 // ---------------------------------------------------------------------------
       
  1396 // Loads the dynamic channel SSYs that matches to given query if not loaded
       
  1397 // ---------------------------------------------------------------------------
       
  1398 //
       
  1399 TBool CSensrvProxyManager::LoadDynamicChannelSsysIfNeeded(const TSensrvResourceChannelInfo& aQueryInfo,
       
  1400                                                           const RMessage2& aQueryMessage,
       
  1401                                                           TBool aAddChannelChangeListener)
       
  1402     {
       
  1403     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::LoadDynamicChannelSsysIfNeeded" ) ) );
       
  1404     TBool ssyLoadPending = EFalse;
       
  1405     TInt proxyCount = iProxyList.Count();
       
  1406     for (TInt i = 0; i < proxyCount; ++i)
       
  1407         {
       
  1408         CSensrvPluginProxy* proxy = iProxyList[i];
       
  1409         TInt channelCount = proxy->DynamicChannelInfoList().Count();
       
  1410         for (TInt j = 0; j < channelCount; ++j)
       
  1411             {
       
  1412             if (proxy->DynamicChannelInfoList()[j].IsMatch(aQueryInfo, aQueryMessage))
       
  1413                 {
       
  1414                 CSensrvPluginProxy::TPluginState pluginState = proxy->PluginState();
       
  1415                 if (pluginState == CSensrvPluginProxy::EPluginStateUninitialized ||
       
  1416                     pluginState == CSensrvPluginProxy::EPluginStateUnloaded ||
       
  1417                     pluginState == CSensrvPluginProxy::EPluginStateUnloading)
       
  1418                     {
       
  1419                     if (!proxy->PreviousSsyLoadFailed()) // If loading failed earlier, ignore new attempt to avoid query deadlocks
       
  1420                         {
       
  1421                         TRAPD(err, proxy->InitializePluginL());
       
  1422                         if (err == KErrNone)
       
  1423                             {
       
  1424                             ssyLoadPending = ETrue;
       
  1425                             }
       
  1426                         else
       
  1427                             {
       
  1428                             ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::LoadDynamicChannelSsysIfNeeded - ERROR: SSY 0x%x initialization failed, error %d" ),
       
  1429                                 proxy->ImplementationUid().iUid, err ) );
       
  1430                             }
       
  1431                         }
       
  1432                     else
       
  1433                         {
       
  1434                         ERROR_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::LoadDynamicChannelSsysIfNeeded - Ignoring SSY 0x%x initialization" ),
       
  1435                             proxy->ImplementationUid().iUid ) );
       
  1436                         }
       
  1437                     }
       
  1438                 else if (pluginState == CSensrvPluginProxy::EPluginStateThreadInitializing)
       
  1439                     {
       
  1440                     ssyLoadPending = ETrue;
       
  1441                     }
       
  1442                 if (aAddChannelChangeListener)
       
  1443                     {
       
  1444                     proxy->AddChannelChangeListener();
       
  1445                     }
       
  1446                 break; // Move on to next proxy
       
  1447                 }
       
  1448             }
       
  1449         }
       
  1450 
       
  1451     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::LoadDynamicChannelSsysIfNeeded - return %d" ), ssyLoadPending ) );
       
  1452     return ssyLoadPending;
       
  1453     }
       
  1454 
       
  1455 // ---------------------------------------------------------------------------
       
  1456 // Removes channel change listener from the matching dynamic channel SSYs to allow unloading
       
  1457 // ---------------------------------------------------------------------------
       
  1458 //
       
  1459 void CSensrvProxyManager::RemoveChannelChangeListenerFromDynamicChannelSsys(const TSensrvResourceChannelInfo& aQueryInfo,
       
  1460                                                                             const RMessage2& aQueryMessage)
       
  1461     {
       
  1462     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::RemoveChannelChangeListenerFromDynamicChannelSsys" ) ) );
       
  1463 
       
  1464     TInt proxyCount = iProxyList.Count();
       
  1465     for(TInt i = 0; i < proxyCount; ++i)
       
  1466         {
       
  1467         CSensrvPluginProxy* proxy = iProxyList[i];
       
  1468         TInt channelCount = proxy->DynamicChannelInfoList().Count();
       
  1469         for(TInt j = 0; j < channelCount; ++j)
       
  1470             {
       
  1471             if (proxy->DynamicChannelInfoList()[j].IsMatch(aQueryInfo, aQueryMessage))
       
  1472                 {
       
  1473                 proxy->RemoveChannelChangeListener();
       
  1474                 break; // Move on to next proxy
       
  1475                 }
       
  1476             }
       
  1477         }
       
  1478 
       
  1479     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvProxyManager::RemoveChannelChangeListenerFromDynamicChannelSsys - return" ) ) );
       
  1480     }
       
  1481 
       
  1482 // End of file