contextengine/src/contextengineao.cpp
changeset 0 c53acadfccc6
child 8 6752808b2036
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contextengine/src/contextengineao.cpp	Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,467 @@
+/*
+* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <sbdefs.h>
+#include <e32property.h>
+
+#include "contextengineao.h"
+#include "contextengine.h"
+#include "contextsnapshotitem.h"
+#include "harvesterlog.h"
+#include "mdsutils.h"
+#include "harvesterdata.h"
+#include "propertywatcher.h" 
+#include "harvestercommon.h"
+
+// ---------------------------------------------------------------------------
+// Default constructor for first phase construction.
+// ---------------------------------------------------------------------------
+//
+CContextEngineAO::CContextEngineAO( 
+		MContextInitializationObserver* aInitObserver,
+		MContextSnapshotObserver* aSnapshotObserver ) : 
+		CActive( KHarvesterPriorityContextEngine ), 
+		iInitializationObserver( aInitObserver ), 
+		iContextSnapshotObserver ( aSnapshotObserver ),
+		iUninitializedPluginsCount( 0 ),
+		iPluginSnapshotsLacking( 0 ),
+		iItem( NULL ),
+	    iState( EInitialization ),
+	    iInitializationError( KErrNone ),
+	    iSnapshotError( KErrNone ),
+	    iMdESession( NULL ),
+	    iPropertyWatcher( NULL ),
+	    iLastPlugin( EFalse )
+    {
+    WRITELOG( "CContextEngineAO::CContextEngineAO" ); // DEBUG INFO
+    }
+
+// ---------------------------------------------------------------------------
+// Standard NewL.
+// ---------------------------------------------------------------------------
+//
+CContextEngineAO* CContextEngineAO::NewL(
+    MContextInitializationObserver* aInitObserver,
+    MContextSnapshotObserver* aSnapshotObserver )
+    {
+    WRITELOG( "CContextEngineAO::NewL" ); // DEBUG INFO
+
+    CContextEngineAO* self = new (ELeave) CContextEngineAO( aInitObserver, aSnapshotObserver );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// 2nd phase construction.
+// ---------------------------------------------------------------------------
+//
+void CContextEngineAO::ConstructL()
+    {
+    WRITELOG( "CContextEngineAO::ConstructL" ); // DEBUG INFO
+
+    CActiveScheduler::Add( this );
+
+    iPropertyWatcher = CPropertyWatcher::GetInstanceL();
+      
+  	// Want to listen when backup/restore starts.
+  	// Calls NotifyKeyL when key's state has changed. 
+  	iPropertyWatcher->ListenKeyChangesL( 
+  			KUidSystemCategory,
+  			conn::KUidBackupRestoreKey, this );
+      
+    
+    if ( !iInitializationObserver )
+        {
+        InitializeL();
+        iState = EReady;
+        }
+    else  // same thing asyncronously
+        {
+        iState = EInitialization;
+        SetActive();
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone ); // "kick-start" this AO
+        }
+    }
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CContextEngineAO::~CContextEngineAO()
+    {
+    WRITELOG( "CContextEngineAO::~CContextEngineAO" ); // DEBUG INFO
+
+    Cancel();
+
+    MdsUtils::CleanupPtrArray<CContextPlugin>( &iPlugins );
+	
+    if( iPropertyWatcher )
+		{
+		
+	 	iPropertyWatcher->StopListeningKeyChanges( 
+	  			KUidSystemCategory,
+	  			conn::KUidBackupRestoreKey, this );
+		
+		iPropertyWatcher->Delete(); // Release connection to TLS object.
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// Set MdeSession for context engine plugins.
+// ---------------------------------------------------------------------------
+//
+void CContextEngineAO::SetMdeSession( CMdESession* aSession )
+    {
+    iMdESession = aSession;
+
+    for ( TInt i = 0; i < iPlugins.Count(); ++i )
+        {
+        iPlugins[i]->SetMdeSession( *aSession );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Start taking a context snapshot (for multiple objects).
+// ---------------------------------------------------------------------------
+//
+void CContextEngineAO::StartSnapshot( CContextSnapshotItem* aItem )
+    {
+    WRITELOG( "CContextEngineAO::StartSnapshot" ); // DEBUG INFO
+    iItem = aItem;
+    if ( !aItem ) return;
+    if ( !aItem->GetItem() && !aItem->GetItemArray() )
+        {
+        // no items to do the snapshot for... stop.
+        aItem->GetObserver()->ContextSnapshotStatus( KErrNone );
+        }
+
+    iSnapshotError = KErrNone;
+    iPluginSnapshotsLacking = iPlugins.Count(); // reset, no snapshots taken yet
+
+    if ( iPluginSnapshotsLacking <= 0 )
+    	{
+    	iState = EReady;
+    	iContextSnapshotObserver->ContextSnapshotStatus( KErrNone );    
+    	}
+    iLastPlugin = EFalse;
+    
+    iState = ESnapshot;
+    SetActive();
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone ); // "kick-start" this AO
+    }
+
+// ---------------------------------------------------------------------------
+// Return loaded plugin count.
+// ---------------------------------------------------------------------------
+//
+TInt CContextEngineAO::PluginCount()
+    {
+    return iPlugins.Count();
+    }
+
+// ---------------------------------------------------------------------------
+// From CActive.
+// Start/continue taking a context snapshot (for multiple objects).
+// Ask a snapshot from one plugin at a time.
+// ---------------------------------------------------------------------------
+//
+void CContextEngineAO::RunL()
+	{
+#ifdef _DEBUG
+    WRITELOG1( "CContextEngineAO::RunL iStatus: %d", iStatus.Int() ); // DEBUG INFO
+#endif
+
+    if ( iState == EInitialization )
+        {
+        InitializeL();
+        }
+    else if ( iState == ESnapshot )
+        {
+        if ( iStatus.Int() != KErrNone )
+            {
+            return;
+            }
+
+        if ( iPluginSnapshotsLacking > 0 )
+            {
+            TInt i = iPlugins.Count() - iPluginSnapshotsLacking;
+            if( iPluginSnapshotsLacking == 1 )
+                {
+                iLastPlugin = ETrue;
+                }
+            if ( iItem->GetItemArray() ) 
+                {
+                iPlugins[i]->ContextSnapshot( *this, *iItem->GetItemArray() );  
+                }                               // CContextEngineAO is instance of
+            else                                // MContextPluginObserver
+                {
+                iPlugins[i]->ContextSnapshot( *this, *iItem->GetItem() );
+                }
+            iPluginSnapshotsLacking--;
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// From CActive.
+// ---------------------------------------------------------------------------
+//
+#ifdef _DEBUG
+TInt CContextEngineAO::RunError( TInt aError )
+#else
+TInt CContextEngineAO::RunError( TInt )
+#endif
+    {
+    WRITELOG1( "CContextEngineAO::RunError with error code: %d", aError ); // DEBUG INFO
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From CActive. 
+// ---------------------------------------------------------------------------
+//
+void CContextEngineAO::DoCancel()
+    {
+    WRITELOG( "CContextEngineAO::DoCancel" ); // DEBUG INFO
+
+    iPluginSnapshotsLacking = 0;
+    iState = EReady;
+    }
+
+// ---------------------------------------------------------------------------
+// From MContextPluginObserver.
+// ---------------------------------------------------------------------------
+//
+void CContextEngineAO::PluginInitializationStatus( TInt aErrorCode )
+    {
+    WRITELOG1( "CContextEngineAO::PluginInitializationStatus with error code: %d", aErrorCode ); // DEBUG INFO
+
+    if ( aErrorCode != KErrNone && iInitializationError != KErrNone )
+        {
+        iInitializationError = aErrorCode;
+        }
+
+    iUninitializedPluginsCount--;
+    if ( iUninitializedPluginsCount <= 0 )
+        {
+        iState = EReady;
+        // notify the client application by using MContextSnapshotObserver's
+        // method ContextInitializationStatus()
+        // Notice! Error code of the last plugin is returned...
+        if ( iInitializationObserver )
+            {
+            iInitializationObserver->ContextInitializationStatus( iInitializationError );
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// From MContextPluginObserver.
+// ---------------------------------------------------------------------------
+//
+void CContextEngineAO::PluginSnapshotStatus( CHarvesterData* aHD )
+    {
+    TInt errorCode = aHD->ErrorCode();
+    WRITELOG1( "CContextEngineAO::PluginSnapshotStatus with error code: %d", errorCode ); // DEBUG INFO
+
+    if ( errorCode != KErrNone && iSnapshotError != KErrNone )
+        {
+        aHD->SetErrorCode( errorCode );
+        }
+    
+    if( iLastPlugin )
+        {
+        // Notice! Error code of the last plugin is returned...
+        iContextSnapshotObserver->ContextSnapshotStatus( aHD );
+        }
+
+    if ( iPluginSnapshotsLacking <= 0 )
+        {
+        iState = EReady;
+        }
+    else 
+        {  // do this again for the next plugin/harvest data object
+        if( !IsActive() )
+            {
+            SetActive();
+            TRequestStatus* status = &iStatus;
+            User::RequestComplete( status, KErrNone ); // "kick-start" this AO
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Called by CBlacklistBackupSubscriberAO when
+// Backup&Restore is backing up or restoring.
+// ---------------------------------------------------------------------------
+//
+void CContextEngineAO::BackupRestoreStart()
+    {
+    // stop context plugins
+    WRITELOG( "CContextEngineAO::BackupRestoreStart" );
+ 
+    iPlugins.ResetAndDestroy(); // remove any existing plugins, just in case
+    }
+
+// ---------------------------------------------------------------------------
+// Called by CBlacklistBackupSubscriberAO when
+// Backup&Restore has finished backup or restore.
+// ---------------------------------------------------------------------------
+//
+void CContextEngineAO::BackupRestoreReady()
+    {
+    // restart plugins
+    WRITELOG( "CContextEngineAO::BackupRestoreReady" );
+    
+    TRAP_IGNORE( InitializeL() );
+    
+    if ( iMdESession )
+    	{
+    	SetMdeSession( iMdESession );
+    	}
+    
+    iState = EReady;
+    
+    }
+
+// private methods
+
+// ---------------------------------------------------------------------------
+// Load context plugins to the "iPlugins" array.
+// ---------------------------------------------------------------------------
+//
+void CContextEngineAO::LoadPluginsL()
+    {
+    WRITELOG( "CContextEngineAO::LoadPluginsL" ); // DEBUG INFO
+
+    if ( iPlugins.Count() > 0 )
+        {
+        iPlugins.ResetAndDestroy(); // remove any existing plugins, just in case
+        }
+
+    // read info about all implementations into infoArray
+    RImplInfoPtrArray infoArray;
+    TCleanupItem cleanupItem( MdsUtils::CleanupEComArray, &infoArray );
+    CleanupStack::PushL( cleanupItem );
+    
+    CContextPlugin::ListImplementationsL( infoArray );
+
+    CContextPlugin* plugin = NULL;
+    TInt err = KErrNone;
+    for ( TInt i = 0; i < infoArray.Count(); i++ )
+        {
+        TUid uid = infoArray[i]->ImplementationUid(); 
+        TRAP( err, plugin = CContextPlugin::NewL( uid ) ); // create the plug-ins
+        if ( err == KErrNone && plugin )
+            {
+            CleanupStack::PushL( plugin );
+            iPlugins.AppendL( plugin );        // and add them to an array
+            CleanupStack::Pop( plugin );
+            }
+        }
+
+	CleanupStack::PopAndDestroy( &infoArray ); // infoArray, results in a call to CleanupEComArray		
+    }
+
+// ---------------------------------------------------------------------------
+// Initialize this object. Thus load and initialize plugins.
+// ---------------------------------------------------------------------------
+//
+void CContextEngineAO::InitializeL()
+    {
+    WRITELOG( "CContextEngineAO::InitializeL" ); // DEBUG INFO
+
+    iInitializationError = KErrNone;
+    LoadPluginsL();
+    iUninitializedPluginsCount = iPlugins.Count(); // set this so we can later be sure that all
+                                                   // plug-ins are initialized.
+    if ( iUninitializedPluginsCount <= 0 ) // if no plugins were loaded
+        {
+        if ( iInitializationObserver )
+            {
+            iInitializationObserver->ContextInitializationStatus( KErrNone );
+            }
+        }
+
+    const TInt KCount = iUninitializedPluginsCount;
+    for ( TInt i = 0; i < KCount; i++ )
+        {
+        iPlugins[i]->Init( *this ); // CContextEngineAO is instance of MContextPluginObserver
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CRestoreWatcher::NotifyKeyL
+// CPropertyWatcher's callback. From 
+// -----------------------------------------------------------------------------
+//
+void CContextEngineAO::NotifyKeyL( 
+		const TInt aKeyValue,
+		const TUid aPropertyCategory,
+		const TUint aKey )
+	{
+	WRITELOG("CContextEngineAO::NotifyKeyL() - begin");
+	
+	if( aPropertyCategory == KUidSystemCategory &&
+			aKey == conn::KUidBackupRestoreKey ) 
+		{
+		HandleBackupRestoreKeyAction( aKeyValue );
+		}
+	
+	
+	WRITELOG("CContextEngineAO::NotifyKeyL() - end");
+	}
+
+// -----------------------------------------------------------------------------
+// CContextEngineAO::HandleBackupKeyAction
+// When user starts restore sets flag on.
+// -----------------------------------------------------------------------------
+//
+void CContextEngineAO::HandleBackupRestoreKeyAction( const TUint aKeyValue )
+	{	
+	WRITELOG("CRestoreWatcher::HandleBackupKeyAction() - begin");
+	
+	TInt backupStateValue = aKeyValue;
+	backupStateValue &= conn::KBURPartTypeMask;
+	
+	switch ( backupStateValue )
+		{
+		case conn::EBURBackupFull:
+		case conn::EBURBackupPartial:
+		case conn::EBURRestoreFull:
+		case conn::EBURRestorePartial:
+			{
+			BackupRestoreStart();
+			break;
+			}
+		
+		case conn::EBURNormal:
+		case conn::EBURUnset:
+		default:
+			{
+			// backup or restore is completed, so resume normal operation.
+       		BackupRestoreReady();
+			}
+		}	
+	
+	WRITELOG("CRestoreWatcher::HandleBackupKeyAction() - end");
+	}
+