contextengine/src/contextengine.cpp
changeset 0 c53acadfccc6
child 19 b73252188534
equal deleted inserted replaced
-1:000000000000 0:c53acadfccc6
       
     1 /*
       
     2 * Copyright (c) 2006-2009 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:  An engine to collect context related metadata.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // this class contains use of memory allocation and release not
       
    20 // conforming to RAII principles
       
    21 
       
    22 #include <e32uid.h>
       
    23 #include <ecom.h>
       
    24 #include <e32svr.h>
       
    25 
       
    26 #include "contextengine.h"
       
    27 #include "contextengineao.h"
       
    28 #include "contextsnapshotitem.h"
       
    29 #include "mdsutils.h"
       
    30 #include "harvesterlog.h"
       
    31 #include "harvesterdata.h"
       
    32 
       
    33 /// Key for thread-local storage used by this singleton.
       
    34 const TInt KContextEngineTLSKey = 0x200009f6;
       
    35 
       
    36 // construct/destruct
       
    37 
       
    38 // ---------------------------------------------------------------------------
       
    39 // 1st phase C++ construction.
       
    40 // Don't export these, because used only by our NewLC() and the like.
       
    41 // ---------------------------------------------------------------------------
       
    42 //
       
    43 CContextEngine::CContextEngine( ) :
       
    44     iContextEngineAO( NULL ), iArrayCount( 0 ), iProcessedArrayCount( 0 )
       
    45     {
       
    46     WRITELOG( "CContextEngine::CContextEngine" ); // DEBUG INFO
       
    47     }
       
    48 
       
    49 // ---------------------------------------------------------------------------
       
    50 // 2nd phase construction
       
    51 // ---------------------------------------------------------------------------
       
    52 //
       
    53 void CContextEngine::ConstructL( MContextInitializationObserver* aObserver )
       
    54     {
       
    55     WRITELOG( "CContextEngine::ConstructL" ); // DEBUG INFO
       
    56     iContextEngineAO = CContextEngineAO::NewL( aObserver, this );
       
    57     }
       
    58 
       
    59 // ---------------------------------------------------------------------------
       
    60 // Get a reference to this singleton. A new object is created if needed.
       
    61 // If an observer object to notify is given, context plugins are initialized
       
    62 // asyncronously and observer is notified when ready.
       
    63 // ---------------------------------------------------------------------------
       
    64 //
       
    65 EXPORT_C CContextEngine* CContextEngine::GetInstanceL(
       
    66 	MContextInitializationObserver* aObserver )
       
    67     {
       
    68     WRITELOG( "CContextEngine::GetInstanceL" ); // DEBUG INFO
       
    69     CContextEngineStaticData* data = static_cast<CContextEngineStaticData*>(
       
    70         UserSvr::DllTls(KContextEngineTLSKey) );
       
    71     CContextEngine* instance = NULL;
       
    72     if ( !data )
       
    73         {
       
    74         instance = new (ELeave) CContextEngine();
       
    75         CleanupStack::PushL( instance );
       
    76         instance->ConstructL( aObserver );
       
    77 
       
    78         UserSvr::DllSetTls( KContextEngineTLSKey,
       
    79         	new (ELeave) CContextEngineStaticData(instance) );
       
    80 
       
    81         CleanupStack::Pop( instance );
       
    82         }
       
    83     else
       
    84         {
       
    85         instance = data->iContextEngine;
       
    86         data->iRefCount++;
       
    87         if ( aObserver )
       
    88             {
       
    89             aObserver->ContextInitializationStatus( KErrNone );
       
    90             }
       
    91         }
       
    92 
       
    93     return instance;
       
    94     }
       
    95 
       
    96 // ---------------------------------------------------------------------------
       
    97 // Release a reference to this singleton.
       
    98 // ---------------------------------------------------------------------------
       
    99 //
       
   100 EXPORT_C void CContextEngine::ReleaseInstance()
       
   101     {
       
   102     WRITELOG( "CContextEngine::ReleaseInstance" ); // DEBUG INFO
       
   103     CContextEngineStaticData* data =
       
   104         static_cast<CContextEngineStaticData*>( UserSvr::DllTls(KContextEngineTLSKey) );
       
   105     if ( data )
       
   106         {
       
   107         data->iRefCount--;
       
   108         if ( data->iRefCount <= 0 )
       
   109             {
       
   110             // destroy the singleton and free TLS
       
   111             delete data;
       
   112             UserSvr::DllFreeTls( KContextEngineTLSKey );
       
   113             }
       
   114         }
       
   115     }
       
   116 
       
   117 /* ---------------------------------------------------------------------------
       
   118  * Ignores the reference count and destroys this singleton.            .   .
       
   119  * Should be used only if client code is not using ReleaseInstance()  /|\ /|\
       
   120  * to release their handles to this singleton.                         |   |
       
   121  *                                                                     |   |
       
   122  *                                                        			  -------
       
   123  *                                                                	  -------
       
   124  * ---------------------------------------------------------------------------
       
   125 */
       
   126 EXPORT_C void CContextEngine::Destroy()
       
   127     {
       
   128     WRITELOG( "CContextEngine::Destroy" ); // DEBUG INFO
       
   129     CContextEngineStaticData* data =
       
   130         static_cast<CContextEngineStaticData*>( UserSvr::DllTls(KContextEngineTLSKey) );
       
   131     if ( data )
       
   132         {
       
   133         // destroy the singleton and free TLS
       
   134         delete data;
       
   135         UserSvr::DllFreeTls( KContextEngineTLSKey );
       
   136         }
       
   137     }
       
   138 
       
   139 // ---------------------------------------------------------------------------
       
   140 // Destructor.
       
   141 // ---------------------------------------------------------------------------
       
   142 //
       
   143 CContextEngine::~CContextEngine()
       
   144     {
       
   145     WRITELOG( "CContextEngine::~CContextEngine" ); // DEBUG INFO
       
   146     delete iContextEngineAO;
       
   147 
       
   148     MdsUtils::CleanupPtrArray<CContextSnapshotItem>( &iSnapshotQueue );
       
   149     REComSession::FinalClose(); // we are done
       
   150     }
       
   151 
       
   152 // ---------------------------------------------------------------------------
       
   153 // Set MdeSession to context engine and it's plugins.
       
   154 // Session must be set in order to successfully harvest context data.
       
   155 // ---------------------------------------------------------------------------
       
   156 //
       
   157 EXPORT_C void CContextEngine::SetMdeSession( CMdESession* aSession )
       
   158     {
       
   159     iContextEngineAO->SetMdeSession( aSession );
       
   160     }
       
   161 
       
   162 // ---------------------------------------------------------------------------
       
   163 // Takes a context snapshot including all initialized plugins.
       
   164 // ---------------------------------------------------------------------------
       
   165 //
       
   166 EXPORT_C void CContextEngine::ContextSnapshot( MContextSnapshotObserver& aObserver,
       
   167     CHarvesterData& aHD )
       
   168     {
       
   169     WRITELOG( "CContextEngine::ContextSnapshot (single)" ); // DEBUG INFO
       
   170     
       
   171     // if any plug-in hasn't been found...
       
   172     if ( iContextEngineAO->PluginCount() <= 0 )
       
   173         {
       
   174         aHD.SetErrorCode( KErrNone );
       
   175         aObserver.ContextSnapshotStatus( &aHD );
       
   176         return;
       
   177         }
       
   178 
       
   179     // queue item for taking a snapshot
       
   180     CContextSnapshotItem* item = NULL;
       
   181     TRAPD( err, item = CContextSnapshotItem::NewL( &aObserver, &aHD ) );
       
   182     iArrayCount = 0;
       
   183     iProcessedArrayCount = 0;
       
   184     if ( err == KErrNone ) QueueSnapshotItem( item );
       
   185     }
       
   186 
       
   187 // ---------------------------------------------------------------------------
       
   188 // Takes a context snapshot including all initialized plugins
       
   189 // for multiple objects.
       
   190 // ---------------------------------------------------------------------------
       
   191 //
       
   192 EXPORT_C void CContextEngine::ContextSnapshot( MContextSnapshotObserver& aObserver,
       
   193     RPointerArray<CHarvesterData>& aHDArray )
       
   194     {
       
   195     WRITELOG( "CContextEngine::ContextSnapshot (array)" ); // DEBUG INFO
       
   196     
       
   197     // if any plug-in hasn't been found...
       
   198     if ( iContextEngineAO->PluginCount() <= 0 )
       
   199         {
       
   200         aObserver.ContextSnapshotStatus( NULL );
       
   201         return;
       
   202         }
       
   203 
       
   204     // queue items for taking a snapshot
       
   205     CContextSnapshotItem* item = NULL;
       
   206     TRAPD( err, item = CContextSnapshotItem::NewL( &aObserver, &aHDArray ) );
       
   207     iArrayCount = aHDArray.Count();
       
   208     iProcessedArrayCount = 0;
       
   209     if ( err == KErrNone ) QueueSnapshotItem( item );
       
   210     }
       
   211 
       
   212 // ---------------------------------------------------------------------------
       
   213 // Number of context plug-ins loaded. For testing purposes only.
       
   214 // ---------------------------------------------------------------------------
       
   215 //
       
   216 EXPORT_C TInt CContextEngine::PluginCount()
       
   217     {
       
   218     return iContextEngineAO->PluginCount();
       
   219     }
       
   220 
       
   221 // ---------------------------------------------------------------------------
       
   222 // From MContextEngineObserver.
       
   223 // Method is called by CContextEngineAO when a context snapshot is finished
       
   224 // or an error has occured.
       
   225 // ---------------------------------------------------------------------------
       
   226 //
       
   227 void CContextEngine::ContextSnapshotStatus( CHarvesterData* aHD )
       
   228     {
       
   229     if( iSnapshotQueue.Count() == 0 )
       
   230         {
       
   231         return;
       
   232         }
       
   233     
       
   234     if( iArrayCount > 0 )
       
   235         {
       
   236         iProcessedArrayCount++;
       
   237         }
       
   238     
       
   239     // notify the client application by using MContextSnapshotObserver's
       
   240     // method ContextSnapshotStatus()
       
   241     iSnapshotQueue[0]->GetObserver()->ContextSnapshotStatus( aHD );
       
   242 
       
   243     // remove handled item from queue
       
   244     if( iProcessedArrayCount == iArrayCount )
       
   245         {
       
   246         delete iSnapshotQueue[0];
       
   247         iSnapshotQueue[0] = NULL;
       
   248         iSnapshotQueue.Remove( 0 );
       
   249         iArrayCount = 0;
       
   250         iProcessedArrayCount = 0;
       
   251         }
       
   252 
       
   253     // ask a new snapshot if there is stuff in the queue
       
   254     if( iArrayCount == 0 && iSnapshotQueue.Count() > 0 )
       
   255         {
       
   256         RPointerArray<CHarvesterData>* tempArray = iSnapshotQueue[0]->GetItemArray();
       
   257         if( tempArray )
       
   258             {
       
   259             iArrayCount = tempArray->Count();
       
   260             }
       
   261         iContextEngineAO->StartSnapshot( iSnapshotQueue[0] );
       
   262         }
       
   263     else if( iSnapshotQueue.Count() == 0 )
       
   264     	{
       
   265     	iSnapshotQueue.Compress();
       
   266     	}
       
   267     }
       
   268 
       
   269 // ---------------------------------------------------------------------------
       
   270 // Add a new item to the snapshot item queue.
       
   271 // Item contains an observer that needs to be informed when a snapshot is ready
       
   272 // and items that need a context snapshot.
       
   273 // If the queue was empty before adding the item, it's handling is started.
       
   274 // ---------------------------------------------------------------------------
       
   275 //
       
   276 void CContextEngine::QueueSnapshotItem( CContextSnapshotItem* aItem )
       
   277     {
       
   278     // add a new object
       
   279     if ( iSnapshotQueue.Append( aItem ) != KErrNone )
       
   280         {
       
   281         delete aItem;
       
   282         return;
       
   283         }
       
   284 
       
   285     // the queue was empty, start ContextEngineAO
       
   286     if ( iSnapshotQueue.Count() == 1 )  // if the queue _was_ empty
       
   287         {
       
   288         iContextEngineAO->StartSnapshot( iSnapshotQueue[0] );
       
   289         }
       
   290     }
       
   291