ncdengine/engine/src/catalogsclientserverserver.cpp
changeset 0 ba25891c3a9e
child 25 7333d7932ef7
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2006 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:   Implementation of CCatalogsClientServerServer
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "catalogsclientserverserver.h"
       
    20 #include "catalogsclientserverserversession.h"
       
    21 #include "catalogsserverdefines.h"
       
    22 #include "catalogsserverengine.h"
       
    23 #include "catalogscontext.h"
       
    24 
       
    25 #include "catalogsdebug.h"
       
    26 
       
    27 CCatalogsClientServerServer* CCatalogsClientServerServer::iCatalogsServer = NULL;
       
    28 
       
    29 // Replaced with USE_BUILD_SCRIPT when using build script
       
    30 #define DUMMY_DEFINE
       
    31 
       
    32 #ifdef CATALOGS_UNDERTAKER
       
    33 #ifdef USE_BUILD_SCRIPT
       
    34 _LIT( KCatalogsUndertakerFilename, "ncdundertaker_APP_NAME_POSTFIX" );
       
    35 #else
       
    36 _LIT( KCatalogsUndertakerFilename, "ncdundertaker_20019119" );
       
    37 #endif // USE_BUILD_SCRIPT
       
    38 #endif
       
    39 
       
    40 // Capability set required from clients. Consists of CAP_APPLICATION capability set.
       
    41 static _LIT_SECURITY_POLICY_C7(
       
    42     KCatalogsServerConnectPolicy1,
       
    43     ECapabilityNetworkServices,
       
    44     ECapabilityLocalServices,
       
    45     ECapabilityLocation,
       
    46     ECapabilityReadUserData,
       
    47     ECapabilityWriteUserData,
       
    48     ECapabilityReadDeviceData,
       
    49     ECapabilityWriteDeviceData );
       
    50     
       
    51 static _LIT_SECURITY_POLICY_C2(
       
    52     KCatalogsServerConnectPolicy2,
       
    53     ECapabilitySwEvent,
       
    54     ECapabilityUserEnvironment );
       
    55 
       
    56 // ======== MEMBER FUNCTIONS ========
       
    57 
       
    58 
       
    59 // ---------------------------------------------------------------------------
       
    60 // 
       
    61 // ---------------------------------------------------------------------------
       
    62 // 
       
    63 CCatalogsClientServerServer* CCatalogsClientServerServer::NewLC()
       
    64     {
       
    65     CCatalogsClientServerServer* self = new( ELeave )
       
    66         CCatalogsClientServerServer( CActive::EPriorityLow - 20 );
       
    67     CleanupStack::PushL( self );
       
    68     self->ConstructL();
       
    69     return self;
       
    70     }
       
    71 
       
    72 // ---------------------------------------------------------------------------
       
    73 // 
       
    74 // ---------------------------------------------------------------------------
       
    75 // 
       
    76 CCatalogsClientServerServer::CCatalogsClientServerServer( TInt aPriority ) :
       
    77     CServer2( aPriority )
       
    78     {
       
    79     iCatalogsServer = this;
       
    80     }
       
    81 
       
    82 // ---------------------------------------------------------------------------
       
    83 // 
       
    84 // ---------------------------------------------------------------------------
       
    85 // 
       
    86 CCatalogsClientServerServer::~CCatalogsClientServerServer()
       
    87     {
       
    88     DLTRACEIN((""));
       
    89     // Usually at this point all sessions are already destroyed.
       
    90     // If not, we have to go through all sessions and destroy
       
    91     // all references to the objects to which references might be lost
       
    92     // if the engine was destroyed first.
       
    93     // Also when doing it this way when the engine is destroyed,
       
    94     // provider can do the final killing of those objects
       
    95     iSessionIter.SetToFirst();
       
    96     CSession2* baseSession = NULL;
       
    97     CCatalogsClientServerServerSession* session = NULL;
       
    98     baseSession = iSessionIter++;
       
    99     while ( baseSession != NULL )
       
   100         {
       
   101         DLTRACE(("Calling ClientSideSessionDown"));
       
   102         // When going down, act as the client side would have died
       
   103         // ->call ClientSideSessionDown for each session
       
   104         session = 
       
   105             static_cast<CCatalogsClientServerServerSession*>( baseSession );
       
   106         session->ClientSideSessionDown();
       
   107         baseSession = iSessionIter++;
       
   108         DLTRACE(("ClientSideSessionDown called"));
       
   109         }
       
   110     
       
   111     DLTRACE(("Delete engine"));
       
   112     // This is destroyed before destroying container, so possible
       
   113     // resources are freed in its destructor and from the container 
       
   114     // in here.
       
   115     // Other way would end up destroying already destroyed stuff.
       
   116     delete iEngine;
       
   117 
       
   118     DLTRACE(("Engine deleted"));
       
   119     iShutdownOperations.ResetAndDestroy();
       
   120     
       
   121     // If container is going to be removed, it has to be done before
       
   122     // it is destroyed by destroying the container index.
       
   123     if ( iContainer != NULL )
       
   124         {
       
   125         DLTRACE(("Remove container"));
       
   126         RemoveContainer( iContainer );        
       
   127         DLTRACE(("Container removed"));
       
   128         }
       
   129     iContainer = NULL;
       
   130     
       
   131     DLTRACE(("Deleting container index"));
       
   132     delete iContainerIndex;
       
   133 
       
   134 #ifdef CATALOGS_UNDERTAKER
       
   135 
       
   136     iUndertakerProcess.Close();
       
   137 
       
   138 #endif 
       
   139 
       
   140     DLTRACEOUT((""));
       
   141     }
       
   142 
       
   143 
       
   144 // ---------------------------------------------------------------------------
       
   145 // 
       
   146 // ---------------------------------------------------------------------------
       
   147 // 
       
   148 void CCatalogsClientServerServer::ConstructL()
       
   149     {
       
   150     DLTRACEIN((""));
       
   151     User::LeaveIfError( User::RenameThread( KCatalogsServerName ) );
       
   152 #ifdef CATALOGS_UNDERTAKER
       
   153 
       
   154     DLINFO(( "Creating undertaker process" ));
       
   155     TInt err = iUndertakerProcess.Create( KCatalogsUndertakerFilename, KNullDesC() );
       
   156     if( err != KErrNone )
       
   157         {
       
   158         DLERROR(( "Creating undertaker process failed with %d", err ));
       
   159         }
       
   160     iUndertakerProcess.SetPriority( (TProcessPriority)450 );  // EPriorityHigh
       
   161     
       
   162     RThread thisThread;
       
   163     DLINFO(( _L("Setting undertaker parameter 15 as %S"), &thisThread.FullName() ));
       
   164     
       
   165     err = iUndertakerProcess.SetParameter( 15, thisThread.FullName() );
       
   166     if( err != KErrNone )
       
   167         {
       
   168         DLERROR(( "Parameter setting failed with %d", err ));
       
   169         }
       
   170     thisThread.Close();
       
   171     iUndertakerProcess.Resume();
       
   172 
       
   173 #endif
       
   174 
       
   175     iContainerIndex = CObjectConIx::NewL();
       
   176     iContainer = NewContainerL();
       
   177 
       
   178 	iEngine = CCatalogsServerEngine::NewL();
       
   179     // Add the server to the active scheduler
       
   180     StartL( KCatalogsServerName );
       
   181     DLTRACEOUT((""));
       
   182     }
       
   183 
       
   184 // ---------------------------------------------------------------------------
       
   185 // 
       
   186 // ---------------------------------------------------------------------------
       
   187 // 
       
   188 void CCatalogsClientServerServer::IncrementSessions()
       
   189     {
       
   190     iSessionCount++;
       
   191     }
       
   192 
       
   193 // ---------------------------------------------------------------------------
       
   194 // 
       
   195 // ---------------------------------------------------------------------------
       
   196 // 
       
   197 void CCatalogsClientServerServer::DecrementSessions()
       
   198     {
       
   199     iSessionCount--;
       
   200 
       
   201     // No more clients, shutdown
       
   202     if ( iSessionCount <= 0 )
       
   203         {
       
   204         CActiveScheduler::Stop();
       
   205         }
       
   206     }
       
   207     
       
   208 // ---------------------------------------------------------------------------
       
   209 // 
       
   210 // ---------------------------------------------------------------------------
       
   211 // 
       
   212 void CCatalogsClientServerServer::HandleSessionRemoval( 
       
   213     MCatalogsSession& aSession )
       
   214     {
       
   215     DASSERT( iEngine );
       
   216     
       
   217     // We don't want to go further unless the context has been created
       
   218     if ( aSession.ContextPtr() )
       
   219         {
       
   220         iEngine->HandleSessionRemoval( aSession );
       
   221         // Execute shutdown operations
       
   222         OperateShutdownOperations( aSession.Context(), ETrue );
       
   223         }
       
   224     }
       
   225 
       
   226 // ---------------------------------------------------------------------------
       
   227 // 
       
   228 // ---------------------------------------------------------------------------
       
   229 // 
       
   230 CObjectCon* CCatalogsClientServerServer::NewContainerL()
       
   231 	{
       
   232     // Return a new object container
       
   233 	return iContainerIndex->CreateL();
       
   234 	}
       
   235 
       
   236 // ---------------------------------------------------------------------------
       
   237 // 
       
   238 // ---------------------------------------------------------------------------
       
   239 // 
       
   240 void CCatalogsClientServerServer::RemoveContainer( CObjectCon* aCon )
       
   241 	{
       
   242 	DASSERT( iContainerIndex );
       
   243 	iContainerIndex->Remove( aCon );
       
   244 	}
       
   245 
       
   246 // ---------------------------------------------------------------------------
       
   247 // 
       
   248 // ---------------------------------------------------------------------------
       
   249 // 
       
   250 void CCatalogsClientServerServer::CreateProviderL( 
       
   251     MCatalogsSession& aSession, 
       
   252     TInt aProviderIdentifier,
       
   253     TInt& aHandle,
       
   254     TUint32 aProviderOptions )
       
   255     {
       
   256     DLTRACEIN((""));
       
   257     
       
   258     iEngine->CreateProviderL( aSession,
       
   259                               aProviderIdentifier, 
       
   260                               aHandle,
       
   261                               aProviderOptions );
       
   262 
       
   263     }
       
   264 
       
   265 // ---------------------------------------------------------------------------
       
   266 // 
       
   267 // ---------------------------------------------------------------------------
       
   268 // 
       
   269 TInt CCatalogsClientServerServer::NewInstanceId()
       
   270     {
       
   271     DLTRACEIN((""));
       
   272     return iSessionInstanceIdCounter++;
       
   273     }
       
   274 
       
   275 // ---------------------------------------------------------------------------
       
   276 // 
       
   277 // ---------------------------------------------------------------------------
       
   278 // 
       
   279 void CCatalogsClientServerServer::AddObjectToContainerL( CObject* aObject )
       
   280     {    
       
   281     // If possible, change trap-implementation to something else.
       
   282     // This is just a simple way to do this.
       
   283     TRAPD( err, iContainer->AddL( aObject ) );
       
   284     DLTRACE(("err: %d", err ));
       
   285     if ( err == KErrAlreadyExists || err == KErrNone )
       
   286         {        
       
   287         return;
       
   288         }
       
   289     else
       
   290         {
       
   291         User::Leave( err );
       
   292         }
       
   293     }
       
   294 
       
   295 // ---------------------------------------------------------------------------
       
   296 // 
       
   297 // ---------------------------------------------------------------------------
       
   298 // 
       
   299 void CCatalogsClientServerServer::ThreadFunctionL()
       
   300     {
       
   301     DLTRACEIN((""));
       
   302     DCHECK_HEAP
       
   303     // Construct an active scheduler for the server
       
   304 
       
   305     DLINFO(( "Creating active schduler" ));
       
   306     CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
       
   307     CleanupStack::PushL( activeScheduler );
       
   308 
       
   309     // Install active scheduler
       
   310     // No need to check whether an active scheduler is already installed
       
   311     // as this is a new thread, so there won't be one
       
   312     DLINFO(( "Installing active schduler" ));
       
   313     CActiveScheduler::Install( activeScheduler );
       
   314 
       
   315     // Construct our server
       
   316     CCatalogsClientServerServer::NewLC(); // anonymous
       
   317 
       
   318     DLINFO(( "Opening semaphore" ));
       
   319     RSemaphore semaphore;
       
   320     User::LeaveIfError(
       
   321         semaphore.OpenGlobal( KCatalogsServerSemaphoreName ));
       
   322     
       
   323     DLINFO(( "Signalling and closing semaphore" ));
       
   324     // Semaphore opened ok
       
   325     semaphore.Signal();
       
   326     semaphore.Close();
       
   327 
       
   328     // Start handling requests, operation will stop here until
       
   329     // the server dies
       
   330     CActiveScheduler::Start();
       
   331 
       
   332     DLINFO(("Server has shut down"));
       
   333 
       
   334     // The server has been shut down, clean up
       
   335     CleanupStack::PopAndDestroy( 2, activeScheduler );
       
   336     DLTRACEOUT((""));
       
   337     }
       
   338 
       
   339 // ---------------------------------------------------------------------------
       
   340 // 
       
   341 // ---------------------------------------------------------------------------
       
   342 // 
       
   343 TInt CCatalogsClientServerServer::ThreadFunction( TAny* /*aNone*/ )
       
   344     {
       
   345 #ifdef CATALOGS_BUILD_CONFIG_HEAP_MARKS    
       
   346     __UHEAP_MARK;
       
   347 #endif    
       
   348     DLINIT;
       
   349     
       
   350     DLTRACEIN((""));
       
   351     
       
   352     CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
   353     TRAPD( err, ThreadFunctionL() );
       
   354     
       
   355     DLTRACE(( "err: %d", err ));
       
   356     delete cleanupStack;
       
   357     cleanupStack = NULL;
       
   358     
       
   359     DLTRACEOUT((""));
       
   360 
       
   361     DLUNINIT;
       
   362 #ifdef CATALOGS_BUILD_CONFIG_HEAP_MARKS    
       
   363     __UHEAP_MARKEND; 
       
   364 #endif    
       
   365     return err;    
       
   366     }
       
   367 
       
   368 // ---------------------------------------------------------------------------
       
   369 // 
       
   370 // ---------------------------------------------------------------------------
       
   371 // 
       
   372 TInt CCatalogsClientServerServer::RunError( TInt aError )
       
   373     {
       
   374     DLTRACEIN(( "aError=%d", aError ));    
       
   375 
       
   376     // Complete the message being processed, although the state of
       
   377     // the server is undetermined
       
   378     DLERROR(( "Completing last message with %d", aError ));
       
   379     Message().Complete( aError );
       
   380 
       
   381     DLTRACEOUT(("KErrNone"));
       
   382     return KErrNone;
       
   383     }
       
   384 
       
   385 // ---------------------------------------------------------------------------
       
   386 // 
       
   387 // ---------------------------------------------------------------------------
       
   388 // 
       
   389 CSession2* CCatalogsClientServerServer::NewSessionL( 
       
   390     const TVersion& aVersion,
       
   391     const RMessage2& aMsg ) const
       
   392     {
       
   393     DLTRACEIN((""));
       
   394         
       
   395     // Check whether the server is compatible with the 
       
   396     // requested version
       
   397     if ( !User::QueryVersionSupported(
       
   398            TVersion(
       
   399                KCatalogsServerMajorVersionNumber,
       
   400                KCatalogsServerMinorVersionNumber,
       
   401                KCatalogsServerBuildVersionNumber
       
   402                ),
       
   403            aVersion))
       
   404         {        
       
   405         User::Leave( KErrNotSupported );
       
   406         }
       
   407 
       
   408     DLINFO(("Checking client capabilities"));
       
   409     // Check the client for required capabilities
       
   410     if (!KCatalogsServerConnectPolicy1().CheckPolicy(
       
   411         aMsg, __PLATSEC_DIAGNOSTIC_STRING("CCatalogsClientServerServer::NewSessionL, KCatalogsServerConnectPolicy1") ) ||
       
   412         !KCatalogsServerConnectPolicy2().CheckPolicy(
       
   413         aMsg, __PLATSEC_DIAGNOSTIC_STRING("CCatalogsClientServerServer::NewSessionL, KCatalogsServerConnectPolicy2" ) ) )
       
   414         {
       
   415         DLINFO(("Client capability check failed"));
       
   416         User::Leave( KErrPermissionDenied );
       
   417         }
       
   418 
       
   419     // Context is not created here for the session, because
       
   420     // user given uid cannot be received by this function from
       
   421     // the client-side and it is nicer to create the whole
       
   422     // context-object in one place.
       
   423 
       
   424     DLTRACEOUT((""));
       
   425         
       
   426     // Create a new session
       
   427     RThread client;
       
   428     return CCatalogsClientServerServerSession::NewL(
       
   429         client,
       
   430         *const_cast<CCatalogsClientServerServer*>( this ) );
       
   431     }
       
   432 
       
   433 
       
   434 /**
       
   435  * Platform dependant entry points
       
   436  */
       
   437 
       
   438 IMPORT_C TInt WinsMain();
       
   439 EXPORT_C TInt WinsMain()
       
   440 	{
       
   441 	// WINS DLL entry-point. Just return the real thread function 
       
   442     // cast to TInt
       
   443 	return reinterpret_cast<TInt>( 
       
   444 	    &CCatalogsClientServerServer::ThreadFunction );
       
   445 	}
       
   446 
       
   447 // ---------------------------------------------------------------------------
       
   448 // 
       
   449 // ---------------------------------------------------------------------------
       
   450 // 
       
   451 GLDEF_C TInt E32Main()
       
   452     {
       
   453     return CCatalogsClientServerServer::ThreadFunction( NULL );
       
   454     }
       
   455 
       
   456 
       
   457 // ---------------------------------------------------------------------------
       
   458 // 
       
   459 // ---------------------------------------------------------------------------
       
   460 // 
       
   461 TInt CCatalogsClientServerServer::AddShutdownOperation( 
       
   462     CCatalogsShutdownOperation* aOperation )
       
   463     {
       
   464     DLTRACEIN((""))
       
   465     DASSERT( aOperation );
       
   466     TInt err = iCatalogsServer->iShutdownOperations.Append( aOperation );
       
   467 
       
   468     if ( err == KErrNone )
       
   469         {
       
   470         aOperation->SetObserver( *iCatalogsServer );
       
   471         iCatalogsServer->IncrementSessions();
       
   472         }
       
   473     else
       
   474         {
       
   475         DLERROR(("Appending failed: %d", err));
       
   476         delete aOperation;
       
   477         }
       
   478     
       
   479     return err;    
       
   480     }
       
   481 
       
   482 
       
   483 // ---------------------------------------------------------------------------
       
   484 // 
       
   485 // ---------------------------------------------------------------------------
       
   486 // 
       
   487 void CCatalogsClientServerServer::ShutdownOperationComplete( 
       
   488     CCatalogsShutdownOperation* aOperation, 
       
   489     TInt aError )
       
   490     {
       
   491     DLTRACEIN(("aError: %d", aError));
       
   492     (void) aError;
       
   493     iShutdownOperations.Remove( iShutdownOperations.Find( aOperation ) );
       
   494     delete aOperation;
       
   495     DecrementSessions();
       
   496     }
       
   497 
       
   498 
       
   499 // ---------------------------------------------------------------------------
       
   500 // 
       
   501 // ---------------------------------------------------------------------------
       
   502 // 
       
   503 void CCatalogsClientServerServer::OperateShutdownOperations( 
       
   504     const MCatalogsContext& aContext,
       
   505     TBool aExecute )
       
   506     {
       
   507     DLTRACEIN((""));
       
   508     TInt count = iShutdownOperations.Count();
       
   509     const TUid uid( aContext.FamilyId() );
       
   510     // Iterating backwards because an executed operation may be removed
       
   511     // from the queue while we are iterating through it
       
   512     while( count-- )
       
   513         {
       
   514         if ( iShutdownOperations[ count ]->FamilyUid() == uid ) 
       
   515             {
       
   516             if ( aExecute )
       
   517                 {
       
   518                 iShutdownOperations[ count ]->Execute();
       
   519                 }
       
   520             else
       
   521                 {
       
   522                 iShutdownOperations[ count ]->Cancel();
       
   523                 }
       
   524             }
       
   525         }
       
   526     }