sensorservices/sensorserver/src/server/sensrvpluginproxy.cpp
changeset 0 4e1aa6a622a0
child 7 1fc153c72b60
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 plugin proxy implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <ecom/ecom.h>
       
    20 #include "sensrvdefines.h"
       
    21 #include "sensrvpluginproxy.h"
       
    22 #include "sensrvproxymanager.h"
       
    23 #include "sensrvtransaction.h"
       
    24 #include "sensrvtransactionqueue.h"
       
    25 #include "sensrvtransactionmonitor.h"
       
    26 #include "senserverchannel.h"
       
    27 #include "sensrvssymediator.h"
       
    28 #include "sensrvservermediator.h"
       
    29 #include "sensrvssyactivescheduler.h"
       
    30 #include "sensrvclientserver.h"
       
    31 #include "sensrvthreadmonitor.h"
       
    32 #include "sensrvchanneldatareader.h"
       
    33 
       
    34 // ---------------------------------------------------------------------------
       
    35 // 2-phase constructor
       
    36 // ---------------------------------------------------------------------------
       
    37 //
       
    38 CSensrvPluginProxy* CSensrvPluginProxy::NewL(CSensrvProxyManager& aParent,
       
    39                          TUid aImplementationUid)
       
    40     {
       
    41     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::NewL(<proxymanager>, aImplementationUid: 0x%x)" ), aImplementationUid.iUid ) );
       
    42 
       
    43     CSensrvPluginProxy* self = new( ELeave ) CSensrvPluginProxy(aParent, aImplementationUid);
       
    44 
       
    45     CleanupStack::PushL( self );
       
    46     self->ConstructL();
       
    47     CleanupStack::Pop( self );
       
    48 
       
    49     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::NewL - return 0x%x" ), self ) );
       
    50 
       
    51     return self;
       
    52     }
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // C++ constructor
       
    56 // ---------------------------------------------------------------------------
       
    57 //
       
    58 CSensrvPluginProxy::CSensrvPluginProxy(CSensrvProxyManager& aParent,
       
    59                                        TUid aImplementationUid)
       
    60         : iPluginState( EPluginStateUninitialized ),
       
    61           iProxyManager(aParent),
       
    62           iImplementationUid(aImplementationUid)
       
    63     {
       
    64     // Nothing to do
       
    65     }
       
    66 
       
    67 // ---------------------------------------------------------------------------
       
    68 // 2nd phase of construction
       
    69 // ---------------------------------------------------------------------------
       
    70 //
       
    71 void CSensrvPluginProxy::ConstructL()
       
    72     {
       
    73     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::ConstructL()" ) ) );
       
    74 
       
    75     // Init mutex
       
    76     User::LeaveIfError(iMutex.CreateLocal());
       
    77 
       
    78     iMutex.Wait();
       
    79 
       
    80     iLoadWaitQueue = CSensrvTransactionQueue::NewL(ETrue);
       
    81 
       
    82     iTransactionMonitor = CSensrvTransactionMonitor::NewL(*this);
       
    83 
       
    84     // Note: Slight memory savings are possible if iThreadMonitor and iUnloadTimer
       
    85     // are created and deleted alongside SSY thread. However, since the timer events
       
    86     // in these classes initiate cleanup, it is not trivial. Maybe server mediator
       
    87     // could be utilized for delayed cleanup of these classes?
       
    88 
       
    89     iThreadMonitor = CSensrvThreadMonitor::NewL(*this);
       
    90 
       
    91     iUnloadTimer = CSensrvTimer::NewL(*this,
       
    92                                       iProxyManager.SsyInactivityPeriod(),
       
    93                                       CSensrvTimer::ETimerIdSsyInactivityTimer);
       
    94 
       
    95     iMutex.Signal();
       
    96 
       
    97     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::ConstructL - return" ) ) );
       
    98     }
       
    99 
       
   100 // ---------------------------------------------------------------------------
       
   101 // Destructor
       
   102 // ---------------------------------------------------------------------------
       
   103 //
       
   104 CSensrvPluginProxy::~CSensrvPluginProxy()
       
   105     {
       
   106     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::~CSensrvPluginProxy()" ) ) );
       
   107 
       
   108     iMutex.Wait();
       
   109 
       
   110     delete iThreadMonitor;
       
   111     delete iTransactionMonitor;
       
   112 
       
   113     delete iServerMediator;
       
   114     delete iSsyMediator;
       
   115 
       
   116     // Cleanup channels
       
   117     TInt count = iChannelList.Count();
       
   118     for(TInt i = 0; i < count; i ++)
       
   119         {
       
   120         delete iChannelList[i];
       
   121         }
       
   122 
       
   123     iChannelList.Reset();
       
   124     iChannelInfoList.Reset();
       
   125     iRemovedChannelsInfoList.Reset();
       
   126     iDynamicChannelInfoList.Reset();
       
   127 
       
   128     delete iLoadWaitQueue;
       
   129     delete iUnloadTimer;
       
   130 
       
   131     iMutex.Signal();
       
   132 
       
   133     iMutex.Close();
       
   134 
       
   135     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::~CSensrvPluginProxy - return" ) ) );
       
   136     }
       
   137 
       
   138 
       
   139 
       
   140 // ---------------------------------------------------------------------------
       
   141 // Completes the transaction and calls handling for next one in queue.
       
   142 // ---------------------------------------------------------------------------
       
   143 //
       
   144 void CSensrvPluginProxy::TransactionHandledAtSsy(CSensrvTransaction* aTransaction)
       
   145     {
       
   146     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy(aTransaction: 0x%x)" ), aTransaction ) );
       
   147 
       
   148     // Handle transaction according to transaction type
       
   149     if (aTransaction)
       
   150         {
       
   151         // Route transaction finalization according to transaction type
       
   152         switch(aTransaction->Type())
       
   153             {
       
   154             // Proxy level transactions handled here
       
   155             case CSensrvTransaction::ETransTypeLoadSsy:
       
   156             case CSensrvTransaction::ETransTypeMediatorChannelsChanged:
       
   157                 {
       
   158                 CompleteTransaction(aTransaction);
       
   159                 }
       
   160                 break;
       
   161 
       
   162             // Channel level transactions handled in corresponding channel object.
       
   163             case CSensrvTransaction::ETransTypeOpenChannel:
       
   164             case CSensrvTransaction::ETransTypeCloseChannel:
       
   165             case CSensrvTransaction::ETransTypeStartListening:
       
   166             case CSensrvTransaction::ETransTypeStopListening:
       
   167             case CSensrvTransaction::ETransTypeMediatorNewDataAvailable:
       
   168             case CSensrvTransaction::ETransTypeGetProperty:
       
   169             case CSensrvTransaction::ETransTypeGetAllProperties:
       
   170             case CSensrvTransaction::ETransTypeSetProperty:
       
   171             case CSensrvTransaction::ETransTypeStartConditionListening:
       
   172             case CSensrvTransaction::ETransTypeStopConditionListening:
       
   173             case CSensrvTransaction::ETransTypeMediatorPropertyChanged:
       
   174             case CSensrvTransaction::ETransTypeMediatorForceChannelClose:
       
   175                 {
       
   176                 // These transactions must always have valid channel object.
       
   177                 __ASSERT_ALWAYS(aTransaction->Channel(), User::Panic(KSensrvPanicCategory, ESensrvPanicNullChannel));
       
   178 
       
   179                 aTransaction->Channel()->CompleteTransaction(aTransaction);
       
   180                 }
       
   181                 break;
       
   182 
       
   183             default:
       
   184                 // Unexpected transaction type, so we do not know what to do with it
       
   185                 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy - ERROR: Invalid transaction type" ) ) );
       
   186                 User::Panic(KSensrvPanicCategory, ESensrvPanicUnknownTransactionType);
       
   187                 break;
       
   188             }
       
   189         }
       
   190     else
       
   191         {
       
   192         // NULL transaction used to trigger transaction handling.
       
   193         if ( iPluginState == EPluginStateThreadInitializing )
       
   194             {
       
   195             // Initial notify from SSY thread.
       
   196             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy - SSY thread initialization completion detected." ) ) );
       
   197 
       
   198             SetPluginState(EPluginStateThreadInitialized);
       
   199 
       
   200             // Start handling queued transactions
       
   201             HandleNextTransaction();
       
   202             }
       
   203         else if (iPluginState == EPluginStateUnloaded)
       
   204             {
       
   205             // SSY unloading has finished, handle next transaction if any
       
   206             HandleNextTransaction();
       
   207             }
       
   208         else
       
   209             {
       
   210             // Can get here if server mediator has been notified,
       
   211             // but before its RunL is executed, the only transaction in server mediator's queue
       
   212             // is deleted (because of client panic caused session termination, for example).
       
   213             // Highly unlikely case, but theoretically possible.
       
   214             // In that case we can just ignore the notification.
       
   215             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy - NULL transaction in an unexpected plugin state: %d" ), iPluginState ) );
       
   216             }
       
   217         }
       
   218 
       
   219     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy - return" ) ) );
       
   220     }
       
   221 
       
   222 
       
   223 // ---------------------------------------------------------------------------
       
   224 // Initializes plugin mediators and thread,
       
   225 // loads the plugin and queries for supported channels.
       
   226 // ---------------------------------------------------------------------------
       
   227 //
       
   228 void CSensrvPluginProxy::InitializePluginL()
       
   229     {
       
   230     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL()" ) ) );
       
   231 
       
   232     iMutex.Wait();
       
   233 
       
   234     iPreviousSsyLoadFailed = EFalse; // Reset SSY load fail indicator
       
   235 
       
   236     if (iPluginState != EPluginStateUnloading)
       
   237         {
       
   238         // Create mutex signaling cleanup item.
       
   239         CleanupStack::PushL(
       
   240             TCleanupItem( CleanupInitializePlugin, this ) );
       
   241 
       
   242         // Create Ssy thread
       
   243         // Use unique identifier generated by proxy manager to name thread
       
   244         // so that name is guaranteed unique, yet recognizable.
       
   245         HBufC* buf = HBufC::NewLC(KSensrvSsyThreadNameMaxLen);
       
   246         buf->Des().Append(KSensrvSsyThreadNameBase);
       
   247 
       
   248         TInt err(KErrAlreadyExists);
       
   249 
       
   250         while (err == KErrAlreadyExists)
       
   251             {
       
   252 
       
   253             buf->Des().AppendNum(iProxyManager.GenerateUniqueId());
       
   254 
       
   255             err = iSsyThread.Create(*buf,
       
   256                                     SsyThreadFunction,
       
   257                                     ProxyManager().SsyStackSize(),
       
   258                                     KSensrvSsyHeapInitialSize,
       
   259                                     ProxyManager().SsyHeapMaxSize(),
       
   260                                     (TAny*)this);
       
   261 
       
   262             if (err == KErrAlreadyExists)
       
   263                 {
       
   264                 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL - Thread name is already in use, recreating..." ) ) );
       
   265                 }
       
   266 
       
   267             buf->Des().Delete(KSensrvSsyThreadNameBaseLen, KSensrvSsyThreadNameMaxLen);
       
   268             }
       
   269 
       
   270         if (err != KErrNone)
       
   271             {
       
   272             ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL - Error creating thread." ) ) );
       
   273             User::Leave(err);
       
   274             }
       
   275 
       
   276         CleanupStack::PopAndDestroy(buf);
       
   277 
       
   278         // start monitoring the thread
       
   279         User::LeaveIfError(iThreadMonitor->StartMonitoring(iSsyThread));
       
   280 
       
   281         // If InitializePluginL leaves, thread monitor triggered cleanup will set state again
       
   282         SetPluginState(EPluginStateThreadInitializing);
       
   283 
       
   284         // SSY mediator is created here but initialized by SSY thread as it needs current thread handle.
       
   285         iSsyMediator = CSensrvSsyMediator::NewL(this);
       
   286 
       
   287         // Create and initialize server mediator if not yet created
       
   288         if (!iServerMediator)
       
   289             {
       
   290             iServerMediator = CSensrvServerMediator::NewL(this);
       
   291             User::LeaveIfError(iServerMediator->Initialize());
       
   292             // Note: SSY mediator is initialized by SSY thread
       
   293             }
       
   294 
       
   295         // Initially there are no channel change listeners concerning this proxy
       
   296         iChannelChangeListenerCount = 0;
       
   297 
       
   298         // Create transaction for loading plugin.
       
   299         CSensrvTransaction* loadTransaction = NULL;
       
   300         loadTransaction = CSensrvTransaction::NewL(
       
   301             NULL,
       
   302             this,
       
   303             NULL,
       
   304             CSensrvTransaction::ETransTypeLoadSsy);
       
   305 
       
   306         // Add transaction to the beginning of the queue
       
   307         err = QueueTransaction(loadTransaction, EFalse);
       
   308 
       
   309         if (err == KErrNone)
       
   310             {
       
   311             // Resume Ssy thread. Must be last thing to do in this method
       
   312             // so that nothing else can leave after this.
       
   313             iSsyThread.Resume();
       
   314             }
       
   315         else
       
   316             {
       
   317             ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL - ERROR: Failed to queue load transaction %d" ), err ) );
       
   318             // Cleanup transaction
       
   319             loadTransaction->SetErrorCode(err);
       
   320             loadTransaction->Complete();
       
   321             delete loadTransaction;
       
   322             User::Leave(err);
       
   323             }
       
   324 
       
   325         CleanupStack::Pop(); // CleanupInitializePlugin
       
   326         }
       
   327     else
       
   328         {
       
   329         TInt err = EnqueueDelayedInitializeTransaction();
       
   330         if (err == KErrNone)
       
   331             {
       
   332             // Handle delayed initialize immediately, if already fully unloaded
       
   333             if (iPluginState == EPluginStateUnloaded)
       
   334                 {
       
   335                 HandleNextTransaction();
       
   336                 }
       
   337             }
       
   338         else
       
   339             {
       
   340             ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL - ERROR: Failed to queue delayed initialize %d" ), err ) );
       
   341             iPreviousSsyLoadFailed = ETrue;
       
   342             User::Leave(err);
       
   343             }
       
   344         }
       
   345 
       
   346     iMutex.Signal();
       
   347 
       
   348     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL - return" ) ) );
       
   349     }
       
   350 
       
   351 // ---------------------------------------------------------------------------
       
   352 // Initializes plugin channel data.
       
   353 // ---------------------------------------------------------------------------
       
   354 //
       
   355 TInt CSensrvPluginProxy::InitializeChannelData( const CImplementationInformation& aImplInfo )
       
   356     {
       
   357     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializeChannelDataL" ) ) );
       
   358 
       
   359     TSensrvChannelDataReader reader;
       
   360     TInt err = reader.ReadChannels( aImplInfo, iChannelInfoList, iDynamicChannelInfoList );
       
   361     if ( err == KErrNone )
       
   362         {
       
   363         // Generate unique IDs for static channels now. IDs for dynamic channels are handled by SSY channel registration.
       
   364         TInt count( iChannelInfoList.Count() );
       
   365         for( TInt i = 0; i < count; i++)
       
   366             {
       
   367             TSensrvChannelId newId = static_cast<TSensrvChannelId>(ProxyManager().GenerateUniqueId());
       
   368 
       
   369             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializeChannelDataL - plugin UID: 0x%x channel: %d" ),
       
   370                 aImplInfo.ImplementationUid().iUid, newId ) );
       
   371 
       
   372             iChannelInfoList[i].iChannelId = newId;
       
   373             }
       
   374         }
       
   375     iIsInitialized = ETrue; // even though thread not setup and plugin not laoded yet.
       
   376 
       
   377     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializeChannelDataL - err %d, return" ), err ) );
       
   378 
       
   379     return err;
       
   380     }
       
   381 
       
   382 // ---------------------------------------------------------------------------
       
   383 // Handles client message.
       
   384 // All messages coming from client to proxy target specific channel,
       
   385 // so pass the message to correct channel object.
       
   386 // Proxy manager makes sure that messages dispatched to each proxy
       
   387 // actually target a channel provided by that proxy, so no rechecking is done.
       
   388 // ---------------------------------------------------------------------------
       
   389 //
       
   390 void CSensrvPluginProxy::DispatchMessage(CSensrvMessage& aMessage,
       
   391                                          TSensrvChannelId aChannelId)
       
   392     {
       
   393     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage(aMessage.Function(): %d, aChannelId: %d)" ), aMessage.Function(), aChannelId ) );
       
   394 
       
   395     iMutex.Wait();
       
   396 
       
   397     TInt err(KErrNone);
       
   398     TBool completeMessageOnError(ETrue);
       
   399 
       
   400     // Check state
       
   401     if (iDeletionFlag)
       
   402         {
       
   403         // If proxy is marked for deletion, do not allow further messages
       
   404         err = KErrNotFound;
       
   405         }
       
   406     else
       
   407         {
       
   408         if (iPluginState == EPluginStateLoaded)
       
   409             {
       
   410             // Get channel and pass message there
       
   411             CSensrvChannel* channel = GetChannelForId(aChannelId);
       
   412 
       
   413             // Special case: When opening channel, create channel if it is not found
       
   414             if (aMessage.Function() == ESensrvSrvReqOpenChannel && !channel)
       
   415                 {
       
   416                 // Get channel info
       
   417                 TSensrvChannelInfo* info = GetChannelInfoForId(aChannelId);
       
   418 
       
   419                 if (info)
       
   420                     {
       
   421                     TRAPD(err, channel = CSensrvChannel::NewL(*info, *this));
       
   422                     if (err == KErrNone)
       
   423                         {
       
   424                         // Add channel to channel list
       
   425                         err = iChannelList.Append(channel);
       
   426 
       
   427                         if (err != KErrNone)
       
   428                             {
       
   429                             delete channel;	// Deleting the channel that is allocated on the heap in case Append Failure.
       
   430                             channel = NULL;
       
   431                             ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - ERROR: Failed to append channel to array: %d" ), err ) );
       
   432                             }
       
   433                         }
       
   434                     else
       
   435                         {
       
   436                         ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - ERROR: Failed to create channel: %d" ), err ) );
       
   437                         }
       
   438                     }
       
   439                 else
       
   440                     {
       
   441                     ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - ERROR: No channel info found" ) ) );
       
   442                     err = KErrNotFound;
       
   443                     }
       
   444                 }
       
   445 
       
   446             if (err == KErrNone)
       
   447                 {
       
   448                 if (channel)
       
   449                     {
       
   450                     channel->DispatchMessage(aMessage);
       
   451                     }
       
   452                 else
       
   453                     {
       
   454                     // If channel object doesn't exist, something is wrong.
       
   455                     ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - ERROR: No channel object" ) ) );
       
   456                     err = KErrNotFound;
       
   457                     }
       
   458                 }
       
   459             }
       
   460         else if (   aMessage.Function() == ESensrvSrvReqOpenChannel
       
   461                  && iPluginState != EPluginStateUninitialized )
       
   462             {
       
   463             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - Queuing open channel message" ) ) );
       
   464 
       
   465             // If unloading/unloaded, queue initialization transaction.
       
   466             if (iPluginState == EPluginStateUnloading || iPluginState == EPluginStateUnloaded)
       
   467                 {
       
   468                 err = EnqueueDelayedInitializeTransaction();
       
   469                 }
       
   470 
       
   471             // Queue open transaction into wait queue until plugin can load itself.
       
   472             if (err == KErrNone)
       
   473                 {
       
   474                 completeMessageOnError = EFalse;
       
   475 
       
   476                 CSensrvTransaction* transaction = NULL;
       
   477 
       
   478                 TRAP(err, transaction = CSensrvTransaction::NewL(
       
   479                     &aMessage,
       
   480                     this,
       
   481                     NULL,
       
   482                     CSensrvTransaction::ETransTypeDelayedOpenChannel));
       
   483 
       
   484                 if (err == KErrNone)
       
   485                     {
       
   486                     err = QueueTransaction(transaction, ETrue);
       
   487 
       
   488                     if(err == KErrNone)
       
   489                         {
       
   490                         // Add transaction to monitor for the duration of the wait.
       
   491                         iTransactionMonitor->AddTransaction(transaction);
       
   492                         }
       
   493                     else
       
   494                         {
       
   495                         transaction->SetErrorCode(err);
       
   496                         transaction->Complete();
       
   497                         delete transaction;
       
   498                         transaction = NULL;
       
   499                         }
       
   500                     }
       
   501                 }
       
   502 
       
   503             // Handle delayed initialize immediately, if already fully unloaded
       
   504             if (err == KErrNone && iPluginState == EPluginStateUnloaded)
       
   505                 {
       
   506                 HandleNextTransaction();
       
   507                 }
       
   508             }
       
   509         else
       
   510             {
       
   511             ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - ERROR: Plugin in invalid state: %d" ), iPluginState ) );
       
   512             err = KErrNotReady;
       
   513             }
       
   514         }
       
   515 
       
   516     if (err != KErrNone && completeMessageOnError)
       
   517         {
       
   518         aMessage.Complete(err);
       
   519         }
       
   520 
       
   521     iMutex.Signal();
       
   522 
       
   523     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - return" ) ) );
       
   524     }
       
   525 
       
   526 // ---------------------------------------------------------------------------
       
   527 // Checks if this proxy supports specified channel
       
   528 // ---------------------------------------------------------------------------
       
   529 //
       
   530 TBool CSensrvPluginProxy::IsChannelSupported(TSensrvChannelId aChannelId)
       
   531     {
       
   532     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::IsChannelSupported(aChannelId: %d)" ), aChannelId ) );
       
   533 
       
   534     TBool isSupported(EFalse);
       
   535 
       
   536     iMutex.Wait();
       
   537 
       
   538     if (iIsInitialized)
       
   539         {
       
   540         TInt channelCount = iChannelInfoList.Count();
       
   541         if (channelCount > 0)
       
   542             {
       
   543             for(TInt j = 0; !isSupported && j < channelCount; j++)
       
   544                 {
       
   545                 if (iChannelInfoList[j].iChannelId == aChannelId)
       
   546                     {
       
   547                     isSupported = ETrue;
       
   548                     }
       
   549                 }
       
   550             }
       
   551         }
       
   552     else
       
   553         {
       
   554         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::IsChannelSupported - Proxy not yet initialized" ) ) );
       
   555         }
       
   556 
       
   557     iMutex.Signal();
       
   558 
       
   559     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::IsChannelSupported - return %d" ), isSupported) );
       
   560 
       
   561     return isSupported;
       
   562     }
       
   563 
       
   564 // ---------------------------------------------------------------------------
       
   565 // Gets channel object handling specified channel.
       
   566 // ---------------------------------------------------------------------------
       
   567 //
       
   568 CSensrvChannel* CSensrvPluginProxy::GetChannelForId(TSensrvChannelId aChannelId) const
       
   569     {
       
   570     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetChannelForId(aChannelId: %d)" ), aChannelId ) );
       
   571 
       
   572     CSensrvChannel* returnChannel = NULL;
       
   573 
       
   574     TInt channelCount = iChannelList.Count();
       
   575     for(TInt i = 0; !returnChannel && i < channelCount; i++)
       
   576         {
       
   577         if (iChannelList[i]->Id() == aChannelId)
       
   578             {
       
   579             returnChannel = iChannelList[i];
       
   580             }
       
   581         }
       
   582 
       
   583     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetChannelForId - return 0x%x" ), returnChannel ) );
       
   584 
       
   585     return returnChannel;
       
   586     }
       
   587 
       
   588 
       
   589 // ---------------------------------------------------------------------------
       
   590 // Cleans up everything related to terminated session.
       
   591 // ---------------------------------------------------------------------------
       
   592 //
       
   593 void CSensrvPluginProxy::SessionTerminated( CSensrvSession* aSession )
       
   594     {
       
   595     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SessionTerminated(aSession: 0x%x)"),aSession ) );
       
   596 
       
   597     iMutex.Wait();
       
   598 
       
   599     // Cleanup any waiting transactions for this session
       
   600     iLoadWaitQueue->Remove(aSession);
       
   601     iTransactionMonitor->RemoveSessionTransactions(aSession);
       
   602 
       
   603     // Clean up mediators
       
   604     if (iSsyMediator)
       
   605         {
       
   606         iSsyMediator->SessionTerminated(aSession);
       
   607         }
       
   608 
       
   609     if (iServerMediator)
       
   610         {
       
   611         iServerMediator->SessionTerminated(aSession);
       
   612         }
       
   613 
       
   614 
       
   615     // Call session cleanup on each channel
       
   616     TInt channelCount = iChannelList.Count();
       
   617     for(TInt i = 0; i < channelCount; i++)
       
   618         {
       
   619         iChannelList[i]->SessionTerminated(aSession);
       
   620         }
       
   621 
       
   622     iMutex.Signal();
       
   623 
       
   624     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SessionTerminated - return" )) );
       
   625     }
       
   626 
       
   627 // ---------------------------------------------------------------------------
       
   628 // Handles SSY notification failure.
       
   629 // This means going through all channels checking where failure possibly
       
   630 // occurred, and of course any proxy level transactions.
       
   631 // Note that this can execute transactions out of original sequence they
       
   632 // have been notified to server mediator, but this should be no problem,
       
   633 // each single channel can only have single ongoing transaction at SSY.
       
   634 // Transactions of different channels do not interfere with each other.
       
   635 // ---------------------------------------------------------------------------
       
   636 //
       
   637 void CSensrvPluginProxy::HandleSsyNotifyFailure()
       
   638     {
       
   639     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleSsyNotifyFailure()" ) ) );
       
   640 
       
   641     // Check queued transactions to determine if they are handled at SSY
       
   642     CSensrvTransaction* transaction = iLoadWaitQueue->First();
       
   643 
       
   644     if (transaction && transaction->State() == CSensrvTransaction::ETransStateNotifyFailed)
       
   645         {
       
   646         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleSsyNotifyFailure - Notify failed transaction found" ) ) );
       
   647         transaction->SetState(CSensrvTransaction::ETransStateHandledAtSsy);
       
   648         TransactionHandledAtSsy(transaction);
       
   649         }
       
   650 
       
   651     if (   iSsyMediator
       
   652         && iSsyMediator->ChannelChangeTransaction()
       
   653         && iSsyMediator->ChannelChangeTransaction()->State() == CSensrvTransaction::ETransStateNotifyFailed)
       
   654         {
       
   655         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleSsyNotifyFailure - Notify failed transaction found (ETransTypeMediatorChannelsChanged)" ) ) );
       
   656         iSsyMediator->ChannelChangeTransaction()->SetState(CSensrvTransaction::ETransStateHandledAtSsy);
       
   657         TransactionHandledAtSsy(iSsyMediator->ChannelChangeTransaction());
       
   658         }
       
   659 
       
   660     // Pass notification to each channel
       
   661     TInt channelCount = iChannelList.Count();
       
   662     for(TInt i = 0; i < channelCount; i++)
       
   663         {
       
   664         iChannelList[i]->HandleSsyNotifyFailure();
       
   665         }
       
   666 
       
   667     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleSsyNotifyFailure - return" ) ) );
       
   668     }
       
   669 
       
   670 // ---------------------------------------------------------------------------
       
   671 // Unloads SSY as any timed out transactions probably mean that
       
   672 // SSY has either crashed or is deadlocked.
       
   673 // ---------------------------------------------------------------------------
       
   674 //
       
   675 void CSensrvPluginProxy::HandleTransactionTimeout()
       
   676     {
       
   677     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleTransactionTimeout()" ) ) );
       
   678 
       
   679     // Any transaction timeout results in unloading of the SSY
       
   680     CleanupPlugin();
       
   681 
       
   682     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleTransactionTimeout - return" ) ) );
       
   683     }
       
   684 
       
   685 // ---------------------------------------------------------------------------
       
   686 // Deletes SSY mediator and closes thread.
       
   687 // ---------------------------------------------------------------------------
       
   688 //
       
   689 void CSensrvPluginProxy::SsyThreadTerminated()
       
   690     {
       
   691     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SsyThreadTerminated()" ) ) );
       
   692 
       
   693     // Instead of delete, Free is used.
       
   694     // It means that destructor of the iSsyMediator is not called.
       
   695     // Calling the destructor causes KERN-EXEC 3 in servers main thread
       
   696     // if SSY thread is not anymore alive.
       
   697     // iSsyMediator inherit from CActive and calling ~CActive() while its
       
   698     // scheduler is dead causes KERN-EXEC 3 panic.
       
   699     iSsyMediator->Destruct();
       
   700     iSsyMediator->BaseDestruct();
       
   701     iProxyManager.ServerHeap()->Free( iSsyMediator );
       
   702     iSsyMediator = NULL;
       
   703 
       
   704     // Note: Server mediator is not deleted until proxy is deleted,
       
   705     // as in some cases resulting in cleanup, its RunL-method is what initiated the sequence.
       
   706 
       
   707     iSsyThread.Close();
       
   708 
       
   709     TPluginState previousState = iPluginState;
       
   710     SetPluginState(EPluginStateUnloaded);
       
   711 
       
   712     // Cleanup needed in case SSY thread termination was uncontrolled.
       
   713     if (previousState != EPluginStateUnloading)
       
   714         {
       
   715         CleanupPlugin();
       
   716         }
       
   717 
       
   718     // Notify server mediator with null transaction to handle next transaction
       
   719     if (iLoadWaitQueue && iServerMediator && !iLoadWaitQueue->IsEmpty())
       
   720         {
       
   721         iServerMediator->Notify(NULL);
       
   722         }
       
   723 
       
   724     // Notify proxy manager that thread has terminated
       
   725     iProxyManager.SsyThreadTerminated();
       
   726 
       
   727     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SsyThreadTerminated - return" ) ) );
       
   728     }
       
   729 
       
   730 // ---------------------------------------------------------------------------
       
   731 // Starts SSY unload timer if no clients
       
   732 // ---------------------------------------------------------------------------
       
   733 //
       
   734 void CSensrvPluginProxy::StartUnloadTimerIfNeeded()
       
   735     {
       
   736     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded()" ) ) );
       
   737 
       
   738     if (!iUnloadTimer->IsActive() )
       
   739         {
       
   740         if (GetTotalListenerCount())
       
   741             {
       
   742             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded - Listener found, aborting" ) ) );
       
   743             }
       
   744         else if (iChannelChangeListenerCount > 0)
       
   745             {
       
   746             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded - Change listener found, aborting" ) ) );
       
   747             }
       
   748         else
       
   749             {
       
   750             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded - No listeners found, starting unload timer" ) ) );
       
   751             iUnloadTimer->Set(iProxyManager.SsyInactivityPeriod());
       
   752             }
       
   753         }
       
   754     else
       
   755         {
       
   756         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded - Unload timer already active or scheduler stopped" ) ) );
       
   757         }
       
   758 
       
   759     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded - return " ) ) );
       
   760     }
       
   761 
       
   762 
       
   763 // ---------------------------------------------------------------------------
       
   764 // Kill threads if they are still active
       
   765 // ---------------------------------------------------------------------------
       
   766 //
       
   767 void CSensrvPluginProxy::TimerFired(TInt /*aTimerId*/)
       
   768     {
       
   769     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TimerFired()" ) ) );
       
   770 
       
   771     iMutex.Wait();
       
   772 
       
   773     // Doublecheck that there is still zero listeners, just in case
       
   774     if(!GetTotalListenerCount())
       
   775         {
       
   776         CleanupPlugin();
       
   777         }
       
   778 
       
   779     iMutex.Signal();
       
   780 
       
   781     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TimerFired - return " ) ) );
       
   782     }
       
   783 
       
   784 // ---------------------------------------------------------------------------
       
   785 // Cleans up the plugin and thread
       
   786 // ---------------------------------------------------------------------------
       
   787 //
       
   788 void CSensrvPluginProxy::CleanupPlugin()
       
   789     {
       
   790     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CleanupPlugin()" ) ) );
       
   791 
       
   792     // Something has failed, so notify proxy manager that proxy initialization is complete,
       
   793     // if this happened during the first attempt to load plugin.
       
   794     // Note that this will leave proxy with zero channels
       
   795     // but there is not much we can do about it, as it is very unlikely that reload would be
       
   796     // successfull either.
       
   797 
       
   798     if (!iIsInitialized ||
       
   799          iPluginState == EPluginStateUninitialized ||
       
   800          iPluginState == EPluginStateThreadInitializing ||
       
   801          iPluginState == EPluginStateThreadInitialized)
       
   802         {
       
   803         iPreviousSsyLoadFailed = ETrue;
       
   804         // If first fail, fake initialized and notify manager to continue pending activities
       
   805         // If proxy provides dynamic channels, notify manager to continue pending channel queries
       
   806         if (!iIsInitialized || iDynamicChannelInfoList.Count() > 0)
       
   807             {
       
   808             iIsInitialized = ETrue;
       
   809             iProxyManager.NotifyProxyInitialized();
       
   810             }
       
   811         }
       
   812 
       
   813     // Cleanup channels
       
   814     iChannelList.ResetAndDestroy();
       
   815 
       
   816     // Cleanup all ongoing transactions.
       
   817     if (iTransactionMonitor)
       
   818         {
       
   819         iTransactionMonitor->RemoveAllTransactions();
       
   820         }
       
   821 
       
   822 
       
   823     if (iServerMediator)
       
   824         {
       
   825 
       
   826         iMutex.Wait();
       
   827         iServerMediator->RemoveAllTransactions();
       
   828         iMutex.Signal();
       
   829         }
       
   830 
       
   831     if (iPluginState != EPluginStateUnloaded && iLoadWaitQueue)
       
   832         {
       
   833         // Load wait transactions are not cleared when cleanup is called from SsyThreadTerminated()
       
   834         iLoadWaitQueue->RemoveAll();
       
   835         }
       
   836 
       
   837     // Clean up SSY mediator. Actual deletion of SSY mediator is done in SsyThreadTerminated()
       
   838     if (iSsyMediator)
       
   839         {
       
   840         SetPluginState(EPluginStateUnloading);
       
   841         iSsyMediator->Cleanup();
       
   842         }
       
   843     else
       
   844         {
       
   845         SetPluginState(EPluginStateUnloaded);
       
   846         }
       
   847 
       
   848     // Thread monitor needs to ensure that SSY thread dies.
       
   849     // If cleanup was triggered by thread dying, this is not needed
       
   850     if (iThreadMonitor && iPluginState != EPluginStateUnloaded)
       
   851         {
       
   852         iThreadMonitor->DelayedTermination();
       
   853         }
       
   854 
       
   855     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CleanupPlugin - return" ) ) );
       
   856     }
       
   857 
       
   858 // ---------------------------------------------------------------------------
       
   859 // Queues transaction
       
   860 // ---------------------------------------------------------------------------
       
   861 //
       
   862 TInt CSensrvPluginProxy::QueueTransaction(CSensrvTransaction* aTransaction, TBool aLast)
       
   863     {
       
   864     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::QueueTransaction(aTransaction: 0x%x, aLast: %d)" ), aTransaction, aLast ) );
       
   865 
       
   866     __ASSERT_ALWAYS(aTransaction, User::Panic(KSensrvPanicCategory, ESensrvPanicNullTransaction));
       
   867 
       
   868     TInt err(KErrNone);
       
   869 
       
   870     aTransaction->SetState(CSensrvTransaction::ETransStateQueued);
       
   871 
       
   872     err = iLoadWaitQueue->Add(aTransaction, aLast);
       
   873     if (err != KErrNone)
       
   874         {
       
   875         ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::QueueTransaction - ERROR: Failed to add transaction to queue" ) ) );
       
   876         }
       
   877 
       
   878     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::QueueTransaction - return %d" ), err ) );
       
   879 
       
   880     return err;
       
   881     }
       
   882 
       
   883 // ---------------------------------------------------------------------------
       
   884 // Executes the first transaction in given queue, unless it is already executing,
       
   885 // in which case nothing is done.
       
   886 // ---------------------------------------------------------------------------
       
   887 //
       
   888 void CSensrvPluginProxy::HandleNextTransaction()
       
   889     {
       
   890     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction()" ) ) );
       
   891 
       
   892     CSensrvTransaction* transaction = iLoadWaitQueue->First();
       
   893 
       
   894     if (transaction && !iDeletionFlag)
       
   895         {
       
   896         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - Handling transaction type: %d" ), transaction->Type() ) );
       
   897         if (transaction->State() == CSensrvTransaction::ETransStateQueued)
       
   898             {
       
   899             switch (transaction->Type())
       
   900                 {
       
   901                 case CSensrvTransaction::ETransTypeLoadSsy:
       
   902                     {
       
   903                     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ETransTypeLoadSsy" ) ) );
       
   904                     transaction->SetState(CSensrvTransaction::ETransStateExecuting);
       
   905 
       
   906                     // If SSY mediator is not yet initialized, it is an error
       
   907                     __ASSERT_ALWAYS(iSsyMediator, User::Panic(KSensrvPanicCategory, ESensrvPanicNullSsyMediator));
       
   908                   
       
   909 				   Mutex().Wait();
       
   910                     // Notify SSY mediator that transaction is ready to be handled.
       
   911                     TInt err(iSsyMediator->Notify(transaction));
       
   912                    Mutex().Signal();
       
   913                     // If there was error, transaction needs to be removed from queue (which also completes it)
       
   914                     if (err == KErrNone)
       
   915                         {
       
   916                         iTransactionMonitor->AddTransaction(transaction);
       
   917                         }
       
   918                     else
       
   919                         {
       
   920                         ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ERROR: Failed to handle next transaction: %d" ), err ) );
       
   921                         transaction->SetErrorCode(err);
       
   922                         iLoadWaitQueue->Remove(transaction, CSensrvTransactionQueue::ERemovalTypeComplete);
       
   923                         transaction = NULL;
       
   924 
       
   925                         // Since proxy only handles plugin level transactions (load),
       
   926                         // failure on any of them means we need to clean up the plugin,
       
   927                         // which will also clean up any pending transactions.
       
   928                         CleanupPlugin();
       
   929                         }
       
   930                     }
       
   931                     break;
       
   932                 case CSensrvTransaction::ETransTypeDelayedInitialize:
       
   933                     {
       
   934                     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ETransTypeDelayedInitialize" ) ) );
       
   935 
       
   936                     // Initialize only if state is unloaded
       
   937                     if (iPluginState == EPluginStateUnloaded)
       
   938                         {
       
   939                         iLoadWaitQueue->Remove(transaction, CSensrvTransactionQueue::ERemovalTypeComplete);
       
   940 
       
   941                         // Request initialize
       
   942                         TRAPD(err, InitializePluginL());
       
   943 
       
   944                         if (err != KErrNone)
       
   945                             {
       
   946                             ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ERROR: Failed to reinitialize plugin : %d" ), err ) );
       
   947                             }
       
   948                         }
       
   949                     else
       
   950                         {
       
   951                         ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ERROR: Attempted to reinitialize in invalid state: %d" ), iPluginState ) );
       
   952                         }
       
   953                     }
       
   954                     break;
       
   955                 case CSensrvTransaction::ETransTypeDelayedOpenChannel:
       
   956                     {
       
   957                     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ETransTypeDelayedOpenChannel" ) ) );
       
   958 
       
   959                     iTransactionMonitor->RemoveTransaction(transaction);
       
   960 
       
   961                     // Extract message from transaction and call dispatch from proper handling
       
   962                     CSensrvMessage* message = transaction->ExtractMessage();
       
   963 
       
   964                     iLoadWaitQueue->Remove(transaction, CSensrvTransactionQueue::ERemovalTypeComplete);
       
   965 
       
   966                     // No need to check error value, we already know message type is correct.
       
   967                     TSensrvChannelId channelId(0);
       
   968                     message->GetChannelId(channelId);
       
   969 
       
   970                     DispatchMessage(*message, channelId);
       
   971 
       
   972                     // Recursively handle next transaction
       
   973                     HandleNextTransaction();
       
   974                     }
       
   975                     break;
       
   976                 default:
       
   977                     // Unexpected transaction type, so we do not know what to do with it
       
   978                     ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ERROR: Invalid transaction type" ) ) );
       
   979                     User::Panic(KSensrvPanicCategory, ESensrvPanicUnknownTransactionType);
       
   980                     break;
       
   981                 }
       
   982             }
       
   983         else
       
   984             {
       
   985             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - Previous transaction still executing" ) ) );
       
   986             }
       
   987         }
       
   988     else
       
   989         {
       
   990         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - No transaction to execute" ) ) );
       
   991         }
       
   992 
       
   993     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - return" ) ) );
       
   994     }
       
   995 
       
   996 // ---------------------------------------------------------------------------
       
   997 // Handles transaction finalization and completes transaction on proxy's queue.
       
   998 // ---------------------------------------------------------------------------
       
   999 //
       
  1000 void CSensrvPluginProxy::CompleteTransaction(CSensrvTransaction* aTransaction)
       
  1001     {
       
  1002     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CompleteTransaction(aTransaction: 0x%x)" ), aTransaction ) );
       
  1003 
       
  1004     __ASSERT_ALWAYS(aTransaction, User::Panic(KSensrvPanicCategory, ESensrvPanicNullTransaction));
       
  1005 
       
  1006     switch (aTransaction->Type())
       
  1007         {
       
  1008         // Proxy level transactions handled here
       
  1009         case CSensrvTransaction::ETransTypeLoadSsy:
       
  1010             {
       
  1011             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CompleteTransaction - ETransTypeLoadSsy" ) ) );
       
  1012 
       
  1013             TInt err = aTransaction->ErrorCode();
       
  1014 
       
  1015             if ( err == KErrNone)
       
  1016                 {
       
  1017                 err = UpdateChannelInfoLists();
       
  1018 
       
  1019                 // Update plugin state
       
  1020                 SetPluginState(EPluginStateLoaded);
       
  1021                 }
       
  1022             else
       
  1023                 {
       
  1024                 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CompleteTransaction - ERROR: Load transaction failed %d" ), err ) );
       
  1025                 }
       
  1026 
       
  1027             if (err != KErrNone)
       
  1028                 {
       
  1029                 // Since there was an error, cleanup the plugin and thread
       
  1030                 CleanupPlugin();
       
  1031                 }
       
  1032             else
       
  1033                 {
       
  1034                 // Proxy has been initialized, notify manager
       
  1035                 // If proxy provides dynamic channels, notify manager to handle pending channel queries
       
  1036                 if (!iIsInitialized || iDynamicChannelInfoList.Count() > 0)
       
  1037                     {
       
  1038                     iIsInitialized = ETrue;
       
  1039                     iProxyManager.NotifyProxyInitialized();
       
  1040                     }
       
  1041 
       
  1042                 // Initially there are no clients, so startup unload timer
       
  1043                 StartUnloadTimerIfNeeded();
       
  1044                 }
       
  1045             }
       
  1046             break;
       
  1047 
       
  1048         case CSensrvTransaction::ETransTypeMediatorChannelsChanged:
       
  1049             {
       
  1050             COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CompleteTransaction - ETransTypeMediatorChannelsChanged" ) ) );
       
  1051 
       
  1052             // Error is irrelevant, as we can't do anything about it anyway, and UpdateChannelInfoLists()
       
  1053             // does its own tracing.
       
  1054             UpdateChannelInfoLists();
       
  1055             }
       
  1056             break;
       
  1057 
       
  1058         default:
       
  1059             // Unexpected transaction type, so we do not know what to do with it
       
  1060             ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy - ERROR: Invalid transaction type" ) ) );
       
  1061             User::Panic(KSensrvPanicCategory, ESensrvPanicUnknownTransactionType);
       
  1062             break;
       
  1063         }
       
  1064 
       
  1065     // Complete the transaction
       
  1066     iTransactionMonitor->RemoveTransaction(aTransaction);
       
  1067     iLoadWaitQueue->Remove(aTransaction, CSensrvTransactionQueue::ERemovalTypeComplete);
       
  1068 
       
  1069     // Handle next transaction.
       
  1070     HandleNextTransaction();
       
  1071 
       
  1072     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CompleteTransaction - return" ) ) );
       
  1073     }
       
  1074 
       
  1075 // ---------------------------------------------------------------------------
       
  1076 // Goes through channel infos and returns pointer to one that matches given id.
       
  1077 // ---------------------------------------------------------------------------
       
  1078 //
       
  1079 TSensrvResourceChannelInfo* CSensrvPluginProxy::GetChannelInfoForId( TSensrvChannelId aChannelId )
       
  1080     {
       
  1081     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetChannelInfoForId(aChannelId: %d)" ), aChannelId ) );
       
  1082 
       
  1083 	TSensrvResourceChannelInfo* info = NULL;;
       
  1084 
       
  1085     if (iIsInitialized)
       
  1086         {
       
  1087         TBool found(EFalse);
       
  1088         TInt channelCount = iChannelInfoList.Count();
       
  1089         if (channelCount > 0)
       
  1090             {
       
  1091             for(TInt j = 0; !found && j < channelCount; j++)
       
  1092                 {
       
  1093                 if (iChannelInfoList[j].iChannelId == aChannelId)
       
  1094                     {
       
  1095                     info = &iChannelInfoList[j];
       
  1096                     found = ETrue;
       
  1097                     }
       
  1098                 }
       
  1099             }
       
  1100         }
       
  1101     else
       
  1102         {
       
  1103         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetChannelInfoForId - Proxy not yet initialized" ) ) );
       
  1104         }
       
  1105 
       
  1106 
       
  1107     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetChannelInfoForId - return 0x%x" ), info ) );
       
  1108 
       
  1109     return info;
       
  1110     }
       
  1111 
       
  1112 // ---------------------------------------------------------------------------
       
  1113 // Set plugin state
       
  1114 // ---------------------------------------------------------------------------
       
  1115 //
       
  1116 void CSensrvPluginProxy::SetPluginState(TPluginState aState)
       
  1117     {
       
  1118     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SetPluginState(aState: %d)" ), aState ) );
       
  1119 
       
  1120     iPluginState = aState;
       
  1121     }
       
  1122 
       
  1123 // ---------------------------------------------------------------------------
       
  1124 // Gets total listener count from all channels
       
  1125 // ---------------------------------------------------------------------------
       
  1126 //
       
  1127 TInt CSensrvPluginProxy::GetTotalListenerCount()
       
  1128     {
       
  1129     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetTotalListenerCount()" ) ) );
       
  1130 
       
  1131     TInt channelCount(iChannelList.Count());
       
  1132     TInt listenerCount(0);
       
  1133 
       
  1134     for(TInt i = 0; i < channelCount; i ++)
       
  1135         {
       
  1136         listenerCount += iChannelList[i]->ListenerCount();
       
  1137         }
       
  1138 
       
  1139     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetTotalListenerCount - return: %d" ), listenerCount ) );
       
  1140 
       
  1141     return listenerCount;
       
  1142     }
       
  1143 
       
  1144 // ---------------------------------------------------------------------------
       
  1145 // Grabs raw channel info data from SSY mediator and
       
  1146 // Updates channel info and removed channel info lists.
       
  1147 // ---------------------------------------------------------------------------
       
  1148 //
       
  1149 TInt CSensrvPluginProxy::UpdateChannelInfoLists()
       
  1150     {
       
  1151     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists()" ) ) );
       
  1152 
       
  1153     TInt err(KErrNone);
       
  1154 
       
  1155     // Get new info into a temporary array.
       
  1156     RSensrvChannelInfoList newInfos;
       
  1157 
       
  1158     TAny** rawDataPtr = iSsyMediator->RawInfos();
       
  1159 
       
  1160     if (*rawDataPtr)
       
  1161         {
       
  1162         // First item in raw data is count
       
  1163         TInt* countPointer = reinterpret_cast<TInt*>(*rawDataPtr);
       
  1164 
       
  1165         if (*countPointer > 0)
       
  1166             {
       
  1167             err = newInfos.Reserve(*countPointer);
       
  1168 
       
  1169             // Data starts after count
       
  1170             TSensrvChannelInfo* info = reinterpret_cast<TSensrvChannelInfo*>(countPointer + 1);
       
  1171 
       
  1172             // Loop through raw data, appending datas to info list
       
  1173             for (TInt newLoop = 0; err == KErrNone && newLoop < *countPointer; newLoop++)
       
  1174                 {
       
  1175                 err = newInfos.Append(*info++);
       
  1176                 if (err != KErrNone)
       
  1177                     {
       
  1178                     ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - ERROR: newInfos.Append failure: %d, count: %d" ), err, newLoop ) );
       
  1179                     newInfos.Reset();
       
  1180                     }
       
  1181                 }
       
  1182             }
       
  1183 
       
  1184         // Free memory allocated by SSY mediator and set mediator's pointer to raw data to NULL
       
  1185         iProxyManager.ServerHeap()->Free(*rawDataPtr);
       
  1186         *rawDataPtr = NULL;
       
  1187         }
       
  1188     else
       
  1189         {
       
  1190         COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - No channels registered by SSY" ) ) );
       
  1191         }
       
  1192 
       
  1193 #ifdef COMPONENT_TRACE_DEBUG
       
  1194     COMPONENT_TRACE( ( _L( "### Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists, initial channel lists:" )) );
       
  1195 
       
  1196     COMPONENT_TRACE( ( _L( "### newInfos contents:" )) );
       
  1197     iProxyManager.TraceChannelInfoList(newInfos);
       
  1198 
       
  1199     COMPONENT_TRACE( ( _L( "### iChannelInfoList contents:" )) );
       
  1200     iProxyManager.TraceChannelInfoList(iChannelInfoList);
       
  1201 
       
  1202     COMPONENT_TRACE( ( _L( "### iRemovedChannelsInfoList contents:" )) );
       
  1203     iProxyManager.TraceChannelInfoList(iRemovedChannelsInfoList);
       
  1204 #endif
       
  1205 
       
  1206     // Compare old infos to new infos and notify removals to sessions,
       
  1207     // add removed infos to iRemovedChannelsInfoList,
       
  1208     // destroy CSensrvChannel objects of removed channelsm, and
       
  1209     // remove old infos from iChannelInfoList.
       
  1210     for (TInt oldLoop = iChannelInfoList.Count() - 1; err == KErrNone && oldLoop >= 0 ; oldLoop--)
       
  1211         {
       
  1212         // If match was not found, this channel has been removed
       
  1213         const TSensrvChannelInfo& oldInfo(iChannelInfoList[oldLoop]);
       
  1214         TInt index = FindChannel(newInfos, oldInfo);
       
  1215         if (index == KErrNotFound)
       
  1216             {
       
  1217             // Notify interested sessions
       
  1218             iProxyManager.NotifyChannelChange(oldInfo, ESensrvChannelChangeTypeRemoved);
       
  1219 
       
  1220             // Add info to removed infos.
       
  1221             err = iRemovedChannelsInfoList.Append(oldInfo);
       
  1222             if (err != KErrNone)
       
  1223                 {
       
  1224                 // Error is ignored as we cannot do anything about this. It results in channel id
       
  1225                 // being regenerated to this channel if it is readded later, which is inconvenient, but
       
  1226                 // not critical.
       
  1227                 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - ERROR: iRemovedChannelsInfoList.Append failure: %d, count: %d" ), err, oldLoop ) );
       
  1228                 }
       
  1229 
       
  1230             // Destroy and remove from channel list the related channel object as it is obsolete.
       
  1231             TInt channelCount = iChannelList.Count();
       
  1232             for(TInt i = 0; i < channelCount; i++)
       
  1233                 {
       
  1234                 if (iChannelList[i]->Id() == oldInfo.iChannelId)
       
  1235                     {
       
  1236                     delete iChannelList[i];
       
  1237                     iChannelList.Remove(i);
       
  1238                     break;
       
  1239                     }
       
  1240                 }
       
  1241 
       
  1242             // Remove channel info from iChannelInfoList
       
  1243             iChannelInfoList.Remove(oldLoop);
       
  1244             }
       
  1245         }
       
  1246 
       
  1247     // Compare new infos to old infos and notify additions to sessions,
       
  1248     // remove added infos from iRemovedChannelsInfoList if they are there, and
       
  1249     // append new infos to iChannelInfoList.
       
  1250     TInt newCount = newInfos.Count();
       
  1251     for (TInt newLoop = 0; err == KErrNone && newLoop < newCount; newLoop++)
       
  1252         {
       
  1253         const TSensrvChannelInfo& newInfo(newInfos[newLoop]);
       
  1254         TInt index = FindChannel(newInfo, iChannelInfoList);
       
  1255         if (index >= 0 && index < iChannelInfoList.Count())
       
  1256             {
       
  1257             // Update silently the actual data item size from SSY channel registration if still unset
       
  1258             TSensrvChannelInfo& oldInfo(iChannelInfoList[index]);
       
  1259             if (oldInfo.iDataItemSize <= 0 && newInfo.iDataItemSize > 0)
       
  1260                 {
       
  1261                 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - channel %d, new data item size: %d" ),
       
  1262                     oldInfo.iChannelId, newInfo.iDataItemSize ) );
       
  1263                 oldInfo.iDataItemSize = newInfo.iDataItemSize;
       
  1264                 }
       
  1265             }
       
  1266         else
       
  1267             {
       
  1268             TSensrvResourceChannelInfo newResourceInfo(newInfo);
       
  1269 
       
  1270             // Store dynamic channel status
       
  1271             newResourceInfo.iDynamic = FindChannel(newInfo, iDynamicChannelInfoList) != KErrNotFound; // Store dynamic status
       
  1272 
       
  1273             err = iChannelInfoList.Append(newResourceInfo);
       
  1274             if (err == KErrNone)
       
  1275                 {
       
  1276                 // Notify interested sessions
       
  1277                 iProxyManager.NotifyChannelChange(newInfo, ESensrvChannelChangeTypeAdded);
       
  1278 
       
  1279                 // Remove from iRemovedChannelsInfoList, in case there has been this channel previously
       
  1280                 index = FindChannel(newInfo, iRemovedChannelsInfoList);
       
  1281                 if(index >= 0 && index < iRemovedChannelsInfoList.Count())
       
  1282                     {
       
  1283                     iRemovedChannelsInfoList.Remove(index);
       
  1284                     }
       
  1285                 }
       
  1286             else
       
  1287                 {
       
  1288                 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - ERROR: iChannelInfoList.Append failure: %d, count: %d" ), err, newLoop ) );
       
  1289                 }
       
  1290             }
       
  1291         }
       
  1292 
       
  1293     // Note: It might be slightly more efficient to simply reset the iChannelInfoList and
       
  1294     // repopulate it with newInfos content as opposed to explicit appends and removes
       
  1295     // above, but that would create a risk that iChannelInfoList was left empty in
       
  1296     // case append fails to allocate new memory. Since there is no way to resurrect
       
  1297     // proxy with no channels once it has been unloaded, this is not acceptable.
       
  1298 
       
  1299 #ifdef COMPONENT_TRACE_DEBUG
       
  1300     COMPONENT_TRACE( ( _L( "### " )) );
       
  1301     COMPONENT_TRACE( ( _L( "### Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists, after changes" )) );
       
  1302 
       
  1303     COMPONENT_TRACE( ( _L( "### iChannelInfoList contents (should be same as newInfos):" )) );
       
  1304     iProxyManager.TraceChannelInfoList(iChannelInfoList);
       
  1305 
       
  1306     COMPONENT_TRACE( ( _L( "### iRemovedChannelsInfoList contents (should have infos removed from iChannelInfoList added to it):" )) );
       
  1307     iProxyManager.TraceChannelInfoList(iRemovedChannelsInfoList);
       
  1308 #endif
       
  1309 
       
  1310     // Cleanup newinfos
       
  1311     newInfos.Close();
       
  1312 
       
  1313     if (iDeletionFlag)
       
  1314         {
       
  1315         // Cleanup bad proxy after its channels have been removed
       
  1316         CleanupPlugin();
       
  1317         }
       
  1318 
       
  1319     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - return: %d" ), err ) );
       
  1320 
       
  1321     return err;
       
  1322     }
       
  1323 
       
  1324 
       
  1325 // ---------------------------------------------------------------------------
       
  1326 // SSY thread main function.
       
  1327 // Creates new active scheduler and cleanup stack and installs those.
       
  1328 // Initializes SSY mediator.
       
  1329 // Starts the new active scheduler.
       
  1330 // ---------------------------------------------------------------------------
       
  1331 //
       
  1332 TInt CSensrvPluginProxy::SsyThreadFunction( TAny* aParameter )
       
  1333     {
       
  1334     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SsyThreadFunction(aParameter: 0x%x)" ), aParameter ) );
       
  1335 
       
  1336     if (!aParameter)
       
  1337         {
       
  1338         ERROR_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - ERROR: NULL proxy, cannot start thread." ) ) );
       
  1339         return KErrBadHandle;
       
  1340         }
       
  1341 
       
  1342     __UHEAP_MARK;
       
  1343 
       
  1344 #ifdef MEMORY_TRACE_DEBUG
       
  1345     // TRACE heap usage
       
  1346     TInt heapSize = User::Heap().Size();
       
  1347     TInt biggestBlock(0);
       
  1348     TInt heapAvail = User::Heap().Available(biggestBlock);
       
  1349     TInt used(heapSize-heapAvail);
       
  1350     MEMORY_TRACE( ( _L( "#### Sensor Server, SSY starting - HEAP: Size: %d, Available: %d, Used: %d" ), heapSize, heapAvail, used ) );
       
  1351 #endif
       
  1352 
       
  1353     CSensrvPluginProxy* proxy = static_cast<CSensrvPluginProxy*>(aParameter);
       
  1354 
       
  1355     TInt err(KErrNone);
       
  1356 
       
  1357     // Create new cleanup stack
       
  1358     CTrapCleanup* cleanup = CTrapCleanup::New();
       
  1359 
       
  1360     if ( cleanup )
       
  1361         {
       
  1362         // Create and install the active scheduler we need
       
  1363         CSensrvSsyActiveScheduler* scheduler = NULL;
       
  1364         TRAP(err, scheduler = CSensrvSsyActiveScheduler::NewL());
       
  1365 
       
  1366         if (err == KErrNone)
       
  1367             {
       
  1368             CActiveScheduler::Install( scheduler );
       
  1369 
       
  1370             proxy->Mutex().Wait();
       
  1371 
       
  1372             COMPONENT_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - Started thread for plugin UID: 0x%x" ), proxy->iImplementationUid.iUid) );
       
  1373 
       
  1374             // initialize SSY mediator
       
  1375             err = proxy->SsyMediator()->Initialize();
       
  1376 
       
  1377             if (err == KErrNone)
       
  1378                 {
       
  1379                 // Initial notify to server mediator via null transaction
       
  1380                 // Notifying NULL transaction cannot fail, so no error handling
       
  1381                 proxy->ServerMediator()->Notify(NULL);
       
  1382 
       
  1383                 proxy->Mutex().Signal();
       
  1384 
       
  1385                 COMPONENT_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - Starting scheduler" )) );
       
  1386 
       
  1387                 CActiveScheduler::Start();
       
  1388 
       
  1389                 COMPONENT_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - Scheduler stopped" )) );
       
  1390 
       
  1391                 // Signal final closure of ecom session for SSY thread
       
  1392                 REComSession::FinalClose();
       
  1393                 }
       
  1394             else
       
  1395                 {
       
  1396                 ERROR_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - ERROR: Failed to initialize SSY mediator, cannot start thread: %d." ),err ) );
       
  1397                 proxy->Mutex().Signal();
       
  1398                 }
       
  1399 
       
  1400             // Cleanup
       
  1401             delete scheduler;
       
  1402             scheduler = NULL;
       
  1403             }
       
  1404         else
       
  1405             {
       
  1406             ERROR_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - ERROR: Failed to create scheduler, cannot start thread: %d." ),err ) );
       
  1407             }
       
  1408 
       
  1409         delete cleanup;
       
  1410         cleanup = NULL;
       
  1411         }
       
  1412     else
       
  1413         {
       
  1414         ERROR_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - ERROR: No memory to create cleanup stack, cannot start thread." ) ) );
       
  1415         err = KErrNoMemory;
       
  1416         }
       
  1417 
       
  1418     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SsyThreadFunction - return" ) ) );
       
  1419 
       
  1420 #ifdef MEMORY_TRACE_DEBUG
       
  1421     // TRACE heap usage
       
  1422     heapSize = User::Heap().Size();
       
  1423     heapAvail = User::Heap().Available(biggestBlock);
       
  1424     TInt newUsed(heapSize-heapAvail);
       
  1425     MEMORY_TRACE( ( _L( "#### Sensor Server, SSY exit - HEAP: Size: %d, Available: %d, Used: %d, Change in used: %d" ), heapSize, heapAvail, newUsed, newUsed - used ) );
       
  1426 #endif
       
  1427 
       
  1428     __UHEAP_MARKEND;
       
  1429 
       
  1430     return err;
       
  1431     }
       
  1432 
       
  1433 // ---------------------------------------------------------------------------
       
  1434 // Cleanup item implementation for plugin initialization
       
  1435 // ---------------------------------------------------------------------------
       
  1436 //
       
  1437 void CSensrvPluginProxy::CleanupInitializePlugin( TAny* aAny )
       
  1438     {
       
  1439     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CleanupInitializePlugin()" ) ) );
       
  1440 
       
  1441     CSensrvPluginProxy* proxy = reinterpret_cast<CSensrvPluginProxy*>(aAny);
       
  1442 
       
  1443     if (proxy)
       
  1444         {
       
  1445         // Uninitialized RThread object also has valid handle to current thread
       
  1446         if (proxy->iSsyThread.Handle() && proxy->iSsyThread.Handle() != RThread().Handle())
       
  1447             {
       
  1448             proxy->iSsyThread.Terminate(KErrCancel);
       
  1449             proxy->iSsyThread.Close();
       
  1450             }
       
  1451 
       
  1452         // Clean up any pending channel open messages
       
  1453         proxy->iLoadWaitQueue->RemoveAll();
       
  1454         proxy->iPreviousSsyLoadFailed = ETrue;
       
  1455         proxy->Mutex().Signal();
       
  1456         }
       
  1457 
       
  1458     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CleanupInitializePlugin - return" ) ) );
       
  1459     }
       
  1460 
       
  1461 // ---------------------------------------------------------------------------
       
  1462 // Finds channel from info list that matches to given channel info
       
  1463 // ---------------------------------------------------------------------------
       
  1464 //
       
  1465 TInt CSensrvPluginProxy::FindChannel( const TSensrvChannelInfo& aChannelInfo,
       
  1466                                       const RSensrvResourceChannelInfoList& aChannelInfoList )
       
  1467     {
       
  1468     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::FindChannel (RSensrvResourceChannelInfoList)" ) ) );
       
  1469 
       
  1470     TInt index = aChannelInfoList.Find(aChannelInfo, TSensrvResourceChannelInfo::CompareFindMatch);
       
  1471 
       
  1472     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::FindChannel - index %d, return" ), index ) );
       
  1473 
       
  1474     return index;
       
  1475     }
       
  1476 
       
  1477 // ---------------------------------------------------------------------------
       
  1478 // Finds channel from info list that matches to given channel info
       
  1479 // ---------------------------------------------------------------------------
       
  1480 //
       
  1481 TInt CSensrvPluginProxy::FindChannel( const RSensrvChannelInfoList& aChannelInfoList,
       
  1482                                       const TSensrvChannelInfo& aChannelInfo )
       
  1483     {
       
  1484     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::FindChannel (RSensrvChannelInfoList) Reverse" ) ) );
       
  1485 
       
  1486     TInt index = aChannelInfoList.Find(aChannelInfo, TSensrvResourceChannelInfo::CompareFindMatchReverse);
       
  1487 
       
  1488     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::FindChannel - index %d, return" ), index ) );
       
  1489 
       
  1490     return index;
       
  1491     }
       
  1492 
       
  1493 // ---------------------------------------------------------------------------
       
  1494 // Increments dynamic channel change listener count
       
  1495 // ---------------------------------------------------------------------------
       
  1496 //
       
  1497 void CSensrvPluginProxy::AddChannelChangeListener()
       
  1498     {
       
  1499     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::AddChannelChangeListener" ) ) );
       
  1500 
       
  1501     ++iChannelChangeListenerCount;
       
  1502     StopUnloadTimer();
       
  1503 
       
  1504     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::AddChannelChangeListener - count %d return " ),
       
  1505         iChannelChangeListenerCount ) );
       
  1506     }
       
  1507 
       
  1508 // ---------------------------------------------------------------------------
       
  1509 // Decrements dynamic channel change listener count
       
  1510 // ---------------------------------------------------------------------------
       
  1511 //
       
  1512 void CSensrvPluginProxy::RemoveChannelChangeListener()
       
  1513     {
       
  1514     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::RemoveChannelChangeListener" ) ) );
       
  1515 
       
  1516     if (iChannelChangeListenerCount > 0)
       
  1517         {
       
  1518         --iChannelChangeListenerCount;
       
  1519         if (!iChannelChangeListenerCount)
       
  1520             {
       
  1521             StartUnloadTimerIfNeeded();
       
  1522             }
       
  1523         }
       
  1524     else
       
  1525         {
       
  1526         ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::RemoveChannelChangeListener - ERROR: count corrupt" ) ) );
       
  1527         }
       
  1528 
       
  1529     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::RemoveChannelChangeListener - count %d return " ),
       
  1530         iChannelChangeListenerCount ) );
       
  1531     }
       
  1532 
       
  1533 // ---------------------------------------------------------------------------
       
  1534 // Enqueues delayed initialize transaction
       
  1535 // ---------------------------------------------------------------------------
       
  1536 //
       
  1537 TInt CSensrvPluginProxy::EnqueueDelayedInitializeTransaction()
       
  1538     {
       
  1539     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::EnqueueDelayedInitializeTransaction" ) ) );
       
  1540 
       
  1541     TInt err = KErrNone;
       
  1542 
       
  1543     // Enqueue initialization transaction if queue is empty.
       
  1544     if (iLoadWaitQueue->IsEmpty())
       
  1545         {
       
  1546         CSensrvTransaction* transaction = NULL;
       
  1547         TRAP(err, transaction = CSensrvTransaction::NewL(
       
  1548             NULL, this, NULL, CSensrvTransaction::ETransTypeDelayedInitialize));
       
  1549         if (err == KErrNone)
       
  1550             {
       
  1551             err = QueueTransaction(transaction, EFalse);
       
  1552             if (err != KErrNone)
       
  1553                 {
       
  1554                 delete transaction;
       
  1555                 transaction = NULL;
       
  1556                 }
       
  1557             }
       
  1558         else
       
  1559             {
       
  1560             ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::EnqueueDelayedInitializeTransaction - ERROR: Failed to create transaction err: %d" ), err ) );
       
  1561             }
       
  1562         }
       
  1563 
       
  1564     COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::EnqueueDelayedInitializeTransaction - return" ) ) );
       
  1565 
       
  1566     return err;
       
  1567     }