wvuing/IMPSConnectionUI/OperationStepSrc/CCnUiLoginUiCntrlStep.cpp
changeset 0 094583676ce7
--- /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 <E32std.h>
+#include <CIMPSSAPSettings.h>
+#include <PEngWVPresenceErrors2.h>
+#include <CPEngNWSessionSlotID2.h>
+#include <CPEngNWSessionSlotManager2.h>
+#include <PEngPresenceEngineConsts2.h>
+#include <barsc.h>
+#include <impsconnectionuing.rsg>
+
+#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 	<centralrepository.h>
+
+// ================= 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
+
+