ncdengine/engine/src/catalogsengineimpl.cpp
changeset 0 ba25891c3a9e
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:   Contains CCatalogsEngineImpl class implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <e32property.h>
       
    21 #include <e32msgqueue.h>
       
    22 #include <s32mem.h>
       
    23 
       
    24 #include "catalogspanics.h"
       
    25 #include "catalogsengineimpl.h"
       
    26 #include "ncdproviderproxy.h"
       
    27 #include "catalogsdebug.h"
       
    28 #include "catalogsengineobserver.h"
       
    29 #include "catalogsconstants.h"
       
    30 #include "catalogsuids.h"
       
    31 #include "catalogsconnectionobserver.h"
       
    32 
       
    33 
       
    34 class CCatalogsProviderCreator : public CActive
       
    35     {
       
    36 public:
       
    37 
       
    38     static CCatalogsProviderCreator* NewL( 
       
    39         RCatalogsClientServerClientSession& aEngine, 
       
    40         TInt aUid, 
       
    41         MCatalogsBase*& aProvider, 
       
    42         TRequestStatus& aStatus,
       
    43         TUint32 aOptions );
       
    44 
       
    45     MCatalogsBase* Provider() const;
       
    46 
       
    47     ~CCatalogsProviderCreator();
       
    48 
       
    49 protected:
       
    50 
       
    51     CCatalogsProviderCreator( 
       
    52         RCatalogsClientServerClientSession& aEngine, 
       
    53         MCatalogsBase*& aProvider, 
       
    54         TRequestStatus& aStatus );
       
    55     
       
    56     void ConstructL( TInt aUid, TUint32 aOptions );
       
    57 
       
    58     void RunL();
       
    59     void DoCancel();
       
    60     TInt RunError( TInt aError );
       
    61 
       
    62     /**
       
    63      * Provider handle
       
    64      */
       
    65     TInt iHandle;
       
    66 
       
    67     /**
       
    68      * Proxy provider.
       
    69      * Own.
       
    70      */
       
    71     CNcdProviderProxy* iProviderProxy;
       
    72 
       
    73     /**
       
    74      * Engine.
       
    75      */
       
    76     RCatalogsClientServerClientSession& iEngine;
       
    77 
       
    78     /**
       
    79      * Proxy provider result.
       
    80      */
       
    81     MCatalogsBase*& iResultProvider;
       
    82 
       
    83     /**
       
    84      * Proxy provider request status.
       
    85      */
       
    86     TRequestStatus* iResultStatus;
       
    87 
       
    88     };
       
    89 
       
    90 CCatalogsProviderCreator* CCatalogsProviderCreator::NewL( 
       
    91     RCatalogsClientServerClientSession& aEngine, 
       
    92     TInt aUid, 
       
    93     MCatalogsBase*& aProvider, 
       
    94     TRequestStatus& aStatus,
       
    95     TUint32 aOptions )
       
    96     {
       
    97     DLTRACEIN(( "aEngine=%08x, aUid=%08x, aProvider=%08x, aStatus=%08x, aOptions=%u", 
       
    98         &aEngine, aUid, &aProvider, &aStatus, aOptions ));
       
    99     
       
   100     CCatalogsProviderCreator* self = new (ELeave) CCatalogsProviderCreator( 
       
   101         aEngine, aProvider, aStatus );
       
   102     CleanupStack::PushL( self );
       
   103     self->ConstructL( aUid, aOptions );
       
   104     CleanupStack::Pop( self );
       
   105 
       
   106     DLTRACEOUT(( "%08x", self ));
       
   107     return self;
       
   108     }
       
   109 
       
   110 void CCatalogsProviderCreator::ConstructL( TInt aUid, TUint32 aOptions )
       
   111     {
       
   112     DLTRACEIN(("aUid=%08x", aUid ));
       
   113 
       
   114     switch( aUid )
       
   115         {
       
   116         // Instantiate a provider based on UID information
       
   117         case 0:
       
   118         default:
       
   119             {
       
   120             iEngine.CreateProvider( aUid, iStatus, iHandle, aOptions );
       
   121             SetActive();            
       
   122             DASSERT( iStatus.Int() == KRequestPending );
       
   123             }
       
   124             break;
       
   125         }
       
   126 
       
   127     DLTRACEOUT((""));
       
   128     }
       
   129 
       
   130 CCatalogsProviderCreator::~CCatalogsProviderCreator()
       
   131     {
       
   132     DLTRACEIN((""));
       
   133     
       
   134     // Never hurts to call this in destructor of active objects
       
   135     Cancel();
       
   136 
       
   137     if( iProviderProxy )
       
   138         {
       
   139         DLTRACE(("Release providerproxy internally"));
       
   140         iProviderProxy->InternalRelease();
       
   141         }
       
   142         
       
   143     DLTRACEOUT((""));    
       
   144     }
       
   145 
       
   146 MCatalogsBase* CCatalogsProviderCreator::Provider() const
       
   147     {
       
   148     return iProviderProxy;
       
   149     }
       
   150 
       
   151 CCatalogsProviderCreator::CCatalogsProviderCreator(
       
   152     RCatalogsClientServerClientSession& aEngine, MCatalogsBase*& aProvider, TRequestStatus& aStatus )
       
   153     : CActive( EPriorityNormal ), iEngine( aEngine ), iResultProvider( aProvider ), iResultStatus( &aStatus )
       
   154     {
       
   155     CActiveScheduler::Add( this );
       
   156     *iResultStatus = KRequestPending;
       
   157     }
       
   158 
       
   159 void CCatalogsProviderCreator::RunL()
       
   160     {
       
   161     DLTRACEIN(( "iStatus=%08x, iHandle=%08x", iStatus.Int(), iHandle ));
       
   162     // Provider creation can succeed with positive codes
       
   163     if ( iStatus.Int() >= KErrNone )
       
   164         {
       
   165         DLINFO(( "Creating provider proxy" ));
       
   166         // If the provider was successfully created, instantiate a 
       
   167         // client-side provider object
       
   168         iProviderProxy = CNcdProviderProxy::NewL( iEngine, iHandle );
       
   169         DLTRACE(("Provider proxy inc ref count"));
       
   170         // Increase both reference counters
       
   171         iProviderProxy->InternalAddRef();
       
   172         iProviderProxy->AddRef();
       
   173         DLINFO(( "Provider proxy %08x created", iProviderProxy ));
       
   174         
       
   175         // We will probably never end up here if the request has been
       
   176         // completed already, but checking just to be sure.
       
   177         if ( iResultStatus )
       
   178             {
       
   179             DLINFO(( "Completing CreateProvider request" ));            
       
   180             iResultProvider = iProviderProxy;
       
   181 
       
   182             // iResultStatus is nullified by the RequestComplete
       
   183             User::RequestComplete( iResultStatus, iStatus.Int() );
       
   184             }
       
   185         }
       
   186     else 
       
   187         {
       
   188         // We will probably never end up here if the request has been
       
   189         // completed already, but checking just to be sure.
       
   190         if ( iResultStatus )
       
   191             {        
       
   192             User::RequestComplete( iResultStatus, iStatus.Int() );             
       
   193             }
       
   194         }
       
   195     DLTRACEOUT((""));
       
   196     }
       
   197 
       
   198 void CCatalogsProviderCreator::DoCancel()
       
   199     {
       
   200     DLTRACEIN((""));
       
   201     // Going down now, so pending message sent by provider creator
       
   202     // should be completed immediately by client server 
       
   203     //(or it is completed by the framework if the message is already
       
   204     // completed but creator is not yet notified of it)
       
   205     iEngine.AsyncMessageSenderDown( iStatus );
       
   206     
       
   207     // Pending request is completed.
       
   208     // We should never end up here if the request is already
       
   209     // completed, but just checking to be sure.
       
   210     if ( iResultStatus )
       
   211         {
       
   212         // iResultStatus is nullified by the RequestComplete
       
   213         User::RequestComplete( iResultStatus, KErrCancel );
       
   214         }
       
   215     
       
   216     DLTRACEOUT((""));
       
   217     }
       
   218 
       
   219 TInt CCatalogsProviderCreator::RunError( TInt aError )
       
   220     {
       
   221     DLTRACEIN((""));
       
   222 
       
   223     User::RequestComplete( iResultStatus, aError );
       
   224 
       
   225     DLTRACEOUT((""));
       
   226     return KErrNone;
       
   227     }
       
   228 
       
   229 
       
   230 /** Catalogs shutdown observer, subscribes to maintenance lock P&S */
       
   231 
       
   232 class CCatalogsShutdownObserver : public CActive
       
   233     {
       
   234 public:
       
   235 
       
   236     static CCatalogsShutdownObserver* NewL( MCatalogsEngineObserver& aObserver );
       
   237     virtual ~CCatalogsShutdownObserver();
       
   238 
       
   239 protected:
       
   240 
       
   241     CCatalogsShutdownObserver( MCatalogsEngineObserver& aObserver );
       
   242     void ConstructL();
       
   243 
       
   244 protected: // from CActive
       
   245 
       
   246     void RunL();
       
   247     void DoCancel();
       
   248 
       
   249 private:
       
   250 
       
   251     RProperty                   iMaintenanceLockProperty;
       
   252     MCatalogsEngineObserver&    iObserver;
       
   253     };
       
   254 
       
   255 
       
   256 CCatalogsShutdownObserver* CCatalogsShutdownObserver::NewL( MCatalogsEngineObserver& aObserver )
       
   257     {
       
   258     DLTRACEIN(( "aObserver=%08x", &aObserver ));
       
   259     CCatalogsShutdownObserver* self = new (ELeave) CCatalogsShutdownObserver( aObserver );
       
   260     CleanupStack::PushL( self );
       
   261     self->ConstructL();
       
   262     CleanupStack::Pop( self );
       
   263     return self;
       
   264     }
       
   265 
       
   266 CCatalogsShutdownObserver::~CCatalogsShutdownObserver()
       
   267     {
       
   268     DLTRACEIN(("this=%08x", this));
       
   269     Cancel();
       
   270     iMaintenanceLockProperty.Close();
       
   271 
       
   272     DLTRACEOUT((""));
       
   273     }
       
   274 
       
   275 CCatalogsShutdownObserver::CCatalogsShutdownObserver( MCatalogsEngineObserver& aObserver )
       
   276     : CActive( EPriorityNormal ), iObserver( aObserver )
       
   277     {
       
   278     CActiveScheduler::Add( this );
       
   279     }
       
   280 
       
   281 void CCatalogsShutdownObserver::ConstructL()
       
   282     {
       
   283     DLTRACEIN((""));
       
   284 
       
   285     // Subscribe to maintenance notify property.
       
   286     User::LeaveIfError( iMaintenanceLockProperty.Attach( 
       
   287         KCatalogsEnginePropertyCategory, 
       
   288         KCatalogsEnginePropertyKeyMaintenanceLock ) );
       
   289 
       
   290     iMaintenanceLockProperty.Subscribe( iStatus );
       
   291     SetActive();
       
   292 
       
   293     DLTRACEOUT((""));
       
   294     }
       
   295 
       
   296 void CCatalogsShutdownObserver::RunL()
       
   297     {
       
   298     DLTRACEIN(( "iStatus=%d", iStatus.Int() ));
       
   299 
       
   300     if( iStatus.Int() == KErrNone )
       
   301         {
       
   302         // Read the property value.
       
   303         TInt value;
       
   304         TInt err = iMaintenanceLockProperty.Get( value );
       
   305         if( err == KErrNone && value != 0 )
       
   306             {
       
   307             DLINFO(( "Calling shutdown observer %08x", &iObserver ));
       
   308             iObserver.CatalogsEngineShutdown();
       
   309             }
       
   310 
       
   311         if( err != KErrNone )
       
   312             {
       
   313             DLERROR(( "Failed to read maintenance lock property value, error %d", err ));
       
   314             }
       
   315         else
       
   316             {
       
   317             DLINFO(( "Maintenance lock value was %d", value ));
       
   318             }
       
   319         }
       
   320 
       
   321     DLTRACEOUT((""));
       
   322     }
       
   323 
       
   324 void CCatalogsShutdownObserver::DoCancel()
       
   325     {
       
   326     DLTRACEIN((""));
       
   327     iMaintenanceLockProperty.Cancel();
       
   328     DLTRACEOUT((""));
       
   329     }
       
   330 
       
   331 
       
   332 /** Catalogs OTA update observer, subscribes to update information P&S */
       
   333 
       
   334 class CCatalogsUpdateObserver : public CActive
       
   335     {
       
   336 public:
       
   337 
       
   338     static CCatalogsUpdateObserver* NewL( MCatalogsEngineObserver& aObserver );
       
   339     virtual ~CCatalogsUpdateObserver();
       
   340 
       
   341 protected:
       
   342 
       
   343     CCatalogsUpdateObserver( MCatalogsEngineObserver& aObserver );
       
   344     void ConstructL();
       
   345 
       
   346 protected: // from CActive
       
   347 
       
   348     void RunL();
       
   349     void DoCancel();
       
   350 
       
   351 private:
       
   352 
       
   353     RMsgQueueBase               iUpdateMessageQueue;
       
   354     MCatalogsEngineObserver&    iObserver;
       
   355     };
       
   356 
       
   357 
       
   358 CCatalogsUpdateObserver* CCatalogsUpdateObserver::NewL( MCatalogsEngineObserver& aObserver )
       
   359     {
       
   360     DLTRACEIN(( "aObserver=%08x", &aObserver ));
       
   361     CCatalogsUpdateObserver* self = new (ELeave) CCatalogsUpdateObserver( aObserver );
       
   362     CleanupStack::PushL( self );
       
   363     self->ConstructL();
       
   364     CleanupStack::Pop( self );
       
   365     return self;
       
   366     }
       
   367 
       
   368 CCatalogsUpdateObserver::~CCatalogsUpdateObserver()
       
   369     {
       
   370     DLTRACEIN(("this=%08x", this));
       
   371     Cancel();
       
   372     iUpdateMessageQueue.Close();
       
   373     DLTRACEOUT((""));
       
   374     }
       
   375 
       
   376 CCatalogsUpdateObserver::CCatalogsUpdateObserver( MCatalogsEngineObserver& aObserver )
       
   377     : CActive( EPriorityNormal ), iObserver( aObserver )
       
   378     {
       
   379     CActiveScheduler::Add( this );
       
   380     }
       
   381 
       
   382 void CCatalogsUpdateObserver::ConstructL()
       
   383     {
       
   384     DLTRACEIN((""));
       
   385 
       
   386     // Create the update information message queue for receiving update messages.
       
   387     RProcess process;
       
   388     DLINFO(( "Client SSID %08x", process.SecureId().iId ));
       
   389 
       
   390 	HBufC* msgQueueName = HBufC::NewLC( KCatalogsUpdateQueueNameFormat().Length() + 8 );
       
   391 	msgQueueName->Des().Format( KCatalogsUpdateQueueNameFormat, process.SecureId().iId );
       
   392 	
       
   393 	DLINFO(( _L("Creating client's update message queue: %S"), msgQueueName ));
       
   394 	TInt err = iUpdateMessageQueue.CreateGlobal( 
       
   395 	    *msgQueueName, 
       
   396 	    KCatalogsUpdateQueueSlotCount, 
       
   397 	    KCatalogsUpdateQueueMessageSize, 
       
   398 	    EOwnerProcess );
       
   399 	
       
   400 	if( err == KErrAlreadyExists )
       
   401 	    {
       
   402         err = iUpdateMessageQueue.OpenGlobal( *msgQueueName );
       
   403 	    }
       
   404 	
       
   405 	if( err != KErrNone )
       
   406 	    {
       
   407 	    DLERROR(( "Failed to create update message queue, error %d", err ));
       
   408 	    }
       
   409 	else
       
   410 	    {
       
   411     	THandleInfo info;
       
   412     	iUpdateMessageQueue.HandleInfo( &info );
       
   413 
       
   414         DLINFO(( "Processes for notify data available: %d", info.iNumProcesses ));
       
   415         DLINFO(( "Threads for notify data available: %d", info.iNumThreads ));
       
   416         DLINFO(( "Open in process for notify data available: %d", info.iNumOpenInProcess ));
       
   417         DLINFO(( "Open in thread for notify data available: %d", info.iNumOpenInThread ));
       
   418         
       
   419         // Only one request allowed per messagequeue
       
   420         // This causes problem in STIF tests at least when they are executed
       
   421         // in the emulator because the handles of crashed processes are not
       
   422         // always freed so testers won't get notifications about the data
       
   423         // and engine will eventually freeze because the queue gets full
       
   424         if ( info.iNumProcesses == 1 )        
       
   425             {
       
   426             DLINFO(( "Requesting notification of update messages" ));
       
   427             // A thread can have only one data available notification request outstanding 
       
   428             // on the message queue. If a second request is made before the first request 
       
   429             // completes, then the calling thread is panicked (KERN-EXEC 47).
       
   430             iUpdateMessageQueue.NotifyDataAvailable( iStatus );
       
   431             SetActive();            
       
   432             }
       
   433 	    }
       
   434 	    
       
   435 	CleanupStack::PopAndDestroy( msgQueueName );
       
   436 
       
   437     DLTRACEOUT((""));
       
   438     }
       
   439 
       
   440 void CCatalogsUpdateObserver::RunL()
       
   441     {
       
   442     DLTRACEIN(( "iStatus=%d", iStatus.Int() ));
       
   443 
       
   444     if( iStatus.Int() == KErrNone )
       
   445         {
       
   446         // Renew notification request.
       
   447         iUpdateMessageQueue.NotifyDataAvailable( iStatus );
       
   448         SetActive();
       
   449         
       
   450         CBufFlat* buffer = CBufFlat::NewL( KCatalogsUpdateInformationMaxSize + KCatalogsUpdateQueueMessageSize );
       
   451         CleanupStack::PushL( buffer );
       
   452         
       
   453         buffer->ResizeL( KCatalogsUpdateInformationMaxSize + KCatalogsUpdateQueueMessageSize );
       
   454         TUint8* msgPtr = const_cast< TUint8* >( buffer->Ptr( 0 ).Ptr() );
       
   455             
       
   456         while( iUpdateMessageQueue.Receive( msgPtr, KCatalogsUpdateQueueMessageSize ) == KErrNone )
       
   457             {
       
   458             msgPtr += KCatalogsUpdateQueueMessageSize;
       
   459             
       
   460             // Make a stream for reading the buffer.
       
   461             RBufReadStream stream( *buffer );
       
   462             CleanupClosePushL( stream );
       
   463 
       
   464             // Read total data size.
       
   465             TInt32 total;
       
   466             stream >> total;
       
   467             DLINFO(( "%d bytes of data incoming", total ));
       
   468 
       
   469             for( TInt bytesLeft = total + sizeof( TInt32 ) - KCatalogsUpdateQueueMessageSize;
       
   470                  bytesLeft > 0;
       
   471                  bytesLeft -= KCatalogsUpdateQueueMessageSize )
       
   472                 {
       
   473                 DLINFO(( "Reading more data, %d bytes to go", bytesLeft ));
       
   474                 iUpdateMessageQueue.ReceiveBlocking( msgPtr, KCatalogsUpdateQueueMessageSize );
       
   475                 msgPtr += KCatalogsUpdateQueueMessageSize;
       
   476                 }
       
   477                 
       
   478             // Read target string.
       
   479             HBufC* target = HBufC::NewLC( stream, KCatalogsUpdateTargetMaxSize );
       
   480             DLINFO(( _L("Update target: %S"), target ));
       
   481                         
       
   482             // Read ID string.
       
   483             HBufC* id = HBufC::NewLC( stream, KCatalogsUpdateIdMaxSize );
       
   484             DLINFO(( _L("Update target ID: %S"), id ));
       
   485             
       
   486             // Read version string.
       
   487             HBufC* version = HBufC::NewLC( stream, KCatalogsUpdateVersionMaxSize );
       
   488             DLINFO(( _L("Update version: %S"), version ));
       
   489             
       
   490             // Read URI string.
       
   491             HBufC* uri = HBufC::NewLC( stream, KCatalogsUpdateUriMaxSize );
       
   492             DLINFO(( _L("Update URI: %S"), uri ));
       
   493             
       
   494             // Read force boolean
       
   495             TInt32 force;
       
   496             stream >> force;
       
   497             DLINFO(( "Update forced: %d", force ));
       
   498             
       
   499             DLINFO(( "Calling update observer %08x", &iObserver ));
       
   500             iObserver.CatalogsUpdateNotification( *target, *id, *version, *uri, force );
       
   501             
       
   502             CleanupStack::PopAndDestroy( 5 ); // uri, version, id, target, stream-close
       
   503             
       
   504             // Reset to start position for next round (if any).
       
   505             msgPtr = const_cast< TUint8* >( buffer->Ptr( 0 ).Ptr() );
       
   506             }
       
   507 
       
   508         CleanupStack::PopAndDestroy( buffer );
       
   509         }
       
   510 
       
   511     DLTRACEOUT((""));
       
   512     }
       
   513 
       
   514 void CCatalogsUpdateObserver::DoCancel()
       
   515     {
       
   516     DLTRACEIN((""));
       
   517     iUpdateMessageQueue.CancelDataAvailable();
       
   518     DLTRACEOUT((""));
       
   519     }
       
   520 
       
   521 
       
   522 // ======== MEMBER FUNCTIONS ========
       
   523 
       
   524 TInt CCatalogsEngineImpl::AddRef() const
       
   525     {
       
   526     DLTRACEIN(( "" ));
       
   527     return ++iRefCount;
       
   528     }
       
   529 
       
   530 TInt CCatalogsEngineImpl::Release() const
       
   531     {
       
   532     DLTRACEIN(( "" ));
       
   533     // NOTE: engine object is deleted by client separately, do not self-destruct here.
       
   534     return --iRefCount;
       
   535     }
       
   536 
       
   537 const TAny* CCatalogsEngineImpl::QueryInterfaceL( TInt aInterfaceType ) const
       
   538     {
       
   539     DLTRACEIN(( "" ));
       
   540     const MCatalogsBase* result = NULL;
       
   541    
       
   542     switch( aInterfaceType )
       
   543         {
       
   544         case MCatalogsBase::KInterfaceUid:
       
   545             result = static_cast< const MCatalogsBase* >( this );
       
   546             result->AddRef();
       
   547             break;
       
   548 
       
   549         case MCatalogsEngine::KInterfaceUid:
       
   550             result = static_cast< const MCatalogsEngine* >( this );
       
   551             result->AddRef();
       
   552             break;
       
   553         }
       
   554 
       
   555     if( result )
       
   556         {
       
   557         iRefCount++;
       
   558         }
       
   559 
       
   560     return result;
       
   561     }
       
   562 
       
   563 CCatalogsEngineImpl::CCatalogsEngineImpl( MCatalogsEngineObserver& aObserver ) 
       
   564     : iObserver( &aObserver )
       
   565     {
       
   566     AddRef(); // Reference count is set to one
       
   567     }
       
   568 
       
   569 CCatalogsEngineImpl::~CCatalogsEngineImpl()
       
   570     {
       
   571     DLTRACEIN((""));
       
   572 
       
   573     DLTRACE(( "Deleting shutdown observer" ));
       
   574     delete iShutdownObserver;
       
   575 
       
   576     DLTRACE(( "Deleting update observer %08x", iUpdateObserver ));
       
   577     delete iUpdateObserver;
       
   578 
       
   579     delete iConnectionObserver;
       
   580     
       
   581     DLTRACE(( "Closing catalogs engine mutex" ));
       
   582     iCatalogsMutex.Close();
       
   583 
       
   584     DLTRACEOUT((""));
       
   585     }
       
   586 
       
   587 void CCatalogsEngineImpl::ConstructL()
       
   588     {
       
   589     DLTRACEIN(( "" ));
       
   590 
       
   591     // Mutex open should succeed, it is already open in CCatalogsEngine::NewLC().
       
   592     User::LeaveIfError( iCatalogsMutex.OpenGlobal( KCatalogsEngineMutex ) );
       
   593 
       
   594     // Create observer for maintenance lock mutex changes -> engine shutdown callback
       
   595     DLINFO(( "Creating shutdown observer" ));
       
   596     iShutdownObserver = CCatalogsShutdownObserver::NewL( *iObserver );
       
   597 
       
   598     // For the Catalogs UI client, create update observer for receiving OTA update
       
   599     // notifications.
       
   600     DLINFO(( "Checking for Catalogs UI client SID" ));
       
   601     RProcess process;
       
   602     static _LIT_SECURITY_POLICY_PASS( catalogsUiSecurityPolicy );
       
   603     if( catalogsUiSecurityPolicy().CheckPolicy( process ) )
       
   604         {
       
   605         DLINFO(( "Passed Catalogs UI security check, SID %08x", process.SecureId().iId ));
       
   606         DLINFO(( "Creating update observer" ));
       
   607         iUpdateObserver = CCatalogsUpdateObserver::NewL( *iObserver );
       
   608         }
       
   609     process.Close();
       
   610     
       
   611     iConnectionObserver = CCatalogsConnectionObserver::NewL( *iObserver );
       
   612     DLTRACEOUT((""));
       
   613     }
       
   614 
       
   615 CCatalogsEngineImpl* CCatalogsEngineImpl::NewL( TAny* aInitParams )
       
   616     {
       
   617     DLTRACEIN(( "aInitParams=%08x" ));
       
   618 
       
   619     // Engine observer was passed as init param pointer.
       
   620     MCatalogsEngineObserver* observer = static_cast< MCatalogsEngineObserver* >( aInitParams );
       
   621 
       
   622     CCatalogsEngineImpl* self =  new( ELeave ) CCatalogsEngineImpl( *observer );
       
   623     CleanupStack::PushL( self );
       
   624     self->ConstructL();
       
   625     CleanupStack::Pop( self );
       
   626     DLTRACEOUT(( "%08x", self ));
       
   627     return self;
       
   628     }
       
   629 
       
   630 TInt CCatalogsEngineImpl::Connect( TUid aClientUid )
       
   631     {
       
   632     DLTRACEIN(("%d",aClientUid.iUid));
       
   633     iClientUid = aClientUid;
       
   634     return iCatalogsEngine.Connect( aClientUid );
       
   635     }
       
   636 
       
   637 void CCatalogsEngineImpl::Close()
       
   638     {
       
   639     DLTRACEIN((""));    
       
   640 
       
   641     // Provider creator has to be deleted before disconnect is said because
       
   642     // the provider creator owns the provider (internal addref called)
       
   643     // and when the provider is deleted it connects to server.
       
   644     DLTRACE(( "Deleting provider creator %08x", iProviderCreator ));
       
   645     delete iProviderCreator;
       
   646     iProviderCreator = NULL;
       
   647 
       
   648     // Disconnect is enough for the iCatalogsEngine. Don't call Close for
       
   649     // the iCatalogsEngine as it does it in the Disconnect.
       
   650     DLTRACE(( "Disconnect" ));
       
   651     iCatalogsEngine.Disconnect();
       
   652     
       
   653     DLTRACEOUT((""));  
       
   654     }
       
   655 
       
   656 
       
   657 void CCatalogsEngineImpl::CreateProviderL( 
       
   658     TInt aUid, 
       
   659     MCatalogsBase*& aProvider, 
       
   660     TRequestStatus& aStatus,
       
   661     TUint32 aProviderOptions )
       
   662     {
       
   663     DLTRACEIN(("%X, %u", aUid, aProviderOptions ));
       
   664     // add UID mapping
       
   665 
       
   666     // If a provider has already been created, return that one
       
   667     if ( iProviderCreator != NULL )
       
   668         {
       
   669         MCatalogsBase* provider = iProviderCreator->Provider();
       
   670         if( provider != NULL )
       
   671             {
       
   672             DLINFO(("Provider already created"));
       
   673 
       
   674             // Increase reference count and pass to provider
       
   675             provider->AddRef();
       
   676             DLINFO(( "Writing CreateProvider result" ));
       
   677             aProvider = provider;
       
   678 
       
   679             aStatus = KRequestPending;
       
   680             TRequestStatus* statusPtr = &aStatus;
       
   681             User::RequestComplete( statusPtr, KErrNone );
       
   682             return;
       
   683             }
       
   684         else
       
   685             {
       
   686             DLINFO(("Provider is not created"));
       
   687             delete iProviderCreator;
       
   688             iProviderCreator = NULL;
       
   689             }
       
   690         }
       
   691 
       
   692     DLINFO(( "Starting provider creation" ));
       
   693     iProviderCreator = CCatalogsProviderCreator::NewL( 
       
   694         iCatalogsEngine, aUid, aProvider, aStatus, aProviderOptions );
       
   695 
       
   696     DLTRACEOUT((""));
       
   697     }
       
   698 
       
   699 void CCatalogsEngineImpl::CancelProviderCreation()
       
   700     {
       
   701     DLTRACEIN((""));
       
   702     
       
   703     // If iProviderCreator is active then the provider has not been properly
       
   704     // constructed.
       
   705     if ( iProviderCreator->IsActive() )
       
   706         {
       
   707         // iProviderCreator is deleted. This enables calling of
       
   708         // CreateProviderL again after this function call. In
       
   709         // that case the outcome of CreateProviderL would be as
       
   710         // if the function had been called normally before any
       
   711         // CancelProviderCreation.
       
   712         // Deletion is also a proper solution here as the creation of
       
   713         // iProviderCreator is mainly about creating the provider.
       
   714         // Construction of the iProviderCreator is simple and can be
       
   715         // done again with quite a little effort.
       
   716         delete iProviderCreator;
       
   717         iProviderCreator = NULL;
       
   718         }
       
   719     }