--- /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