diff -r 000000000000 -r 094583676ce7 wvuing/wvcommandutils/Src/CCASessionHandlerCmd.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wvuing/wvcommandutils/Src/CCASessionHandlerCmd.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,1579 @@ +/* +* Copyright (c) 2006 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: Network session handling (login, logout, etc.) +* +*/ + + + +// INCLUDE FILES +#include "CCASessionHandlerCmd.h" +#include "ChatDebugPrint.h" +#include "MCAImpsFundClient.h" +#include "CCAEngine.h" +#include "mcagroupmanagerinterface.h" +#include "MCAContactLists.h" +#include "MCAPresence.h" +#include "CAPresenceManager.h" +#include "MCAStoredContact.h" +#include "MCAStoredContacts.h" +#include "CCAStorageManagerFactory.h" +#include "ImpsCSPAllErrors.h" +#include "MCASettings.h" +#include "MCAChatInterface.h" +#include "MCAContactFetchObserver.h" +#include "MCAAccessInterface.h" +#include "mcaservicestateobserver.h" + +#include "MCABackgroundTaskObserver.h" +#include "SServerPrefers.h" +#include "impsbuilddefinitions.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "IMUtils.h" +#include "IMDialogUtils.h" +#include "IMNoteMapper.h" +#include "CCACommandManagerFactory.h" +#include "CCACommandManager.h" +#include "MCALoginPC.h" +#include "MCAProcessManager.h" +#include "MCASettingsPC.h" +#include "MCAConversationPC.h" +#include "MCAUiLoginCmdCB.h" + +// The Settings have been moved to Cenrep (also retained in the Resource file) +// so the enums for keys and central repository header is added here + +#include "VariantKeys.h" + + +// CONSTANTS +// defines whether first login to server has been done +_LIT( KIMFirstLoginToServer, "IMFirstLoginToServer" ); + + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::CCASessionHandlerCmd +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CCASessionHandlerCmd::CCASessionHandlerCmd( + MCAProcessManager& aProcessManager, + MCAUiLoginCmdCB& aUiLoginCmdCB ) + : iLastState( EIMPSPresenceServiceUnknownEvent ), + iPresenceInitializationSuccesfull( EFalse ), + iIsContactFetchDone( EFalse ), + iProcessManager( aProcessManager ), + iUiLoginCmdCB( aUiLoginCmdCB ), + + iBackgroundTaskRunning( ETrue ) + { + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CCASessionHandlerCmd::ConstructL() + { + + iProfileApi = CreateProfileEngineL(); + + iConnUI = CIMPSPresenceConnectionUi::NewL( EIMPSConnClientIM ); + + iConnUIEventNotifier = CIMPSConnUiClntFilteredPresEventNotifier::NewL( + EIMPSConnClientIM ); + iConnUIEventNotifier->AddObserverL( this ); + + iConnUIEventNotifier->StartL(); + + iUiLoginCmdCB.SetStatusPaneIconsL(); + + + MCAPresence* presence = CAPresenceManager::InstanceL(); + + + if ( IsLoggedIn() ) + // If already logged in, just update engine state and fetch contact lists + { + + iBackgroundTaskRunning = EFalse; + + // we can ignore the returnvalue here, + // since the member variable is set inside anyway + NetworkSessionSlotIDL(); + TRAPD( err, presence->InitializePresenceAPIL( *iSessionSlotID ) ); + + // ATM only occasion for this to fail is that PEC has not fully + // synchronized contact lists. We will get online event when the + // lists are in sync. + if ( err == KErrNone ) + { + iPresenceInitializationSuccesfull = ETrue; + + TBool redraw( GetServicesL() ); + + iUiLoginCmdCB.SetIMPSServices( iImpsServices, ETrue, redraw ); + + // make sure chat has been constructed before notifying + // the engine. if we're logged in, IMPS server should be up, + // so this is fast + iUiLoginCmdCB.FinalizeChatConstructionL(); + + NotifyEngineL( ELoggedIn, iSessionSlotID ); + + + iUiLoginCmdCB.CaptureEventsL(); + + // Idle loop for starting default list selection + + delete iSelectIdle; + iSelectIdle = NULL; + iSelectIdle = CIdle::NewL( CActive::EPriorityIdle ); + iSelectIdle->Start( TCallBack( BackgroundSelect, this ) ); + + + // set variated settings + TRAPD( err, UpdateDefaultSettingsL() ); + if ( err != KErrNone ) // Signal user about error + { + CActiveScheduler::Current()->Error( err ); + } + + + // Store current logged in SAP as previous + CIMPSSAPSettings* temp = CurrentSAPLC(); + iPreviousSAP = temp; // Take ownership + CleanupStack::Pop( temp ); + } + } + else + { +#ifndef CHAT_UNIT_TEST + // Idle loop for starting login sequence login + iIdle = CIdle::NewL( CActive::EPriorityIdle ); + iIdle->Start( TCallBack( BackgroundTasks, this ) ); +#endif + } + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CCASessionHandlerCmd* CCASessionHandlerCmd::NewL( + MCAProcessManager& aProcessManager, + MCAUiLoginCmdCB& aUiLoginCmdCB ) + { + CCASessionHandlerCmd* self = new( ELeave ) CCASessionHandlerCmd( + aProcessManager, + aUiLoginCmdCB ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + + +// Destructor +CCASessionHandlerCmd::~CCASessionHandlerCmd() + { + if ( iProfileApi ) + { + iProfileApi->Release(); + } + + if ( iConnUIEventNotifier ) + { + iConnUIEventNotifier->Stop(); + iConnUIEventNotifier->RemoveObserver( this ); + } + + delete iConnUIEventNotifier; + delete iConnUI; + delete iIdle; + delete iSelectIdle; + + delete iPreviousSAP; + delete iSessionSlotID; + + iFetchObservers.Close(); + iServiceStateObservers.Close(); + + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::IsLoggedIn +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCASessionHandlerCmd::IsLoggedIn() const + { + TBool returnValue( EFalse ); + + if ( IsOfflineProfileOn() ) + { + CHAT_DP( D_CHAT_LIT( + "CCASessionHandlerCmd::IsLoggedIn, offline profile is ON, returning %d" ), + returnValue ); + return returnValue; + } + + + TRAPD( err, returnValue = iConnUI->LoggedInL( EIMPSConnClientIM ) ); + + if ( err ) + { + returnValue = EFalse; + } + + CHAT_DP( D_CHAT_LIT( "CCASessionHandlerCmd::IsLoggedIn returning %d" ), + returnValue ); + + // if there are no slots in the system then we get KErrNotFound + // and we don't show it to the user + if ( ( err != KErrNone ) && ( err != KErrNotFound ) ) + { + CActiveScheduler::Current()->Error( err ); + } + return returnValue; + } + + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::LoginL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCASessionHandlerCmd::LoginL( TBool aAskConfirmation /*= ETrue */, + TBool aIsStartupLogin /*= EFalse */ ) + { + CHAT_DP_TXT( "CCASessionHandlerCmd::LoginL started" ); + + if ( IsOfflineProfileOn() ) + { + IMDialogUtils::DisplayInformationNoteL( R_QTN_OFFLINE_NOT_POSSIBLE ); + return EFalse; + } + + if ( IsLoggedIn() ) + { + return ETrue; // already logged in + } + + TInt ret( EAknSoftkeyNo ); + if ( aAskConfirmation ) + { + TPtrC serverNamePtr( KNullDesC ); + + CIMPSSAPSettings* sap = NULL; + if ( iPreviousSAP ) + { + + // get current SAP + CIMPSSAPSettings* currentSap = CurrentSAPLC(); + delete iPreviousSAP; + + // replace the previous SAP + iPreviousSAP = currentSap; + CleanupStack::Pop( currentSap ); + + + // get the last logged in server name + + serverNamePtr.Set( iPreviousSAP->SAPName() ); + } + else + { + sap = CurrentSAPLC(); + serverNamePtr.Set( sap->SAPName() ); + + + CleanupStack::PopAndDestroy( sap ); + } + // load the promp from lOC file + server name + HBufC* prompt = StringLoader::LoadLC( R_QTN_CHAT_CONNECTION_NEEDED_TO, + serverNamePtr ); + + ret = IMDialogUtils::DisplayQueryDialogL( R_GENERIC_YES_NO_CONFIRMATION_QUERY, + *prompt ); + + CleanupStack::PopAndDestroy( prompt ); + } + + if ( ( ret == EAknSoftkeyOk ) || ( ret == EAknSoftkeyYes ) + || ( !aAskConfirmation ) ) + { + // check if we have valid server data + if ( iUiLoginCmdCB.CheckCurrentServerDataL() ) + { + CHAT_DP_TXT( + "PEC is offline, server data is ok -> execute PEC login" ); + + TIMPSLoginType loginType = LoginType(); // default to manual login + if ( ( loginType == EIMPSAAConnectionStart || + loginType == EIMPSApplicationLaunch ) && + !aIsStartupLogin ) + { + //defaulting to manual if login type is automatic + // since in this case we want to see the server selection dialog + loginType = EIMPSManualLogin; + } + + if ( loginType != EIMPSAAConnectionStart ) + { + iLogging = ETrue; + + if ( aAskConfirmation ) + { + loginType = EIMPSApplicationLaunch; + } + + CPEngNWSessionSlotID2* tempID = CPEngNWSessionSlotID2::NewL(); + delete iSessionSlotID; + iSessionSlotID = tempID; + + iCurrentLoginIsFirst = EFalse; + TInt err = KErrNone; + + if ( aAskConfirmation && iPreviousSAP ) + { + // user want to connect to last logged in server + // hence pass the previous sap + // aAskConfirmation will allow to load from sapsetting any more + err = iConnUI->LoginL( EIMPSConnClientIM, loginType, + *iSessionSlotID, this , iPreviousSAP, aAskConfirmation ) ; + } + else + { + err = iConnUI->LoginL( EIMPSConnClientIM, loginType, + *iSessionSlotID, this ) ; + } + + CHAT_DP( D_CHAT_LIT( + "CCASessionHandlerCmd::LoginL, \ + iConnUI->LoginL( EIMPSConnClientIM, %d ) returned %d" ), + loginType, err ); + iLogging = EFalse; + + if ( err == KErrNone ) + { + + TBool redraw( GetServicesL() ); + + iUiLoginCmdCB.SetIMPSServices( iImpsServices, ETrue, redraw ); + + NotifyEngineL( EServerPrefers ); + + iUiLoginCmdCB.SetStatusPaneIconsL(); + + CCAStorageManagerFactory::ContactListInterfaceL()-> + ResetContactLists(); + + CIMPSSAPSettings* sap = CurrentSAPLC(); + + MCASettingsPC* settingsPC = iProcessManager.GetSettingsInterface(); + settingsPC->SetDefaultSapL( sap ); + CleanupStack::PopAndDestroy( sap ); + } + + iUiLoginCmdCB.FinalizeChatConstructionL(); + + } + } + } + + iUiLoginCmdCB.ReleaseCapturingL(); + return IsLoggedIn(); // Login was perhaps done + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::LogoutL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCASessionHandlerCmd::LogoutL() + { + CHAT_DP_TXT( "CCASessionHandlerCmd::LogoutL started" ); + //Check for background tasks completion. + //only then give perform logout + + if ( !IsBackgroundTaskPendingL() ) + { + + iProcessManager.GetEngine()->CancelAllRequests(); + + return DoLogoutL(); + } + CHAT_DP_TXT( "CCASessionHandler::LogoutL done" ); + + return IsLoggedIn(); + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::LogoutL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- + +TBool CCASessionHandlerCmd::DoLogoutL() + { + CHAT_DP_TXT( "CCASessionHandlerCmd::DoLogoutL started" ); + + MCAStoredContacts* contactsInterface = + CCAStorageManagerFactory::ContactListInterfaceL(); + + contactsInterface->SetContactListLock( ETrue ); + + iLogging = ETrue; + // this should not even be called if there is no session slot ID + if ( iSessionSlotID ) + { + + iProcessManager.GetLogInInterface()->LogoutL(); + iConnUI->LogoutL( *iSessionSlotID, this ); + delete iSessionSlotID; + iSessionSlotID = NULL; + + } + + iLogging = EFalse; + iCurrentLoginIsFirst = EFalse; + NotifyEngineL( ELoggingOut ); + + + contactsInterface->SetContactListLock( EFalse ); + + + CHAT_DP_TXT( "CCASessionHandlerCmd::DoLogoutL done" ); + return IsLoggedIn(); + } + +// --------------------------------------------------------- +// CCASessionHandler::HandleSapAccessEventEventL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::HandleSapAccessEventEventL( const TDesC& aServerName, + const TDesC& aServerURL, + MIMPSConnProcessUi* aConnProcessUi ) + { + iUiLoginCmdCB.HandleSapAccessEventEventL( aServerName, aServerURL, + aConnProcessUi ); + } + + +// --------------------------------------------------------- +// CCASessionHandlerCmd::IsSupported +// (other items were commented in a header). +// --------------------------------------------------------- +// +TBool CCASessionHandlerCmd::IsSupported( TSupportedFeature aFeature ) + { + switch ( aFeature ) + { + case EGroup : + { + return iImpsServices.iGroupFeat.FeatureSupported(); + } + case ESearch : + { + return iImpsServices.iFundamentalFeat.FunctionSupported( + KPEngFFSearchFunction ); + } + case EInvite : + { + return iImpsServices.iFundamentalFeat.FunctionSupported( + KPEngFFInviteFunction ); + } + case EBlock : + { + return iImpsServices.iIMFeat.FunctionSupported( + KPEngIMAuthorFunctions ); + } + case EAttrList : + { + return iImpsServices.iPresenceFeat.FunctionSupported( + KPEngWVAttrListFunction ); + } + case ECLIMod: + { + // contact list creation/deletion is possible only if + // both CCLI and DCLI are supported + TBool returnValue( ETrue ); + returnValue &= + iImpsServices.iPresenceFeat.SubFunctionSupported( KPEngWVSubFuncCCLI ); + returnValue &= + iImpsServices.iPresenceFeat.SubFunctionSupported( KPEngWVSubFuncDCLI ); + return returnValue; + } + case EGroupRejectList: + { + return iImpsServices.iGroupFeat.SubFunctionSupported( + KPEngGRSubFuncREJEC ); + } + default: + { + return EFalse; // Unknown features are not supported + } + } + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::HandlePresenceEventL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCASessionHandlerCmd::HandlePresenceEventL( + CIMPSConnUiPresEventNotifier* /*aNotifier*/, + const CPEngNWSessionSlotID2& /*aSessionSlotID*/, + TIMPSConnectionClient /*aClient*/, + TIMPSPresenceServiceEvent aEvent ) + { + CHAT_DP( D_CHAT_LIT( + "CCASessionHandlerCmd::HandlePresenceEventL, TIMPSPresenceServiceEvent: %d" ), + aEvent ); + + // Same state as previous, no need for action + if ( aEvent == iLastState ) + { + return; + } + + switch ( aEvent ) + { + case EIMPSPresenceServiceUnknownEvent: + { + CHAT_DP_TXT( + "CCASessionHandlerCmd::HandlePresenceEventL\ + ->EIMPSPresenceServiceUnknownEvent" ); + break; + } + case EIMPSPresenceServiceOffline: + { + CHAT_DP_TXT( + "CCASessionHandlerCmd::HandlePresenceEventL\ + ->EIMPSPresenceServiceOffline" ); + iTemporaryNetworkDown = EFalse; + + if ( iLastState != EIMPSPresenceServiceForceLogOut ) + { + NotifyEngineL( ELoggedOut ); + } + + iAlreadyLoggedOut = ETrue; + + iProcessManager.GetLogInInterface()->LogoutL(); + + TRAPD( error, iUiLoginCmdCB.SetStatusPaneIconsL() ); + + iAlreadyLoggedOut = EFalse; + + User::LeaveIfError( error ); + + // nuke all contacts from IM Storage + MCAStoredContacts* contacts = + CCAStorageManagerFactory::ContactListInterfaceL(); + // Update own status item + contacts->OwnStatus().SetOnlineStatus( TStorageManagerGlobals::EOffline ); + // nuke all contacts from IM Storage + contacts->RemoveAllContactsL(); + + iUiLoginCmdCB.IMUIPIConForcedClear(); + + break; + } + case EIMPSPresenceServiceOnline: + { + CHAT_DP_TXT( + "CCASessionHandlerCmd::HandlePresenceEventL \ + ->EIMPSPresenceServiceOnline" ); + + if ( iPresenceInitializationSuccesfull ) + { + // Construction is already done, so no need to do it here + // again. If user have launched IM after contact list + // synchronization and before this online event, we might + // initialize IM twice. + break; + } + + iUiLoginCmdCB.FinalizeChatConstructionL(); + + + if ( !iLogging ) + { + // this login was not initiated by us + // -> we need to refresh the session slot id + CPEngNWSessionSlotID2* tempId = + iConnUI->GetActiveNWSessionSlotIDL( EIMPSConnClientIM ); + delete iSessionSlotID; + iSessionSlotID = tempId; + + CIMPSSAPSettings* sap = CurrentSAPLC(); + MCASettingsPC* settingsPC = iProcessManager.GetSettingsInterface(); + settingsPC->SetDefaultSapL( sap ); + + CleanupStack::PopAndDestroy( sap ); + } + if ( !iTemporaryNetworkDown ) + { + + TBool redraw( GetServicesL() ); + + CAPresenceManager::InstanceL()->InitializePresenceAPIL( + *iSessionSlotID ); + + iUiLoginCmdCB.SetIMPSServices( iImpsServices, ETrue, redraw ); + NotifyEngineL( ELoggedIn, iSessionSlotID ); + + iUiLoginCmdCB.SetStatusPaneIconsL(); + + // Idle loop for starting default list selection + delete iSelectIdle; + iSelectIdle = NULL; + iSelectIdle = CIdle::NewL( CActive::EPriorityIdle ); + iSelectIdle->Start( TCallBack( BackgroundSelect, this ) ); + + // set variated settings + TRAPD( err, UpdateDefaultSettingsL() ); + if ( err != KErrNone ) // Signal user about error + { + CActiveScheduler::Current()->Error( err ); + } + + CIMPSSAPSettings* currentSap = CurrentSAPLC(); + // reomoved extra code from here + + // take the ownership + delete iPreviousSAP; + iPreviousSAP = currentSap; + CleanupStack::Pop( currentSap ); + + // check if this was first login or not + UpdateFirstLoginL(); + + iUiLoginCmdCB.CaptureEventsL(); + } + else + { + iTemporaryNetworkDown = EFalse; + } + + break; + } + case EIMPSPresenceServiceForceLogOut: + { + CHAT_DP_TXT( + "CCASessionHandlerCmd::HandlePresenceEventL ->\ + EIMPSPresenceServiceForceLogOut" ); + + + NotifyEngineL( ELoggedOut ); + iUiLoginCmdCB.SetStatusPaneIconsL(); + + // nuke all contacts from IM Storage + MCAStoredContacts* contacts = + CCAStorageManagerFactory::ContactListInterfaceL(); + // Update own status item + contacts->OwnStatus().SetOnlineStatus( TStorageManagerGlobals::EOffline ); + + contacts->RemoveAllContactsL(); + + break; + } + default: + { + break; + } + } + + if ( aEvent == EIMPSPresenceServiceForceLogOut || + aEvent == EIMPSPresenceServiceOffline || + aEvent == EIMPSPresenceServiceOnline ) + { + // Reset initialization flag. + iPresenceInitializationSuccesfull = EFalse; + iIsContactFetchDone = EFalse; + } + + // Offline events + if ( aEvent == EIMPSPresenceServiceForceLogOut || + aEvent == EIMPSPresenceServiceOffline ) + { + // notify observers just in case some post login task failed + NotifyContactFetchObserversL( KErrCancel ); + } + + iLastState = aEvent; + + // Notify Service state change to MCAServiceStateObservers + NotifyServiceStateObserversL( aEvent ); + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::HandlePresenceEventNotifyError +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCASessionHandlerCmd::HandlePresenceEventNotifyError( + CIMPSConnUiPresEventNotifier* /*aNotifier*/, + TInt aError ) + { + CHAT_DP( D_CHAT_LIT( + "CCASessionHandlerCmd::HandlePresenceEventNotifyError, Error: %d" ), + aError ); + + // Show note, if appropriate found + if ( aError != KErrCancel ) // don't show error note for cancel events + { + TRAPD( err, IMNoteMapper::ShowNoteL( aError ) ); + if ( err ) + { + CActiveScheduler::Current()->Error( err ); + } + } + } + + +// --------------------------------------------------------- +// CCASessionHandlerCmd::LoginType +// Central repository version +// (other items were commented in a header). +// --------------------------------------------------------- +// +TIMPSLoginType CCASessionHandlerCmd::LoginType() + { + CHAT_DP( D_CHAT_LIT( "CCASessionHandlerCmd::LoginType" ) ); + + TInt readValue( KErrCouldNotConnect ); // initialize to an error value + + TIMPSLoginType loginType( EIMPSManualLogin ); + + CRepository* cenrep = NULL; + TRAPD( err, cenrep = CRepository::NewL( KWVSettingsCenRepUid ) ); + + if ( err != KErrNone ) + { + // creation of cenrep failed -> return + return loginType; + } + + TRAP( err, + CleanupStack::PushL( cenrep ); + err = cenrep->Get( KIMPSCRChatLogin, readValue ); + CleanupStack::PopAndDestroy( cenrep ); + ); // TRAP + cenrep = NULL; + + if ( err != KErrNone ) + { + // there was an error + return loginType; + } + + if ( ( readValue == EWVSettingsChatLoginAutoAlways ) || + ( readValue == EWVSettingsChatLoginAutoInHomeNW ) ) + { + return EIMPSAAConnectionStart; + } + else if ( readValue == EWVSettingsChatLoginApplicationLaunch ) + { + return EIMPSApplicationLaunch; + } + else + { + return EIMPSManualLogin; + } + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::BackgroundTasks +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CCASessionHandlerCmd::BackgroundTasks( TAny *aInstance ) + { + return static_cast( aInstance )->DoBackgroundTasks(); + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::DoBackgroundTasks +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CCASessionHandlerCmd::DoBackgroundTasks() + { + CHAT_DP_TXT( "CCASessionHandlerCmd::DoBackgroundTasks()" ); + + TBool dataOk( EFalse ); + TRAPD( err, dataOk = iUiLoginCmdCB.CheckCurrentServerDataL() ); + + if ( err != KErrNone ) // Signal user about error + { + CActiveScheduler::Current()->Error( err ); + } + + + // do not even try to log in if data check failed or data is invalid + if ( err != KErrNone || !dataOk ) + { + + + // update to platform using the new task. + + // If the server data is invalid, then set the flag back + iBackgroundTaskRunning = EFalse; + + // create the views + TRAPD( err2, iUiLoginCmdCB.FinalizeChatConstructionL() ); + if ( err2 != KErrNone ) + { + // show e.g. OOM + CActiveScheduler::Current()->Error( err2 ); + } + return EFalse; + } + + + TBool loginDone = EFalse; + TRAP( err, loginDone = LoginL( EFalse, ETrue ) ); + + if ( err != KErrNone || ! loginDone ) // Signal user about error + { + TRAPD( err2, iUiLoginCmdCB.FinalizeChatConstructionL() ); + if ( err2 != KErrNone ) + { + // show e.g. OOM + CActiveScheduler::Current()->Error( err2 ); + } + if ( err != KErrNone ) + { + // some error, the views should exist now. + // must check err, because loginDone condition could bring us here, + // in which case errors have been shown by IMPS Common UI. + CActiveScheduler::Current()->Error( err ); + } + } + + + // Set it back. + iBackgroundTaskRunning = EFalse; + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::BackgroundSelect +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CCASessionHandlerCmd::BackgroundSelect( TAny *aInstance ) + { + // CodeScanner warning ignored because CS does not regognize TRAP being used + // after line break + + TRAPD( err, static_cast( aInstance )->DoBackgroundSelectL() ); + // CSI: 42 # See comment above + + if ( err != KErrNone ) // Signal user about error + { + CActiveScheduler::Current()->Error( err ); + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::DoBackgroundSelectL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCASessionHandlerCmd::DoBackgroundSelectL() + { + CHAT_DP_TXT( "CCASessionHandlerCmd::DoBackgroundSelectL()" ); + + + iUiLoginCmdCB.ReleaseCapturingL(); + + if ( ! IsLoggedIn() ) + { + // perhaps we couldn't login + return; + } + + TBool supportAlias = IMUtils::IntResourceValueL( RSC_CHAT_VARIATION_HAVE_ALIAS ); + + if ( supportAlias ) + { + // subscribe also the alias attribute + MCAPresence* presence = CAPresenceManager::InstanceL(); + presence->AddAttributeL( MCAPresence::EAliasAttr ); + } + + TInt chatLoginType( IMUtils::WVSettingsChatLoginValue() ); + TBool manualLogin = chatLoginType != EWVSettingsChatLoginAutoAlways && + chatLoginType != EWVSettingsChatLoginAutoInHomeNW; + + iUiLoginCmdCB.ShowPostLoginNotesL( iCurrentLoginIsFirst, manualLogin ); + + + // Check P&S flag for forced login. + // If forced login is made in Common UI side + // contact list base sync is needed here although + // login type value is allways online at this point. + TBool forcedLogin = EFalse; + // Ignore errors + TInt err = RProperty::Get( KBrandingUid, KForcedLoginKey, forcedLogin ); + + if ( forcedLogin ) + { + // Force contact list base sync when starting the fetch + manualLogin = ETrue; + } + + // fetch all contact lists + FetchContactListsL( !manualLogin ); + + if ( forcedLogin ) + { + // Flag used, clear it + // Ignore errors + TInt err = RProperty::Set( KBrandingUid, KForcedLoginKey, EFalse ); + } + + GetServicesL(); + iUiLoginCmdCB.SetIMPSServices( iImpsServices ); + NotifyEngineL( ELoggedIn ); + + if ( ! iUiLoginCmdCB.CancelLoginValue() ) + { + // flush RA stuff only if login was not cancelled + + // flush any reactive authorizations now that we are done with the login + MCAPresence* presence = CAPresenceManager::InstanceL(); + presence->PostLoginRAFlushL(); + } + else + { + // user wanted to cancel login + if ( ! iLogging ) + { + // invoked by Always Online, so must do logout here + LogoutL(); + } + } + } + + + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::CurrentSAPLC +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CIMPSSAPSettings* CCASessionHandlerCmd::CurrentSAPLC() + { + CIMPSSAPSettings* sap = CIMPSSAPSettings::NewLC(); + + // If session is active, then current user-id should be retrieved from + // connection UI instead of SAP settings store + if ( IsLoggedIn() ) + { + CHAT_DP_TXT( + "CCASessionHandlerCmd::CurrentSAPLC returning SAP based on ConnUI" ); + if ( !iSessionSlotID ) + { + iSessionSlotID = + iConnUI->GetActiveNWSessionSlotIDL( EIMPSConnClientIM ); + } + iConnUI->GetLoggedInSapL( *iSessionSlotID, *sap ); + } + else + { + CHAT_DP_TXT( + "CCASessionHandlerCmd:: \ + CurrentSAPLC returning SAP based on SAPSettingsStore" ); + CIMPSSAPSettingsStore* sapStore = CIMPSSAPSettingsStore::NewLC(); + sapStore->GetDefaultL( sap, EIMPSIMAccessGroup ); + CleanupStack::PopAndDestroy( sapStore ); + } + + CHAT_DP( D_CHAT_LIT( "CCASessionHandlerCmd::CurrentSAPLC sap uid %d" ), + sap->Uid() ); + return sap; + } + + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::GetServicesL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCASessionHandlerCmd::GetServicesL() + { + TBool redraw( EFalse ); + + TBool groupsBefore( IsSupported( EGroup ) ); + + CPEngNWSessionSlot2* slot = CPEngNWSessionSlot2::NewLC( *iSessionSlotID ); + TPckg cspTreePtr( iImpsServices ); + TInt err = slot->GetOption( KPEngWVCspServicesTree2, + KPEngNWSessionSlotTransportQuery, + cspTreePtr ); + + CleanupStack::PopAndDestroy( slot ); + if ( err <= Imps_ERROR_BASE ) + { + IMNoteMapper::ShowNoteL( err ); + } + else + { + User::LeaveIfError( err ); + + // redraw if group feature has changed + redraw = ( groupsBefore != IsSupported( EGroup ) ); + } + CHAT_DP( D_CHAT_LIT( "*getservices, need redraw %d" ), redraw ); + return redraw; + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::NotifyEngineL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCASessionHandlerCmd::NotifyEngineL( TNetworkState aState, + CPEngNWSessionSlotID2* aSessionSlotID /* = NULL */ ) + { + + CIMPSSAPSettings* sap = CurrentSAPLC(); + + if ( aState == ELoggedOut ) + { + // clear the contacts refreshed flag also + iContactsRefreshed = EFalse; + MCALoginPC* login = iProcessManager.GetLogInInterface(); + + if ( login ) + { + login->NotifyEngineForLogoutL( aState, aSessionSlotID, iImpsServices ); + iUiLoginCmdCB.ShutDialogsL(); + } + else + return; // don't anything, becoz login object is null. + } + + else if ( aState == ELoggedIn ) + { + CHAT_DP( D_CHAT_LIT( "NotifyEngineL - ELoggedIn" ) ); + + if ( aSessionSlotID ) + { + + MCALoginPC* login = iProcessManager.GetLogInInterface(); + login->LoginL( aState, sap, aSessionSlotID, iImpsServices ); + + } + + } + + + CleanupStack::PopAndDestroy(); + + + } + + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::IsOfflineProfileOn +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCASessionHandlerCmd::IsOfflineProfileOn() const + { + return ( EProfileOffLineId == iProfileApi->ActiveProfileId() ); + } + + + +// --------------------------------------------------------- +// CCASessionHandlerCmd::FetchContactListsL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::FetchContactListsL( TBool aAlwaysOnlineActive ) + { + MCAPresence* presence = CAPresenceManager::InstanceL(); + if ( !presence ) + { + User::Leave( KErrNotFound ); + } + MCAContactLists* listInterface = presence->ContactLists(); + +#ifndef IMPS_CONTACT_FETCH_BACKGROUND + + iUiLoginCmdCB.ShowProcessingNoteLC(); + TInt err( listInterface->FetchContactsL( aAlwaysOnlineActive ) ); + CleanupStack::PopAndDestroy(); // waitdialog + + iIsContactFetchDone = ETrue; + NotifyContactFetchObserversL( err ); + + if ( err != KErrNone ) + { + + HBufC* text = CCoeEnv::Static()->AllocReadResourceLC( + R_QTN_CHAT_FETCHING_CONTACT_LISTS_FAILED ); + IMDialogUtils::DisplayErrorNoteL( *text ); + CleanupStack::PopAndDestroy( text ); + + } +#else + // If we have AO active, then base sync should be done already + listInterface->FetchContactsL( aAlwaysOnlineActive ); +#endif //IMPS_CONTACT_FETCH_BACKGROUND + } + +// --------------------------------------------------------- +// CCASessionHandlerCmd::CloseConversationsL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::CloseConversations() + { + + iProcessManager.GetConversationInterface()->CloseConversations(); + + } + + +// --------------------------------------------------------- +// CCASessionHandlerCmd::NetworkSessionSlotID +// (other items were commented in a header). +// --------------------------------------------------------- +// +const CPEngNWSessionSlotID2& CCASessionHandlerCmd::NetworkSessionSlotIDL() + { + if ( !iSessionSlotID ) + { + iSessionSlotID = iConnUI->GetActiveNWSessionSlotIDL( + EIMPSConnClientIM ); + } + + return *iSessionSlotID; + } + +// --------------------------------------------------------- +// CCASessionHandlerCmd::CloseConversationsL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::DoApplicationExitL() + { + if ( IsLoggedIn() ) + { + // Leave groups when exiting application in AO. + + TRAP_IGNORE( iProcessManager.GetConversationInterface()->LeaveJoinedGroupsL() ); + + if ( !iSessionSlotID ) + { + NetworkSessionSlotIDL(); + } + iConnUI->HandleApplicationExitL( EIMPSConnClientIM, + EIMPSLeaveSessionOpenExit, + *iSessionSlotID ); + + iProcessManager.GetLogInInterface()->LogoutL(); + + } + } + +// --------------------------------------------------------- +// CCASessionHandlerCmd::UpdateFirstLoginL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::UpdateFirstLoginL() + { + CIMPSSAPSettings* currentSAP = CurrentSAPLC(); + + // check if this is first login to server + TInt firstLogin = 0; + TInt sapError = -1; + sapError = currentSAP->GetOpaqueInt( KIMFirstLoginToServer, firstLogin ); + + if ( sapError != KErrNotFound ) + { + User::LeaveIfError( sapError ); + } + + if ( ! firstLogin ) + { + // first login has not been done. so this is the first login + + iCurrentLoginIsFirst = ETrue; + + CIMPSSAPSettingsStore* sapStore = CIMPSSAPSettingsStore::NewLC(); + CIMPSSAPSettingsList* sapList = CIMPSSAPSettingsList::NewLC(); + sapStore->PopulateSAPSettingsListL( *sapList, EIMPSIMAccessGroup ); + + // update information that this server has now logged in + // at least once and find our sap.. because logged in SAP has UID of zero, we must + // find the correct UID manually from list + TInt index( KErrNotFound ); + sapList->FindNameL( currentSAP->SAPName(), index ); + if ( index == KErrNotFound ) + { + User::Leave( index ); + } + + if ( index != KErrNotFound ) + { + // found it, update the correct sap + CIMPSSAPSettings* storedSap = CIMPSSAPSettings::NewLC(); + + TUint32 sapUid = sapList->UidForIndex( index ); + sapStore->GetSAPL( sapUid, storedSap ); + storedSap->SetOpaqueInt( KIMFirstLoginToServer, ETrue ); + sapStore->UpdateOldSAPL( storedSap, sapUid ); + + CleanupStack::PopAndDestroy( storedSap ); + } + + CleanupStack::PopAndDestroy( 2, sapStore ); + } + else + { + iCurrentLoginIsFirst = EFalse; + } + + CleanupStack::PopAndDestroy( currentSAP ); + } + +// --------------------------------------------------------- +// CCASessionHandlerCmd::UpdateDefaultSettingsL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::UpdateDefaultSettingsL() + { + + MCASettingsPC* settingsPC = iProcessManager.GetSettingsInterface(); + + + // set variated presence update mode + + TInt presenceUpdate = IMUtils::IntResourceValueL( RSC_CHAT_VARIATION_UPDATE_CONTACTS_SETTING ); + + CHAT_DP( D_CHAT_LIT( + "CCASessionHandlerCmd::UpdateDefaultSettingsL, presenceUpdate %d" ), + presenceUpdate ); + + if ( presenceUpdate == 1 ) // 1: only automatic update supported + { + settingsPC->SetBoolValuePCL( TEnumsPC::EAutomaticPresenceUpdate, ETrue ); + } + else if ( presenceUpdate == 2 ) // 2: only manual update supported + { + settingsPC->SetBoolValuePCL( TEnumsPC::EAutomaticPresenceUpdate, EFalse ); + } + + } + +// --------------------------------------------------------- +// CCASessionHandlerCmd::NotifyContactFetchObserversL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::NotifyContactFetchObserversL( TInt aError ) + { + TInt count = iFetchObservers.Count(); + for ( TInt i = 0; i < count; ++i ) + { + iFetchObservers[ i ]->HandleFetchCompleteL( aError ); + } + + } + +// --------------------------------------------------------- +// CCASessionHandlerCmd::AddContactFetchObserverL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::AddContactFetchObserverL( MCAContactFetchObserver* aObserver ) + { + if ( iFetchObservers.Find( aObserver ) == KErrNotFound ) + { + iFetchObservers.AppendL( aObserver ); + } + } + +// --------------------------------------------------------- +// CCASessionHandlerCmd::RemoveContactFetchObserver +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::RemoveContactFetchObserver( MCAContactFetchObserver* aObserver ) + { + TInt index = iFetchObservers.Find( aObserver ); + if ( index >= 0 ) + { + iFetchObservers.Remove( index ); + } + } + +// --------------------------------------------------------- +// CCASessionHandlerCmd::NotifyServiceStateObserversL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::NotifyServiceStateObserversL( TIMPSPresenceServiceEvent aEvent ) + { + MCAServiceStateObserver::TServiceState state = + MCAServiceStateObserver::EUnknown; + + // Convert TIMPSPresenceServiceEvent to TServiceState + switch ( aEvent ) + { + case EIMPSPresenceServiceOffline: + case EIMPSPresenceServiceForceLogOut: // flowthrough + { + state = MCAServiceStateObserver::EOffline; + break; + } + case EIMPSPresenceServiceOnline: + { + state = MCAServiceStateObserver::EOnline; + break; + } + default: + { + // Not important event. + return; + } + } + + // Notify observers + TInt count = iServiceStateObservers.Count(); + for ( TInt i = 0; i < count; ++i ) + { + TRAP_IGNORE( iServiceStateObservers[ i ]-> + HandleServiceStateChangeL( state ) ); + } + + } + +// --------------------------------------------------------- +// CCASessionHandlerCmd::AddServiceStateObserversL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::AddServiceStateObserversL( MCAServiceStateObserver* aObserver ) + { + if ( iServiceStateObservers.Find( aObserver ) == KErrNotFound ) + { + iServiceStateObservers.AppendL( aObserver ); + } + } + +// --------------------------------------------------------- +// CCASessionHandlerCmd::RemoveServiceStateObservers +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCASessionHandlerCmd::RemoveServiceStateObservers( MCAServiceStateObserver* aObserver ) + { + TInt index = iServiceStateObservers.Find( aObserver ); + if ( index >= 0 ) + { + iServiceStateObservers.Remove( index ); + } + } + +// --------------------------------------------------------- +// CCASessionHandlerCmd::IsFetchDone +// (other items were commented in a header). +// --------------------------------------------------------- +// +TBool CCASessionHandlerCmd::IsFetchDone() + { + return iIsContactFetchDone; + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::ContactsRefreshed() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCASessionHandlerCmd::ContactsRefreshed() const + { + return iContactsRefreshed; + } +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::ContactsRefreshed() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCASessionHandlerCmd::IsAlreadyLoggedOut() const + { + return iAlreadyLoggedOut; + } +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::SetContactsRefreshed() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- + +void CCASessionHandlerCmd::SetContactsRefreshed( TBool aRefreshed ) + { + iContactsRefreshed = aRefreshed; + } + +// ----------------------------------------------------------------------------- +// CCASessionHandlerCmd::SetContactsRefreshed() +// (other items were commented in a header). +// ----------------------------------------------------------------------------- + +TBool CCASessionHandlerCmd::IsBackgroundTaskRunning() const + { + return iBackgroundTaskRunning; + } + +// --------------------------------------------------------- +// CCASessionHandler::IsBackgroundGroupSyncPending +// (other items were commented in a header). +// --------------------------------------------------------- + +TBool CCASessionHandlerCmd::IsBackgroundTaskPendingL() + { + TBool ret = EFalse; + + CHAT_DP_TXT( "CCASessionHandler::IsBackgroundGroupSyncPending started" ); + + MCALoginPC* loginPC = iProcessManager.GetLogInInterface(); + + iBackgroundTaskPending = loginPC->IsBackgroundTaskPending(); + + // this call minimize the synch time + // it cancel all runing request + loginPC->CancelAllRequests(); + + // check for background task state + if ( iBackgroundTaskPending ) + { + loginPC->RegisterBackGroundTaskObserver( this ); + + ret = WaitToCompleteBackgroundTaskL(); + + } + + CHAT_DP_TXT( "CCASessionHandler::IsBackgroundGroupSyncPending completed" ); + + return ret; + + } + +// --------------------------------------------------------- +// CCASessionHandler::HandleGroupSync +// (other items were commented in a header). +// --------------------------------------------------------- + +void CCASessionHandlerCmd::HandleBackGroundTaskCompleteL( TBool aCompleted ) + { + + CHAT_DP_TXT( "CCASessionHandler::HandleBackGroundTaskComplete started" ); + + MCALoginPC* loginPC = iProcessManager.GetLogInInterface(); + + iBackgroundTaskPending = aCompleted; + + if ( ! iBackgroundTaskPending ) //group synchro is complete + { + // hide wait note + if ( iWaitVisible ) + { + TRAPD( err, iUiLoginCmdCB.DismissProcessingNoteL( KErrNone , ETrue ) ); + if ( err != KErrNone ) + { + User::Leave( err ); + } + iWaitVisible = EFalse; + } + + loginPC->UnRegisterBackGroundTaskObserver( this ); + + // every thinh is ok ,now call logout + DoLogoutL() ; + + } + CHAT_DP_TXT( "CCASessionHandler::HandleGroupSync done" ); + } +// ----------------------------------------------------------------------------- +// CCASessionHandler::GroupSyncL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCASessionHandlerCmd::WaitToCompleteBackgroundTaskL() + { + + CHAT_DP_TXT( "CCASessionHandler::GroupSyncL started" ); + + if ( ! iWaitVisible ) + { + CHAT_DP_TXT( + "CCASessionHandler::GroupSyncL - ! iWaitVisible && iGroupSyncProgress" ); + // launch the wait note + iWaitVisible = ETrue; + + iUiLoginCmdCB.ShowProcessingNoteLC(); + + CleanupStack::Pop();// waitnote + + CHAT_DP_TXT( "CCASessionHandler::GroupSyncL done" ); + } + return ETrue; + } + + +// End of File +