diff -r 000000000000 -r 094583676ce7 wvuing/IMPSConnectionUI/OperationStepSrc/CCnUiLoginUiCntrlStep.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wvuing/IMPSConnectionUI/OperationStepSrc/CCnUiLoginUiCntrlStep.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,594 @@ +/* +* Copyright (c) 2004 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: Login SAP select UI control. +* +*/ + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CCnUiLoginUiCntrlStep.h" +#include "CnUiSapLoginDataRefresher.h" +#include "CCnUiConnOpener.h" +#include "MCnUiUiControlContext.h" +#include "MCnUiUiFacade.h" +#include "MCnUiConnectionHandler.h" +#include "MCnUiConnModeHandler.h" +#include "MCnUiClientPlugin.h" +#include "MCnUiConnModeRewaker.h" +#include "CnUiSapDataPacker.h" + +#include "CnUiErrors.h" + +#include "CnUiClientId.h" +#include "impscommonuibuilddefinitions.h" +#include "IMPSCommonUiDebugPrint.h" + +#include "cnuitermsofusedialoghandler.h" +#include "mimpsshareddata.h" +#include "cimpsshareddatafactory.h" +#include "cnuiresourcefilename.h" + +#include "VariantKeys.h" +#include + +// ================= MEMBER FUNCTIONS ======================= +// Two-phased constructor. +CCnUiLoginUiCntrlStep* CCnUiLoginUiCntrlStep::NewLC( MCnUiUiControlContext& aCCntxt, + CIMPSSAPSettings& aLoginSap, + TIMPSLoginType aLoginType, + CPEngNWSessionSlotID2& aNWSessionSlotID, + TIMPSConnectionClient aClient ) + { + CCnUiLoginUiCntrlStep* self = new ( ELeave ) CCnUiLoginUiCntrlStep( aCCntxt, + aLoginSap, + aNWSessionSlotID, + aClient, + aLoginType ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +// Destructor +CCnUiLoginUiCntrlStep::~CCnUiLoginUiCntrlStep() + { + if ( iConnOpener->IsActive() ) + { + iConnOpener->Cancel(); + } + delete iConnOpener; + delete iWaitNote; + iRFs.Close(); + delete iSharedData; + } + +// C++ default constructor can NOT contain any code, that +// might leave. +// +CCnUiLoginUiCntrlStep::CCnUiLoginUiCntrlStep( MCnUiUiControlContext& aCCntxt, + CIMPSSAPSettings& aLoginSap, + CPEngNWSessionSlotID2& aNWSessionSlotID, + TIMPSConnectionClient aClient, + TIMPSLoginType aLoginType ) + : iCCntxt( aCCntxt ), + iLoginSap( aLoginSap ), + iLoginType( aLoginType ), + iSessionSlotID( aNWSessionSlotID ), + iClient( aClient ) + { + } + + +// Symbian OS default constructor can leave. +void CCnUiLoginUiCntrlStep::ConstructL() + { + iConnOpener = CCnUiConnOpener::NewL(); + iSharedData = CIMPSSharedDataFactory::CreateTemporaryKeyHandlerL( NULL, KBrandingUid ); + } + + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::RunStepL() +// from MCnUiCntrlStep +// ----------------------------------------------------------------------------- +// +TInt CCnUiLoginUiCntrlStep::RunStepL() + { + TInt loginTrieStatus = KErrNone; + + TBool loginRetryOngoing( EFalse ); + TBool loginRetryAllowed = ETrue; + while ( loginRetryAllowed ) + { + //initialization is needed on every round since + //there might have run some sub steps when handling login result + TIMPSConnectionClient clientToLogIn; + TInt initErr = DoInitLoginStepL( clientToLogIn ); + if ( initErr != ECnUiLoginInitContinue ) + { + return initErr; + } + + if ( ( iLoginSap.SAPUserId().Length() == 0 ) || + ( iLoginSap.SAPUserPassword().Length() == 0 ) ) + { + if ( !CnUiSapLoginDataRefresher::RefreshLoginDataL( iCCntxt.Ui(), + iLoginSap, + EFalse ) ) + { + //user canceled the login data query + iCCntxt.Ui().ShowNoteL( ECnUiConnCanceled ); + return KErrCancel; + } + else + { + // User ID may have changed + // Check Terms of use variation + if ( ReadResourceIntValueL( RSC_CHAT_VARIATION_IMPSCU_TOU_MESSAGE ) + && iLoginSap.SAPUserId().Length() > 0 ) + { + TInt retVal = CnUiTermsOfUseDialogHandler::HandleTermsOfUseDialogL( + iLoginSap, iCCntxt.Ui(), iCCntxt.SapStoreL() ); + + if ( retVal == KErrCancel ) + { + // User canceled ToU query, login cancelled + // note is already shown inside HandleTermsOfUseDialogL + // method, return KErrCancel + return retVal; + } + } + } + } + + if ( iLoginSap.ClientId().Length() == 0 ) + { + iLoginSap.SetClientIdL( KClientId() ); + } + + // set the network session slot ID + iSessionSlotID.SetServiceAddressL( iLoginSap.SAPAddress() ); + iSessionSlotID.SetUserIdL( iLoginSap.SAPUserId() ); + + if ( iClient == EIMPSConnClientIM ) + { + iSessionSlotID.SetAppIdL( KPEngAppIdIM() ); + } + else + { + iSessionSlotID.SetAppIdL( KPEngAppIdPEC() ); + } + + // create a network session slot to PEC engine + CPEngNWSessionSlotManager2* slotManager = CPEngNWSessionSlotManager2::NewLC(); + + TInt err = slotManager->CreateNWSessionSlot( iSessionSlotID ); + // we can ignore KErrAlreadyExist, since if the error is that + // we can just start using the slot + if ( ( err != KErrNone ) && ( err != KErrAlreadyExists ) ) + { + User::Leave( err ); + } + CleanupStack::PopAndDestroy( slotManager ); + + //proceed with login, notify first observers + iCCntxt.ProcessObserverProxy().NotifyAccessingSapL( iLoginSap ); + + + //store clients needing AA rewake to login SAP + RArray< TIMPSConnectionClient > clientsNeedingAARewake; + CleanupClosePushL( clientsNeedingAARewake ); + iCCntxt.ConnModeRewaker().GetAARewakeListL( clientsNeedingAARewake ); + + CnUiSapDataPacker::PackAAClientsL( clientsNeedingAARewake, iLoginSap ); + CleanupStack::PopAndDestroy(); //clientsNeedingAARewake + + TBool refreshPlugin( EFalse ); + if ( loginRetryOngoing ) + { + refreshPlugin = ETrue; + loginRetryOngoing = EFalse; + } + //Open the client connection using the connection opener + //control listens opener progress events + //and sets up proper wait notes according the opener states + loginTrieStatus = iConnOpener->MakeLoginForClient( + clientToLogIn, + iLoginSap, + iCCntxt.ClientPluginL( clientToLogIn, iSessionSlotID, refreshPlugin ), + iCCntxt.ConnHandler(), + this, + iSessionSlotID ); + + //connection opener finished its processing + //clear any existing wait note set by the progress step. + //own wait note container used ==> direct deletion ok. + delete iWaitNote; + iWaitNote = NULL; + + //handle success + if ( loginTrieStatus == KErrNone ) + { + //Rewake list is now stored in logged in SAP + //==> clear existing rewake list + iCCntxt.ConnModeRewaker().ClearAARewakeList(); + + //and notify about user level login + if ( iLoginType == EIMPSAAConnectionStart ) + { + iCCntxt.ConnModeHandler().SendUserSelectionL( EUserLevelAAConnectionStart, + clientToLogIn ); + } + else + { + iCCntxt.ConnModeHandler().SendUserSelectionL( EUserLevelLogin, + clientToLogIn ); + } + + //login is completed + return KErrNone; + } + + + //handle errors & determine wheter to try again + //only here listed errors may cause the restart from begining + switch ( loginTrieStatus ) + { + case KPEngNwErrInvalidPassword: + case KPEngNwErrUnknownUser: + case KPEngNwErrInvalidOrUnSupportedUserProperties: + case KPEngNwErrUnauthorized: + { + loginTrieStatus = HandleLoginDataFailureL( loginTrieStatus ); + if ( !loginTrieStatus ) + { + loginRetryOngoing = ETrue; + } + break; + } + + case KCnUiErrorAlreadyConnectedToAnotherSap: + { + loginTrieStatus = HandleConflictingSapConnectionL( loginTrieStatus, + clientToLogIn ); + break; + } + + default: + { + //in all other cases restart isn't allowed but some note is needed + iCCntxt.Ui().ShowLoginErrorNoteL( loginTrieStatus ); + break; + } + } + + if ( loginTrieStatus != KErrNone ) + { + //No retry allowed ==> stop login tries here + loginRetryAllowed = EFalse; + } + } + + return loginTrieStatus; + } + + + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::HandleCompleteL() +// from MCnUiCntrlStep +// ----------------------------------------------------------------------------- +// +TCnUiHandleCompleteStatus CCnUiLoginUiCntrlStep::HandleCompleteL() + { + //nothing to complete + return ECnUiStepContinueTeardown; + } + + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::UndoStepL() +// from MCnUiCntrlStep +// ----------------------------------------------------------------------------- +// +void CCnUiLoginUiCntrlStep::UndoStepL() + { + //nothing to undo + } + + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::HandleWaitNoteCancel() +// from MCnUiWaitNoteObserver +// ----------------------------------------------------------------------------- +// +void CCnUiLoginUiCntrlStep::HandleWaitNoteCancel() + { + iConnOpener->CancelLogin(); + } + + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::HandleProgressStateEnter() +// ----------------------------------------------------------------------------- +// +void CCnUiLoginUiCntrlStep::HandleProgressStateEnter( TInt aStateId, + TIMPSConnectionClient aClient ) + { + IMPSCUI_DP_FUNC_ENTER( "CCnUiLoginUiCntrlStep::HandleProgressStateEnter()" ); + TRAPD( leaveErr, DoShowLoginStateSpecificWaitnoteL( aStateId, aClient ) ) + if ( ( aStateId == ECnOpenerProcessingPlugin ) && ( !leaveErr ) ) + { + //show login ok note + TRAP( leaveErr, iCCntxt.Ui().ShowNoteL( ECnUiConnectionOK ) ); + } + iCCntxt.Ui().HandleIfError( leaveErr ); + IMPSCUI_DP_FUNC_DONE( "CCnUiLoginUiCntrlStep::HandleProgressStateEnter()" ); + } + + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::DoInitLoginStepL() +// ----------------------------------------------------------------------------- +// +TInt CCnUiLoginUiCntrlStep::DoInitLoginStepL( TIMPSConnectionClient& aClient ) + { + TIMPSConnectionClient clientId = iCCntxt.ControlledClient(); + if ( iCCntxt.ConnHandler().TheClientLoggedInL( clientId ) ) + { + //current client is already logged in + return KCnUiErrorClientAlreadyConnected; + } + + aClient = clientId; + return ECnUiLoginInitContinue; + } + + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::DoShowLoginStateSpecificWaitnoteL() +// ----------------------------------------------------------------------------- +// +void CCnUiLoginUiCntrlStep::DoShowLoginStateSpecificWaitnoteL( TInt aStateId, + TIMPSConnectionClient aClient ) + { + switch ( aStateId ) + { + //FLOW TROUGH + case ECnOpenerOpeningSAPConnection: + case ECnOpenerClosingInterferingSAPConnection: + { + if ( !iWaitNote ) + { + // opening SAP connection + if ( aClient == EIMPSConnClientIM ) + { + iWaitNote = iCCntxt.Ui().WaitNoteL( ECnUiWaitNoteConnectingChat, + iLoginSap.SAPName(), + this ); + } + + else + { + //client is considered to be PEC + iWaitNote = iCCntxt.Ui().WaitNoteL( ECnUiWaitNoteConnectingPEC, + iLoginSap.SAPName(), + this ); + } + } + + break; + } + case ECnOpenerProcessingPlugin: + case ECnOpenerIdle: + case ECnOpenerClosingOwnedSAPConnection: + default: + { + //clear any existing wait note set by the previous + //progress steps. No wait note used during these steps. + //own wait note container used ==> direct deletion ok. + delete iWaitNote; + iWaitNote = NULL; + + break; + } + } + } + + + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::HandleLoginDataFailureL() +// ----------------------------------------------------------------------------- +// +TInt CCnUiLoginUiCntrlStep::HandleLoginDataFailureL( TInt aTrieError ) + { + //login has failed to improper user name or password + //show a note for the reason & refresh the login data + iCCntxt.Ui().ShowLoginErrorNoteL( aTrieError ); + if ( CnUiSapLoginDataRefresher::RefreshLoginDataL( iCCntxt.Ui(), iLoginSap, ETrue ) ) + { + return KErrNone; //user accepted the login data query ==> retry + } + + else + { + //user canceled the login data query + iCCntxt.Ui().ShowNoteL( ECnUiConnCanceled ); + return KErrCancel; + } + } + + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::HandleConflictingSapConnectionL() +// ----------------------------------------------------------------------------- +// +TInt CCnUiLoginUiCntrlStep::HandleConflictingSapConnectionL( + TInt aTrieError, + TIMPSConnectionClient aTriedLoginClient ) + { + TBool dropExistingConnection = EFalse; + if ( aTriedLoginClient == EIMPSConnClientPEC ) + { + //PEC trying to connect + //==> the other existing client must be IM + dropExistingConnection = iCCntxt.Ui().ConfirmationQueryL( ECnUiDropIMLogin, + iLoginSap.SAPName() ); + } + else + { + dropExistingConnection = iCCntxt.Ui().ConfirmationQueryL( ECnUiDropPECLogin, + iLoginSap.SAPName() ); + } + + + if ( !dropExistingConnection ) + { + //user doesn't want to terminate existing connection + iCCntxt.Ui().ShowNoteL( ECnUiConnCanceled ); + return KErrCancel; + } + + //user selected to drop existing connection + //if disconnecting succeeds, then retry is allowed + //else return the original error + if ( TryDisconnectOtherConnectionsL() ) + { + return KErrNone; + } + else + { + return aTrieError; + } + } + + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::TryDisconnectOtherConnectionsL() +// ----------------------------------------------------------------------------- +// +TBool CCnUiLoginUiCntrlStep::TryDisconnectOtherConnectionsL() + { + TBool subOperationOk = EFalse; + CIMPSSAPSettings* disconnectedSap = CIMPSSAPSettings::NewLC(); + RArray< TIMPSConnectionClient > disconnectedClients; + CleanupClosePushL( disconnectedClients ); + + + TInt disconnStatus = iCCntxt.SubOpDisconnectAllL( *disconnectedSap, + disconnectedClients, + iSessionSlotID ); + if ( ( disconnStatus == KErrNone ) || + ( disconnStatus == KCnUiErrorNoClientsToDisconnect ) ) + { + //sub operation succeeded + subOperationOk = ETrue; + + //Add disconnected clients to AA mode rewaker + const TInt disconnectedClientsCount = disconnectedClients.Count(); + for ( TInt ii = 0; ii < disconnectedClientsCount; ii++ ) + { + TIMPSConnectionClient client = disconnectedClients[ ii ]; + MCnUiClientPlugin& clientPlugin = iCCntxt.ClientPluginL( client, iSessionSlotID ); + + iCCntxt.ConnModeRewaker().AddToAAModeRewakeListL( clientPlugin, iSessionSlotID ); + } + } + + CleanupStack::PopAndDestroy( 2 ); //disconnectedClients, disconnectedSap + return subOperationOk; + } + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::OpenResourceFileLC() +// !!!Notice!!!. Two variables in cleanupstack after call of this method. +// ----------------------------------------------------------------------------- +// +void CCnUiLoginUiCntrlStep::OpenResourceFileLC( RResourceFile& aResourceFile ) + { + TFileName resourceFileName; + iRFs.Close(); + User::LeaveIfError( iRFs.Connect() ); + + TInt err = iSharedData->GetStringKey( ( TIMPSSharedKeys )KBrandingResourceKey, resourceFileName ); + if ( err || !resourceFileName.Length() ) + { + CnUiResourceFileName::NearestVariationForCurrentLanguage( iRFs, resourceFileName ); + } + aResourceFile.OpenL( iRFs, resourceFileName ); + CleanupClosePushL( aResourceFile ); + aResourceFile.ConfirmSignatureL(); + } + +// ----------------------------------------------------------------------------- +// CCnUiLoginUiCntrlStep::ReadResourceIntValueL() +// ----------------------------------------------------------------------------- +// +TInt CCnUiLoginUiCntrlStep::ReadResourceIntValueL( TInt aResourceId ) + { + + + TInt val( 0 ); + TInt err ( KErrNone ); + + CRepository* rep = 0; + + TRAP( err, rep = CRepository::NewL( KCRUidIMNG ) ); + + if ( err == KErrNone ) + { + TInt key = aResourceId + KIMCUStartVariationID; + + err = rep->Get( key, val ); + + delete rep; + } + + if ( err != KErrNone ) + { + + RResourceFile resFile; + OpenResourceFileLC( resFile ); // Two items in cleanup stack. + + aResourceId = aResourceId + RSC_CRRSS_CHAT_VARIATION_IMPSCU_START_ID; + + // read the data to a buffer + TInt plainResourceId = 0x00000fff & aResourceId; // Remove offset from id + HBufC8* rawDataBuf = resFile.AllocReadLC( plainResourceId ); + + // it's now as ascii code: \x00 for 0, \x01 for 1, etc. + TUint value = ( *rawDataBuf )[ 0 ]; + + CleanupStack::PopAndDestroy( 2 ); // rawDataBuf, resFile + + val = value; + } + + return val; + + } + +// End of File + +