wvuing/wvuieng/EngSrc/CCABlockingManager.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wvuing/wvuieng/EngSrc/CCABlockingManager.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,1399 @@
+/*
+* Copyright (c) 2002-2005 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:  Blocking manager handles the blocking and granting
+ *
+*/
+
+
+// INCLUDES
+
+#include "CCABlockingManager.h"
+#include "CCARequest.h"
+#include "CCARequestMapper.h"
+#include "PrivateEngineDefinitions.h"
+#include "ChatDebugPrint.h"
+#include "CCAStorageManagerFactory.h"
+#include "MCASettings.h"
+#include "MCAStoredContact.h"
+#include "MCAStoredContacts.h"
+#include "MCAImpsFactory.h"
+
+#include "impsbuilddefinitions.h"
+
+#include "TStorageManagerGlobals.h"
+#include "CAUtils.h"
+
+#include "MCAPresence.h"
+#include "MCAContactLists.h"
+#include "CAPresenceManager.h"
+
+#include "ccasyncchecker.h"
+#include "mcacontactlist.h"
+
+#include <badesca.h>
+
+const TInt KBlockingMgrListGranularity = 10;
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+
+CCABlockingManager::CCABlockingManager(
+    MCAImpsFactory* aIMPSFactory,
+    CCARequestMapper* aRequestMapper,
+    MCASettings* aSettingsManager )
+        :   iImpsFactory( aIMPSFactory ),
+        iRequestMapper( aRequestMapper ),
+        iSettingsManager( aSettingsManager ),
+        iStrategy( MCASettings::EAll ),
+        iMgrState( EStateNormal )
+    {
+    }
+
+// Destructor
+EXPORT_C CCABlockingManager::~CCABlockingManager()
+    {
+    if ( iBlockedList )
+        {
+        iBlockedList->Reset();
+        delete iBlockedList;
+        }
+
+    if ( iGrantedList )
+        {
+        iGrantedList->Reset();
+        delete iGrantedList;
+        }
+    }
+
+// Two-phased constructor.
+EXPORT_C CCABlockingManager* CCABlockingManager::NewL(
+    MCAImpsFactory* aIMPSFactory,
+    CCARequestMapper* aRequestMapper,
+    MCASettings* aSettingsManager )
+    {
+    CCABlockingManager* self = new ( ELeave ) CCABlockingManager(
+        aIMPSFactory,
+        aRequestMapper,
+        aSettingsManager );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+
+// Symbian OS default constructor can leave.
+void CCABlockingManager::ConstructL()
+    {
+    iStoredContacts = CCAStorageManagerFactory::ContactListInterfaceL();
+
+    iBlockedList = new ( ELeave ) CDesCArrayFlat( KBlockingMgrListGranularity );
+    iGrantedList = new ( ELeave ) CDesCArrayFlat( KBlockingMgrListGranularity );
+
+    // after this the strategy gets updated via observing mechanism
+    iStrategy = ( MCASettings::TCASettingValues )
+                iSettingsManager->Value( MCASettings::EReceiveIMessages );
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::GetBlockedListRequestL()
+// GetBlocked list
+// ---------------------------------------------------------
+//
+TInt CCABlockingManager::GetBlockedListFromServerL()
+    {
+    CHAT_DP_TXT( "CCABlockingManager::GetBlockedListFromServerL...starts" );
+
+    iGetBlockedListOpId =  iImpsFactory->CreateImClientL()->GetBlockedListRequestL();
+
+    // owned by request mapper
+    CCARequest* request = iRequestMapper->CreateRequestL( iGetBlockedListOpId );    // CSI: 35 # Ownership is not transferred to caller.
+
+    CHAT_DP_FUNC_DP( "GetBlockedListResponseL", "Going to HandleRequest" );
+    iRequestMapper->HandleRequest( iGetBlockedListOpId, KErrNone );
+
+    // set to 0 so we know that there is no request hanging.
+    iGetBlockedListOpId = 0;
+
+    TInt errorCode( request->ErrorCode() );
+    iRequestMapper->RemoveRequest( request );
+
+    if ( iMgrState == EStateNormal )
+        {
+        if ( iStrategy != MCASettings::EAll && iCanUseGrant )
+            {
+            CHAT_DP_FUNC_DP( "GetBlockedListResponseL",
+                             "Copying grantlist" );
+            switch ( iStrategy )
+                {
+                case MCASettings::EFriends:
+                    {
+#ifdef IMPS_CONTACT_FETCH_BACKGROUND
+                    if( iAppUiExit )
+                    	{
+                    	return errorCode;
+                    	}
+                    // Can't grant friends if contact list
+                    // sync is not done, wait for it if needed
+                    if ( !CCASyncChecker::CheckSyncStateL() )
+                        {
+                        User::Leave( KErrNotReady );
+                        }
+#endif // IMPS_CONTACT_FETCH_BACKGROUND
+                    CDesCArray* clone = CloneArrayLC( *iGrantedList );
+                    GrantFriendsL();
+                    // Check new ids to be granted
+                    CDesCArray* diff = CreateNeutralDiffLC( *iGrantedList,
+                                                            *clone );
+                    // Check if clone contains more ids than we have friends
+                    CDesCArray* diff2 = CreateNeutralDiffLC( *clone,
+                                                             *iGrantedList );
+                    iGrantedList->Reset();
+                    // Remove grant from excess ids
+                    RemoveL( NULL, diff2, ETrue );
+                    // Add grant for new ids
+                    InsertL( NULL, diff, ETrue );
+                    GrantFriendsL(); // reset situation
+                    CleanupStack::PopAndDestroy( 3, clone ); // clone, diff, diff2
+                    break;
+                    }
+                case MCASettings::ENobody:
+                    {
+                    CDesCArray* clone = CloneArrayLC( *iGrantedList );
+                    RemoveL( NULL, clone, ETrue );
+                    CleanupStack::PopAndDestroy( clone );
+                    break;
+                    }
+                default:
+                    {
+                    break;
+                    }
+                }
+            }
+        else if ( !iCanUseGrant )
+            // This is done to get rid of grant list usage.
+            {
+            //if iGrantedList is empty, nothing to clean
+            if ( iGrantedList && iGrantedList->MdcaCount() > 0 )
+                {
+                CDesCArray* clone = CloneArrayLC( *iGrantedList );
+                RemoveL( NULL, clone, ETrue );
+                CleanupStack::PopAndDestroy( clone );
+                }
+            }
+        else if ( iCanUseGrant && iStrategy == MCASettings::EAll )
+            {
+            if( iAppUiExit )
+            	{
+            	return errorCode;
+            	}
+            InsertL( iBlockedList, NULL, ETrue );
+            }
+        }
+
+    CHAT_DP_TXT( "CCABlockingManager::GetBlockedListFromServerL...over" );
+
+    return errorCode;
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::BlockedList()
+// ---------------------------------------------------------
+//
+const CDesCArray* CCABlockingManager::BlockedList()
+    {
+    return iBlockedList;
+    }
+
+// check if grant list in use according to the
+// currently chosen strategy
+TBool CCABlockingManager::GrantListInUse()
+    {
+    CHAT_DP_FUNC_ENTER( "GrantListInUse" );
+
+    // grant list is always in use if we're not
+    // accepting IMessages from all
+    TBool retval( ETrue );
+
+    if ( iStrategy == MCASettings::EAll || !iCanUseGrant )
+        {
+        // grant list not in use, everyone is accepted (except
+        // that the blocking list overrides)
+        retval = EFalse;
+        CHAT_DP_TXT( "Grant list not in use!" );
+        }
+
+    CHAT_DP_FUNC_DONE( "GrantListInUse" );
+
+    return retval;
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::InsertL()
+// Insert users to block or grant lists at server
+// ---------------------------------------------------------
+//
+TInt CCABlockingManager::InsertL(
+    const CDesCArray* aBlockList,
+    const CDesCArray* aGrantList,
+    TBool aForceUpdate /* = EFalse */ )
+    {
+    if ( aGrantList )
+        {
+        CDesCArray* diff = CreateNeutralDiffLC( *aGrantList, *iGrantedList );
+
+        TInt err( KErrNone );
+        if ( NeedUpdate( aBlockList, diff, aForceUpdate ) && !iUpdateInProgress )
+            {
+            err = DoBlockRequestL( aBlockList, NULL, diff, NULL, aBlockList,
+                                   EBlockRequest );
+            if ( err == KErrNone )
+                {
+                AddToGrantedListL( *aGrantList );
+                }
+            }
+        CleanupStack::PopAndDestroy( diff );
+
+        return err;
+        }
+    else if ( NeedUpdate( aBlockList, aGrantList, aForceUpdate ) )
+        {
+        return DoBlockRequestL( aBlockList, NULL, aGrantList, NULL, aBlockList,
+                                EBlockRequest );
+        }
+
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::RemoveL()
+// Remove users from block or grant lists at server
+// ---------------------------------------------------------
+//
+TInt CCABlockingManager::RemoveL(
+    const CDesCArray* aBlockList,
+    const CDesCArray* aGrantList,
+    TBool aForceUpdate /* = EFalse */ )
+    {
+    if ( aGrantList )
+        {
+        CDesCArray* clone = CloneArrayLC( *aGrantList );
+        RemoveFromGrantedList( *clone );
+        TInt err( KErrNone );
+        if ( NeedUpdate( aBlockList, clone, aForceUpdate )
+             && !iUpdateInProgress )
+            {
+            err = DoBlockRequestL( NULL, aBlockList, NULL, clone, aBlockList,
+                                   EUnBlockRequest );
+            }
+        CleanupStack::PopAndDestroy( clone );
+        return err;
+        }
+
+    if ( NeedUpdate( aBlockList, aGrantList, aForceUpdate ) )
+        {
+        return DoBlockRequestL( NULL, aBlockList, NULL, aGrantList, aBlockList,
+                                EUnBlockRequest );
+        }
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CCABlockingManager::NeedUpdate
+// If update is needed, return True
+// -----------------------------------------------------------------------------
+//
+TBool CCABlockingManager::NeedUpdate( const CDesCArray* aBlockList,
+                                      const CDesCArray* aGrantList,
+                                      TBool aForceUpdate )
+    {
+    if ( !aForceUpdate )
+        {
+        if ( aGrantList )
+            {
+            if ( aGrantList->MdcaCount() == 0 )
+                {
+                return EFalse;
+                }
+            }
+        else if ( aBlockList )
+            {
+            if ( aBlockList->MdcaCount() == 0 )
+                {
+                return EFalse;
+                }
+            }
+        }
+    return ETrue;
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::GrantFriendsL()
+// Insert friends to grant lists at server
+// ---------------------------------------------------------
+//
+void CCABlockingManager::GrantFriendsL(
+    CDesCArray* aDoNotIncludeList /*= NULL*/ )
+    {
+    if( iAppUiExit )
+    	{
+    	return ;
+    	}
+    // add all friends to Grant list
+    // the blocked list overrides this list anyway
+    iGrantedList->Reset();
+
+    // fetch the contacts from all lists in server
+    CPtrCArray* wvids = new( ELeave )CPtrCArray( KArrayGranularity );
+    CleanupStack::PushL( wvids );
+
+    MCAPresence* presence = CAPresenceManager::InstanceL();
+    MCAContactLists* listInterface = presence->ContactLists();
+    TContactListsWrapper contactListIds;
+
+    if ( listInterface )
+        {
+        contactListIds = listInterface->FetchServerContactListsL();
+        }
+    TInt count( contactListIds.MdcaCount() );
+    TInt i;
+    for ( i = 0; i < count; ++i )
+        {
+        listInterface->FetchServerContactsL( contactListIds.MdcaPoint( i ),
+                                             *wvids );
+        }
+    count = wvids->MdcaCount();
+    TBool doNotIncludeFlag( EFalse );
+    for ( i = 0; i < count; ++i )
+        {
+        TPtrC id( wvids->MdcaPoint( i ) );
+        if ( aDoNotIncludeList )
+            {
+            TInt count2( aDoNotIncludeList->MdcaCount() );
+            for ( TInt j( 0 ); j < count2 && !doNotIncludeFlag; ++j )
+                {
+                if ( CAUtils::NeutralCompare( id,
+                                              aDoNotIncludeList->MdcaPoint( j ) ) == 0 )
+                    {
+                    doNotIncludeFlag = ETrue;
+                    aDoNotIncludeList->Delete( j );
+                    }
+                }
+            }
+        if ( !doNotIncludeFlag )
+            {
+            iGrantedList->AppendL( wvids->MdcaPoint( i ) );
+            }
+        else
+            {
+            doNotIncludeFlag = EFalse;
+            }
+        }
+
+    CleanupStack::PopAndDestroy( wvids ); // wvids
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::DoBlockRequestL()
+// Execute block entity request with given arguments.
+// ---------------------------------------------------------
+//
+TInt CCABlockingManager::DoBlockRequestL( const CDesCArray* aInsertBlockList,
+                                          const CDesCArray* aRemoveBlockList,
+                                          const CDesCArray* aInsertGrantList,
+                                          const CDesCArray* aRemoveGrantList,
+                                          const CDesCArray* aAdditionalData,
+                                          TOperationRequests aRequest )
+    {
+    // check argument validity
+    if ( aRequest != EBlockRequest && aRequest != EUnBlockRequest )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    TBool grantUsed = GrantListInUse();
+
+    // Create the request but do not start the synchronous wait yet ( EFalse )
+    CCARequest* request = iRequestMapper->CreateRequestL(
+                              iImpsFactory->CreateImClientL()->BlockEntityRequestL(
+                                  aInsertBlockList,
+                                  aRemoveBlockList,
+                                  ETrue,
+                                  aInsertGrantList,
+                                  aRemoveGrantList,
+                                  grantUsed ),
+                              EFalse );
+
+    request->SetRequestType( aRequest );
+
+    // empty array, so granularity of one
+    CDesCArrayFlat* emptyArray = new( ELeave )CDesCArrayFlat( 1 );
+    CleanupStack::PushL( emptyArray );
+
+    // set correct array based on request to additional data
+    const CDesCArray *tempArrayPtr = NULL;
+    tempArrayPtr = emptyArray;
+
+    if ( aAdditionalData )
+        {
+        tempArrayPtr = aAdditionalData;
+        }
+
+    request->SetAdditionalData( *tempArrayPtr );
+
+    // Now when the request type and additional data is set we can
+    // activate the synchronous wait
+    request->StartWait();
+
+    // Execution continues from here
+    TInt errorCode( request->ErrorCode() );
+
+    CHAT_DP( D_CHAT_LIT( "   Error code in DoBlockRequestL is %d" ), errorCode );
+
+    iRequestMapper->RemoveRequest( request );
+    CleanupStack::PopAndDestroy( emptyArray );
+
+    return errorCode;
+
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::IsContactBlocked
+// ---------------------------------------------------------
+//
+TBool CCABlockingManager::IsContactBlocked(
+    const TDesC& aContact,
+    TBool aUseGrant /*= EFalse*/ ) const
+    {
+    CHAT_DP_FUNC_ENTER( "IsContactBlocked" );
+    CHAT_DP( D_CHAT_LIT(
+                 "CCABlockingManager::IsContactBlocked - Checking contact %S" ),
+             &aContact );
+
+    MCAStoredContact* contact = iStoredContacts->FindAnyContact( aContact );
+
+    // default to allowing the contact if it gets through
+    // the switch-case
+    TBool retVal( EFalse );
+
+    MCASettings::TCASettingValues strategy =
+        iCanUseGrant ? iStrategy : MCASettings::EAll;
+    switch ( strategy )
+        {
+        case MCASettings::EAll:
+            CHAT_DP_FUNC_DP( "IsContactBlocked", "Strategy is Grant all" );
+                {
+                // grant list not in use, allow all
+                // but note the blocklist
+                if ( !contact )
+                    {
+                    CHAT_DP_FUNC_DP( "IsContactBlocked", "Contact is not a friend" );
+                    retVal = InternallyBlocked( aContact );
+                    }
+                else
+                    {
+                    CHAT_DP_FUNC_DP( "IsContactBlocked", "Contact is a friend" );
+                    retVal = contact->IsBlocked();
+                    }
+                break;
+                }
+
+        case MCASettings::EFriends:
+            {
+            CHAT_DP_FUNC_DP( "IsContactBlocked", "Strategy is Grant friends" );
+            // friends are granted according to block status
+            if ( contact )
+                {
+                CHAT_DP_FUNC_DP( "IsContactBlocked", "Contact is a friend" );
+                retVal = contact->IsBlocked();
+                }
+            else
+                {
+                if ( aUseGrant )
+                    {
+                    // Check grantlist, because there might be some
+                    // contacts in grant list.
+                    CHAT_DP_FUNC_DP( "IsContactBlocked",
+                                     "Contact is not friend but might in grant list" );
+                    // Other than friends could be in grant list
+                    // because temporary grant.
+                    retVal = !IsContactGranted( aContact );
+                    }
+                else
+                    {
+                    retVal = InternallyBlocked( aContact );
+                    }
+                }
+            break;
+            }
+        case MCASettings::ENobody:
+            {
+            CHAT_DP_FUNC_DP( "IsContactBlocked", "Strategy is Grant none, but \
+                         someone could be in grant list." );
+            // Some one could be in grant list because temporary grant.
+            if ( aUseGrant )
+                {
+                retVal = !IsContactGranted( aContact );
+                }
+            else
+                {
+                retVal = InternallyBlocked( aContact );
+                }
+            break;
+            }
+
+        default:
+            {
+            // bogus value!
+            CHAT_DP_FUNC_DP( "IsContactBlocked",
+                             "Bogus grant strategy, defaulting to allow all" );
+            retVal = EFalse;
+            break;
+            }
+        }
+
+    CHAT_DP_FUNC_DONE( "IsContactBlocked" );
+    return retVal;
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::ContactListChangedL
+// ---------------------------------------------------------
+//
+void CCABlockingManager::ContactListChangeL( TBool aUpdateInProgress )
+    {
+    iUpdateInProgress = aUpdateInProgress;
+
+    if ( iUpdateInProgress )
+        {
+        return;
+        }
+
+    TInt count( iBlockedList->MdcaCount() );
+    for ( TInt a( 0 ); a < count; ++a )
+        {
+        iStoredContacts->SetBlocked( iBlockedList->MdcaPoint( a ), ETrue );
+        }
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::HandleCompleteL
+// ---------------------------------------------------------
+//
+void CCABlockingManager::HandleCompleteL(
+    TInt aOperationId,
+    TImpsCspIdentifier& /* aCspId */ )
+    {
+    TInt status( KErrNone );
+
+    TRAPD( err, DoHandleCompleteL( aOperationId, status ) );
+    if ( err != KErrNone )
+        {
+        status = err;
+        }
+    iRequestMapper->HandleRequest( aOperationId, status );
+
+    User::LeaveIfError( err );
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::DoHandleCompleteL
+// ---------------------------------------------------------
+//
+void CCABlockingManager::DoHandleCompleteL(
+    TInt aOperationId,
+    TInt aStatus )
+    {
+    CHAT_DP_TXT( "CCABlockingManager::HandleCompleteL...starts" );
+    CHAT_DP( D_CHAT_LIT( "   aStatus is %d" ), aStatus );
+
+    // Find the request
+    const CCARequest* request = iRequestMapper->FindRequest( aOperationId );
+
+    if ( request )
+        {
+        // check if this was block request or unblock request
+        TBool blockRequest = ETrue;
+        if ( request->RequestType() == EUnBlockRequest )
+            {
+            blockRequest = EFalse;
+            }
+        // set requested contacts as blocked
+        TInt itemInArray( request->AdditionalData()->MdcaCount() );
+
+        for ( TInt i( 0 ); i < itemInArray; i++ )
+            {
+            TPtrC userId =
+                TPtrC( request->AdditionalData()->MdcaPoint( i ) );
+
+            // block and save state in persistent storage
+            iStoredContacts->SetBlocked( userId, blockRequest );
+
+            if ( blockRequest )
+                {
+                AddToBlockListL( userId );
+                }
+            else
+                {
+                RemoveFromBlockList( userId );
+                }
+            }
+        }
+
+    CHAT_DP_TXT( "CCABlockingManager::HandleCompleteL...over" );
+    }
+
+
+
+// ---------------------------------------------------------
+// CCABlockingManager::GetBlockedListResponseL
+// ---------------------------------------------------------
+//
+void CCABlockingManager::GetBlockedListResponseL(
+    const MDesCArray* aBlockedList,
+    TBool aBlockedListInUse,
+    const MDesCArray* aGrantedList,
+    TBool aGrantedListInUse,
+    TImpsCspIdentifier& /* aCspId */ )
+    {
+    TRAPD( err, DoGetBlockedListResponseL( aBlockedList, aBlockedListInUse,
+                                           aGrantedList, aGrantedListInUse ) );
+
+    if ( iGetBlockedListOpId != 0 )
+        {
+        CHAT_DP_FUNC_DP( "GetBlockedListResponseL", "Going to HandleRequest" ) ;
+        iRequestMapper->HandleRequest( iGetBlockedListOpId, err );
+        iGetBlockedListOpId = 0;
+        }
+
+    User::LeaveIfError( err );
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::DoGetBlockedListResponseL
+// ---------------------------------------------------------
+//
+void CCABlockingManager::DoGetBlockedListResponseL(
+    const MDesCArray* aBlockedList,
+    TBool /* aBlockedListInUse */,
+    const MDesCArray* aGrantedList,
+    TBool /* aGrantedListInUse */ )
+    {
+    CHAT_DP_FUNC_ENTER( "GetBlockedListResponseL" );
+
+    switch ( iMgrState )
+        {
+        case EStateNormal :
+            {
+            CHAT_DP_FUNC_DP( "GetBlockedListResponseL", "EStateNormal" );
+
+            if ( aBlockedList )
+                {
+                // nuke the internal list
+                iBlockedList->Reset();
+                if ( aBlockedList->MdcaCount() > 0 )
+                    {
+                    // now block the selected contacts, if there are any
+                    CHAT_DP_FUNC_DP( "GetBlockedListResponseL",
+                                     "Updating blocking status" );
+
+                    TInt count( aBlockedList->MdcaCount() );
+                    CHAT_DP( D_CHAT_LIT(
+                                 "CCABlockingManager::GetBlockedListResponseL \
+                    - Blocked count %d" ), count );
+
+#ifdef IMPS_CONTACT_FETCH_BACKGROUND
+                    TBool needToObserve = EFalse;
+                    TBool syncReady = EFalse;
+#endif // IMPS_CONTACT_FETCH_BACKGROUND                    
+                    for ( TInt i( 0 ); i < count; ++i )
+                        {
+                        TPtrC userId = TPtrC( aBlockedList->MdcaPoint( i ) );
+
+                        CHAT_DP( D_CHAT_LIT(
+                                     "CCABlockingManager::GetBlockedListResponseL \
+                        - Contact %S" ), &userId );
+
+                        // it's blocked, so remember it
+                        AddToBlockListL( userId );
+
+#ifndef IMPS_CONTACT_FETCH_BACKGROUND
+                        iStoredContacts->SetBlocked( userId, ETrue );
+#else
+                        // Contact list sync state must be checked.
+                        // If list sync is not finished mark blocked ids
+                        // while sync progresses.
+                        if ( !needToObserve )
+                            {
+                            MCAContactLists* listInterface =
+                                CAPresenceManager::InstanceL()->ContactLists();
+                            TBool syncDone = EFalse;
+                            if ( listInterface )
+                                {
+                                syncDone = listInterface->IsSyncDone();
+                                }
+                            TBool ignoreFailed = ETrue;
+                            if ( !iStoredContacts->IsAllSynchronised( ignoreFailed )
+                                 || !syncDone )
+                                {
+                                // Sync not done, observe it through stored
+                                // contacts interface
+                                needToObserve = ETrue;
+                                }
+                            else
+                                {
+                                // Sync done
+                                syncReady = ETrue;
+                                }
+                            }
+                        if ( syncReady )
+                            {
+                            // Sync done, ids can be blocked directly
+                            iStoredContacts->SetBlocked( userId, ETrue );
+                            }
+#endif // IMPS_CONTACT_FETCH_BACKGROUND
+                        }
+
+#ifdef IMPS_CONTACT_FETCH_BACKGROUND
+                    if ( needToObserve )
+                        {
+                        // Observe fetching.
+                        // Blocked ids are marked in HandleChange method.
+                        iStoredContacts->AddObserverL( this );
+                        }
+#endif // IMPS_CONTACT_FETCH_BACKGROUND                    
+                    }
+                }
+            iGrantedList->Reset();
+            if ( aGrantedList )
+                {
+                // copy the granted list
+                CHAT_DP_FUNC_DP( "GetBlockedListResponseL",
+                                 "Copying grantlist" );
+                const TInt count( aGrantedList->MdcaCount() );
+                for ( TInt i = 0; i < count; i++ )
+                    {
+                    iGrantedList->AppendL( aGrantedList->MdcaPoint( i ) );
+                    }
+                }
+            break;
+            }
+
+        case EStateDeletingGrantList :
+            {
+            CHAT_DP_FUNC_DP( "GetBlockedListResponseL",
+                             "EStateDeletingGrantList" );
+            // copy the returned grant list into an internal structure
+            iGrantedList->Reset();
+            if ( aGrantedList )
+                {
+                // copy the granted list
+                CHAT_DP_FUNC_DP( "GetBlockedListResponseL",
+                                 "Copying grantlist" );
+                const TInt count( aGrantedList->MdcaCount() );
+                for ( TInt i = 0; i < count; i++ )
+                    {
+                    iGrantedList->AppendL( aGrantedList->MdcaPoint( i ) );
+                    }
+                }
+            else
+                {
+                // we should have gotten it
+                CHAT_DP_FUNC_DP( "GetBlockedListResponseL",
+                                 "Grantlist was NULL, assuming it's empty" );
+                }
+            break;
+            }
+
+        default:
+            {
+            CHAT_DP_FUNC_DP( "GetBlockedListResponseL", "Invalid state" );
+            break;
+            }
+        }
+
+    CHAT_DP_FUNC_DONE( "GetBlockedListResponseL" );
+    }
+
+// clear the grant list
+void CCABlockingManager::ClearGrantListL( TBool aForceUpdate /* = EFalse */ )
+    {
+    // fetch the lists
+    iMgrState = EStateDeletingGrantList;
+    GetBlockedListFromServerL();
+
+    // ungrant all of the returned grant list people,
+    // effectively clearing the grant list
+    CDesCArray* clone = CloneArrayLC( *iGrantedList );
+    iGrantedList->Reset();
+    RemoveL( NULL, clone, aForceUpdate );
+    CleanupStack::PopAndDestroy( clone );
+
+    // RemoveL return value ignored, because if remove fails
+    // engine gets callback HandleErrorL, if removeL is succeed
+    // CCABlockingManager gets callback HandleCompleteL
+
+    // that's it grant list is cleared
+    iMgrState = EStateNormal;
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::HandleSettingsChangeL
+// ---------------------------------------------------------
+//
+void CCABlockingManager::HandleSettingsChangeL( TInt aChangedSettingEnum )
+    {
+    CHAT_DP_FUNC_ENTER( "HandleSettingsChangeL" );
+
+    if ( aChangedSettingEnum != MCASettings::EReceiveIMessages )
+        {
+        // it's not for us
+        CHAT_DP_FUNC_DP( "HandleSettingsChangeL",
+                         "Got event but it was not for me" );
+        return;
+        }
+
+    MCASettings::TCASettingValues newValue = ( MCASettings::TCASettingValues )
+                                             iSettingsManager->Value( MCASettings::EReceiveIMessages );
+
+    CHAT_DP( D_CHAT_LIT( "CCABlockingManager::HandleSettingsChangeL - \
+                        Current %d, new %d" ), iStrategy, newValue );   // CSI: 62 # Not valid, new inside debug print.
+
+    if ( newValue == iStrategy )
+        {
+        CHAT_DP_FUNC_DP( "HandleSettingsChangeL",
+                         "Unchanged setting state for grantlist strategy" );
+        return;
+        }
+
+    CHAT_DP( D_CHAT_LIT( "CCABlockingManager::HandleSettingsChangeL - \
+                        BackGroundTaskReady %d" ), iBackgroundTaskReady );
+    if ( !iBackgroundTaskReady ) // haven't runned the backgroundtask yet.
+        {
+        return;
+        }
+
+    iStrategy = newValue;
+    if ( !iLoggedIn )
+        {
+        // not logged in -> return
+        return;
+        }
+
+    // the changed settings effects us
+    MCASettings::TCASettingValues strategy =
+        iCanUseGrant ? newValue : MCASettings::EAll;
+
+    switch ( strategy )
+        {
+        case MCASettings::EAll :
+            {
+            CHAT_DP_FUNC_DP( "HandleSettingsChangeL", "Blocklist only" );
+            // only blocklist active. it should be up-to-date.
+            InsertL( iBlockedList, NULL, ETrue );
+            break;
+            }
+
+        case MCASettings::EFriends :
+            {
+            CHAT_DP_FUNC_DP( "HandleSettingsChangeL",
+                             "Blocklist with grantlist" );
+            // blocklist with grantlist
+            CDesCArray* clone = CloneArrayLC( *iGrantedList );
+            GrantFriendsL();
+            // Check new ids to be granted
+            CDesCArray* diff = CreateNeutralDiffLC( *iGrantedList,
+                                                    *clone );
+            // Check if clone contains more ids than we have friends
+            CDesCArray* diff2 = CreateNeutralDiffLC( *clone,
+                                                     *iGrantedList );
+            iGrantedList->Reset();
+            // Remove grant from excess ids
+            RemoveL( NULL, diff2, ETrue );
+            // Add grant for new ids
+            InsertL( NULL, diff, ETrue );
+            CleanupStack::PopAndDestroy( 3, clone ); // clone, diff, diff2
+            break;
+            }
+
+        case MCASettings::ENobody :
+            {
+            CHAT_DP_FUNC_DP( "HandleSettingsChangeL", "Granting nobody" );
+            // grantlist empty == decline all messages
+
+            // empty the grant list
+            ClearGrantListL( ETrue );
+            break;
+            }
+
+        default :
+            {
+            // bogus
+            break;
+            }
+        }
+
+    CHAT_DP_FUNC_DONE( "HandleSettingsChangeL" );
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::AddToBlockListL
+// add to internal blocking list
+// ---------------------------------------------------------
+//
+void CCABlockingManager::AddToBlockListL( const TDesC& aId )
+    {
+    CHAT_DP_FUNC_ENTER( "AddToBlockListL" );
+
+    TInt position( KErrNotFound );
+    if ( iBlockedList->Find( aId, position, ECmpCollated ) == 0 )
+        {
+        // found it, don't add a duplicate
+        CHAT_DP_FUNC_DP( "AddToBlockListL", "Contact already in blocked list" );
+        return;
+        }
+
+    // didn't find it, so add it
+    iBlockedList->AppendL( aId );
+
+    CHAT_DP_FUNC_DONE( "AddToBlockListL" );
+    }
+
+
+// ---------------------------------------------------------
+// CCABlockingManager::RemoveFromBlockList
+// remove from internal blocking list
+// ---------------------------------------------------------
+//
+void CCABlockingManager::RemoveFromBlockList( const TDesC& aId )
+    {
+    CHAT_DP_FUNC_ENTER( "RemoveFromBlockListL" );
+
+#ifdef _DEBUG
+    TPtrC myDebug( aId );
+    CHAT_DP( D_CHAT_LIT( "CCABlockingManager::RemoveFromBlockListL\
+	                      looking for %S" ), &myDebug );
+#endif
+
+    TInt count( iBlockedList->MdcaCount() );
+    for ( TInt a( 0 ); a < count; ++a )
+        {
+#ifdef _DEBUG
+        myDebug.Set( iBlockedList->MdcaPoint( a ) );
+        CHAT_DP( D_CHAT_LIT( "CCABlockingManager::RemoveFromBlockListL \
+		                     we have %S" ), &myDebug );
+#endif
+        if ( 0 == CAUtils::NeutralCompare( iBlockedList->MdcaPoint( a ), aId ) )
+            {
+            // found it, remove it
+            CHAT_DP_FUNC_DP( "RemoveFromBlockListL",
+                             "Found internally blocked contact" );
+            iBlockedList->Delete( a );
+            iBlockedList->Compress();
+            CHAT_DP_FUNC_DONE( "RemoveFromBlockListL" );
+            return;
+            }
+        }
+    CHAT_DP_FUNC_DONE( "RemoveFromBlockListL" );
+    }
+
+
+// ---------------------------------------------------------
+// CCABlockingManager::InternallyBlocked
+// see if contact is internally blocked or not
+// ---------------------------------------------------------
+//
+TBool CCABlockingManager::InternallyBlocked( const TDesC& aId ) const
+    {
+    CHAT_DP_FUNC_ENTER( "InternallyBlocked" );
+
+#ifdef _DEBUG
+    TPtrC myDebug( aId );
+    CHAT_DP( D_CHAT_LIT( "CCABlockingManager::InternallyBlocked \
+	                      looking for %S" ), &myDebug );
+#endif
+
+    TInt count( iBlockedList->MdcaCount() );
+    for ( TInt a( 0 ); a < count; ++a )
+        {
+#ifdef _DEBUG
+        myDebug.Set( iBlockedList->MdcaPoint( a ) );
+        CHAT_DP( D_CHAT_LIT( "CCABlockingManager::InternallyBlocked we have %S" ),
+                 &myDebug );
+#endif
+        if ( 0 == CAUtils::NeutralCompare( iBlockedList->MdcaPoint( a ), aId ) )
+            {
+            CHAT_DP_FUNC_DONE( "InternallyBlocked" );
+            return ETrue;
+            }
+        }
+
+    CHAT_DP_FUNC_DONE( "InternallyBlocked" );
+    return EFalse;
+    }
+
+
+// ---------------------------------------------------------
+// CCABlockingManager::HandleNetworkStateChange
+// ---------------------------------------------------------
+//
+void CCABlockingManager::HandleNetworkStateChange( TNetworkState aState,
+                                                   TBool aCanUseGrant )
+    {
+    CHAT_DP_FUNC_ENTER( "HandleNetworkState" );
+    CHAT_DP( D_CHAT_LIT( "New state is: %d" ), aState );
+
+    iCanUseGrant = aCanUseGrant;
+
+    if ( aState == ELoggedIn )
+        {
+        iLoggedIn = ETrue;
+        //just make sure its not started yet
+        if ( iRequestMapper->BackgroundTaskStatus(
+                 MCABackgroundInterface::EBlockGrantListFetch ) &
+             ( MCABackgroundInterface::EUnknown |
+               MCABackgroundInterface::ECompleted |
+               MCABackgroundInterface::ECancelled |
+               MCABackgroundInterface::EFailed
+             ) )
+            {
+            CHAT_DP_TXT( "CCABlockingManager::HandleNetworkStateChange \
+			              registering block list fetch" );
+
+#ifdef RD_SETTINGS_FACELIFT
+            // Make sure we have the correct settings value.
+            // With settings facelift enabled it is possible to
+            // edit settings of any server. If user edits settings
+            // for some other server than the default server, notification
+            // is not observed here -> getting value here is needed.
+            iStrategy = ( MCASettings::TCASettingValues )
+                        iSettingsManager->Value( MCASettings::EReceiveIMessages );
+#endif
+
+            iRequestMapper->RegisterBackgroundTask(
+                this, MCABackgroundInterface::EBlockGrantListFetch );
+            iBackgroundTaskReady = EFalse;
+            }
+        }
+    if ( aState == ELoggedOut )
+        {
+        iLoggedIn = EFalse;
+        }
+    CHAT_DP_FUNC_DONE( "HandleNetworkState" );
+    }
+
+
+// ---------------------------------------------------------
+// CCABlockingManager::HandleBackgroundTaskL
+// ---------------------------------------------------------
+//
+void CCABlockingManager::HandleBackgroundTaskL( TInt aSubTask )
+    {
+    CHAT_DP_FUNC_ENTER( "HandleBackgroundTaskL" );
+    CHAT_DP( D_CHAT_LIT( "CCABlockingManager::HandleBackgroundTaskL \
+	                      Subtask is: %d" ), aSubTask );
+
+
+    TInt error = GetBlockedListFromServerL();
+
+    iBackgroundTaskReady = ETrue;
+
+    CHAT_DP_FUNC_DONE( "HandleBackgroundTaskL" );
+
+    if ( error )
+        {
+        User::Leave( error );
+        }
+
+    }
+// ---------------------------------------------------------
+// CCABlockingManager::HandleContactDelete
+// ---------------------------------------------------------
+//
+void CCABlockingManager::HandleContactDelete( const TDesC& /*aContactId*/ )
+    {
+    // Not used
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::HandleAddition
+// ---------------------------------------------------------
+//
+void CCABlockingManager::HandleAddition( MCAContactList& /*aList*/,
+                                         MCAStoredContact& /*aContact*/ )
+    {
+    // Not used
+    }
+
+// ---------------------------------------------------------
+// CCABlockingManager::HandleChange
+// ---------------------------------------------------------
+//
+void CCABlockingManager::HandleChange(
+    MCAContactList* /*aList*/,
+    MCAStoredContact* /*aContact*/,
+    TStorageManagerGlobals::TCAObserverEventType aEventType,
+    TBool /*aUserIdChanged*/ )
+    {
+    if ( !iLoggedIn )
+        {
+        // Logout event received, stop observing
+        iStoredContacts->RemoveObserver( this );
+        return;
+        }
+
+    // Mark contacts blocked as they are fetched
+    if ( aEventType == TStorageManagerGlobals::EStorageEventMultipleChanges )
+        {
+        MCAContactList* currentList = NULL;
+        TRAPD( err, currentList = &iStoredContacts->ListInSyncProcessL() );
+        if ( err == KErrNone && currentList )
+            {
+            // Sync not yet ready means that contact adding is going on
+            // -> check list for blocked ids
+            if ( currentList->Synchronised() == MCAContactList::ESynchroniseNotDone )
+                {
+                TInt blockCount = iBlockedList->Count();
+                for ( TInt i = 0; i < blockCount; i++ )
+                    {
+                    TPtrC userId = iBlockedList->MdcaPoint( i );
+                    TPtrC listId = currentList->ListId();
+                    iStoredContacts->SetBlocked( userId, listId, ETrue );
+                    }
+                }
+            }
+        }
+
+    // Check if sync has ended
+    TBool failed = EFalse;
+    TBool syncDone = EFalse;
+
+    TRAP_IGNORE(
+        MCAContactLists* listInterface =
+            CAPresenceManager::InstanceL()->ContactLists();
+        syncDone = listInterface->IsSyncDone();
+    );  // TRAP_IGNORE
+
+    if ( iStoredContacts->IsAllSynchronised( failed ) &&
+         syncDone )
+        {
+        if ( !failed )
+            {
+            // Sync done and no failed lists, no need to observe anymore
+            iStoredContacts->RemoveObserver( this );
+            }
+        // If there were failed lists keep on observing for
+        // the possible re-fetching of the failed lists.
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCABlockingManager::SetTemporaryGrantL
+// Temporary grant, permanent unblock.
+// -----------------------------------------------------------------------------
+//
+TInt CCABlockingManager::SetTemporaryGrantL( const TDesC& aContact, TBool aOn )
+    {
+    //Creating list of unblocked users
+    CDesCArrayFlat* unBlockList =
+        new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
+    CleanupStack::PushL( unBlockList );
+
+    // unBlockList is those persons who are going to be unblocked
+    unBlockList->AppendL( aContact );
+
+    TInt errorCode( KErrNone );
+    if ( aOn )
+        {
+        if ( GrantListInUse() )
+            {
+            errorCode = InsertL( NULL, unBlockList );
+            }
+        TInt temp( RemoveL( unBlockList, NULL ) );
+        if ( temp != KErrNone && errorCode == KErrNone )
+            {
+            errorCode = temp;
+            }
+        }
+    else
+        {
+        MCAStoredContact* contact = iStoredContacts->FindAnyContact( aContact );
+        if ( !( contact && iStrategy == MCASettings::EFriends ) )
+            {
+            errorCode = RemoveL( NULL, unBlockList );
+            }
+        }
+
+    CleanupStack::PopAndDestroy( unBlockList );
+
+    return errorCode;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCABlockingManager::IsContactGranted
+// Check if contact is granted or not.
+// -----------------------------------------------------------------------------
+//
+TBool CCABlockingManager::IsContactGranted( const TDesC& aContact ) const
+    {
+    TInt count( iGrantedList->MdcaCount() );
+    for ( TInt a( 0 ); a < count; ++a )
+        {
+        if ( 0 == CAUtils::NeutralCompare( iGrantedList->MdcaPoint( a ),
+                                           aContact ) )
+            {
+            return ETrue;
+            }
+        }
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CCABlockingManager::CloneArrayLC
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CDesCArray* CCABlockingManager::CloneArrayLC( const MDesCArray& aSource )
+    {
+    TInt count( aSource.MdcaCount() );
+    CDesCArray* array = new( ELeave )CDesCArrayFlat( count == 0 ? 1 : count );
+    CleanupStack::PushL( array );
+    for ( TInt i( 0 ); i < count; ++i )
+        {
+        TPtrC text( aSource.MdcaPoint( i ) );
+        CHAT_DP( D_CHAT_LIT( " CloneArrayLC [%d] %S" ), i, &text );
+        array->AppendL( text );
+        }
+    CHAT_DP_TXT( "----------------------[endClone]----------------------" );
+    return array;
+    }
+
+// -----------------------------------------------------------------------------
+// CCABlockingManager::CreateNeutralDiffLC
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CDesCArray* CCABlockingManager::CreateNeutralDiffLC(
+    const MDesCArray& aArrayDiff,
+    const MDesCArray& aArrayTest )
+    {
+    CDesCArray* array = new( ELeave )CDesCArrayFlat( KArrayGranularity );
+    CleanupStack::PushL( array );
+    TInt count( aArrayDiff.MdcaCount() );
+    for ( TInt i( 0 ); i < count; ++i )
+        {
+        TPtrC id( aArrayDiff.MdcaPoint( i ) );
+        TInt count2( aArrayTest.MdcaCount() );
+        TInt flag( EFalse );
+
+        for ( TInt j( 0 ); j < count2 && !flag; ++j )
+            {
+            if ( CAUtils::NeutralCompare( id, aArrayTest.MdcaPoint( j ) ) == 0 )
+                {
+                flag = ETrue;
+                }
+            }
+        if ( !flag )
+            {
+            // item that is in aArrayDiff, but not in aArrayTest
+            // add to resulting array if it does not exist in resulting array
+            TInt count3( array->MdcaCount() );
+            for ( TInt k( 0 ); k < count3 && !flag; ++k )
+                {
+                if ( CAUtils::NeutralCompare( id, array->MdcaPoint( k ) ) == 0 )
+                    {
+                    flag = ETrue;
+                    }
+                }
+
+            if ( !flag )
+                {
+                CHAT_DP( D_CHAT_LIT( " CreateDiffLC [%d] %S" ), i, &id );
+                array->AppendL( id );
+                }
+            }
+        }
+    CHAT_DP_TXT( "-----------------------[endDiff]----------------------" );
+    return array;
+    }
+
+// -----------------------------------------------------------------------------
+// CCABlockingManager::AddToGrantedListL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCABlockingManager::AddToGrantedListL( const MDesCArray& aInsertArray )
+    {
+    TInt count( aInsertArray.MdcaCount() );
+    for ( TInt a( 0 ); a < count && !iUpdateInProgress; ++a )
+        {
+        iGrantedList->AppendL( aInsertArray.MdcaPoint( a ) );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCABlockingManager::RemoveFromGrantedListL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCABlockingManager::RemoveFromGrantedList( CDesCArray& aRemoveArray )
+    {
+    TInt count( aRemoveArray.MdcaCount() );
+    for ( TInt a( --count ); a >= 0 && !iUpdateInProgress; --a )
+        {
+        TInt grantedCount( iGrantedList->MdcaCount() );
+        TBool foundFlag( EFalse );
+        TBool foundOther( EFalse );
+        TPtrC id( aRemoveArray.MdcaPoint( a ) );
+
+        for ( TInt b( --grantedCount ); b >= 0 && !foundOther; --b )
+            {
+            TPtrC id2( iGrantedList->MdcaPoint( b ) );
+            if ( CAUtils::NeutralCompare( id, id2 ) == 0 )
+                {
+                if ( !foundFlag )
+                    {
+                    // Delete current position
+                    iGrantedList->Delete( b );
+                    foundFlag = ETrue;
+                    }
+                else
+                    {
+                    foundOther = ETrue;
+                    }
+                }
+            }
+        if ( foundOther )
+            {
+            aRemoveArray.Delete( a );
+            }
+        }
+    }
+// -----------------------------------------------------------------------------
+// CCABlockingManager::SetAppUiExitFlag
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCABlockingManager::SetAppUiExitFlag( TBool aFlag )
+	{
+	iAppUiExit = aFlag;
+	}
+// end of file