diff -r 000000000000 -r 094583676ce7 wvuing/wvuieng/EngSrc/CCABlockingManager.cpp --- /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 + +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