wvuing/IMPSConnectionUI/OperationStepSrc/CCnUiAALoginCntrlStep.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wvuing/IMPSConnectionUI/OperationStepSrc/CCnUiAALoginCntrlStep.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,445 @@
+/*
+* 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:  AA login control.
+*
+*/
+
+// INCLUDE FILES
+#include <E32std.h>
+#include <CIMPSSAPSettingsStore.h>
+#include <CIMPSSAPSettings.h>
+#include <PEngWVPresenceErrors2.h>
+#include <impserrors.h>
+#include <IMPSConnectionUiNG.rsg>
+#include <CPEngNWSessionSlotID2.h>
+#include <CPEngNWSessionSlotManager2.h>
+#include <PEngPresenceEngineConsts2.h>
+
+#include "CCnUiAALoginCntrlStep.h"
+#include "CCnUiConnOpener.h"
+#include "CCnUiConnCloser.h"
+
+#include "MCnUiBaseControlContext.h"
+#include "MCnUiConnectionHandler.h"
+#include "MCnUiSignaller.h"
+#include "MCnUiGlobalNotificationUiFacade.h"
+
+#include "CnUiErrors.h"
+
+#include "CnUiClientId.h"
+
+
+// ================= MEMBER FUNCTIONS =======================
+// Two-phased constructor.
+CCnUiAALoginCntrlStep* CCnUiAALoginCntrlStep::NewLC( MCnUiBaseControlContext& aCCntxt,
+                                                     CIMPSSAPSettings& aLoginSap,
+                                                     TBool aShowDetailedError,
+                                                     CPEngNWSessionSlotID2& aNWSessionSlotID )
+    {
+    CCnUiAALoginCntrlStep* self = new ( ELeave ) CCnUiAALoginCntrlStep( aCCntxt, aLoginSap,
+                                                                        aShowDetailedError, aNWSessionSlotID );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+
+// Destructor
+CCnUiAALoginCntrlStep::~CCnUiAALoginCntrlStep()
+    {
+    delete iConnOpener;
+    delete iConnCloser;
+    delete iLogoutPlugin;
+    }
+
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+CCnUiAALoginCntrlStep::CCnUiAALoginCntrlStep( MCnUiBaseControlContext& aCCntxt,
+                                              CIMPSSAPSettings& aLoginSap,
+                                              TBool aShowDetailedError,
+                                              CPEngNWSessionSlotID2& aNWSessionSlotID )
+        : iCCntxt( aCCntxt ),
+        iLoginSap( aLoginSap ),
+        iShowDetailedError( aShowDetailedError ),
+        iNWSessionSlotID( aNWSessionSlotID )
+    {
+    }
+
+
+// Symbian OS default constructor can leave.
+void CCnUiAALoginCntrlStep::ConstructL()
+    {
+    iConnOpener = CCnUiConnOpener::NewL();
+    iConnCloser = CCnUiConnCloser::NewL();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiAALoginCntrlStep::RunStepL()
+// -----------------------------------------------------------------------------
+//
+TInt CCnUiAALoginCntrlStep::RunStepL()
+    {
+    TInt mappedError = KErrNone;
+    TInt errorDetail = KErrNone;
+
+    switch ( DoRunStepL() )
+        {
+        case KErrNone: //  Login succeeded
+            {
+            //this is returned as is
+            mappedError = KErrNone;
+            break;
+            }
+
+        case KCnUiErrorClientAlreadyConnected:
+            {
+            //Current client is already logged in. (Thus not a real error.)
+            mappedError = KErrAlreadyExists;
+            break;
+            }
+
+
+        case KErrAccessDenied:
+        case KCnUiErrorNetworkConnectionNotAllowed: //  //network access denied
+            {
+            mappedError = KErrAccessDenied;
+            errorDetail = R_QTN_CHAT_LOGIN_CONERROR_NOTE;
+            break;
+            }
+
+
+        case KCnUiErrorSapMissingCompulsoryFields:
+        case KCnUiErrorNoProperDefaultSap:
+            {
+            //Missing the whole default SAP
+            //or it was missing some required fields.
+            mappedError = KErrNotFound;
+            errorDetail = R_QTN_CHAT_SETT_COMP_MISS;
+            break;
+            }
+
+
+        case KPEngNwErrInvalidPassword:
+        case KPEngNwErrUnknownUser:
+        case KPEngNwErrInvalidOrUnSupportedUserProperties:
+        case KPEngNwErrUnauthorized:
+            {
+            //wrong username / password
+            //free first plug-in dynamic resources
+            TIMPSConnectionClient clientId = iCCntxt.ControlledClient();
+            iCCntxt.ClientPluginL( clientId, iNWSessionSlotID ).ReleaseDynamicResources();
+
+            iCCntxt.GlobalNotificationUiL().ShowLoginUserDataErrorL( iLoginSap.SAPName() );
+            mappedError = KErrArgument;
+            break;
+            }
+
+        case KCnUiErrorAlreadyConnectedToAnotherSap:
+            {
+            // user declined disconnect from manually logged in sap
+            mappedError = KErrCouldNotDisconnect;
+            break;
+            }
+
+        case KPEngNwErrForbidden:// 403
+            {
+            errorDetail = R_QTN_CHAT_LOGIN_ACCOUNT_LOST;
+            mappedError = KErrAccessDenied;
+            break;
+            }
+
+        //flow through
+        case KPEngNwErrServiceNotSupported: // 405
+        case KPEngNwErrServiceNotAgreed: // 506
+            {
+            mappedError = KErrNotSupported;
+            errorDetail = R_QTN_CHAT_ERROR_SERVICE_ERR;
+            break;
+            }
+
+        // flow through
+        case KPEngNwErrServiceUnavailable: // 503
+        case KPEngNwErrMessageQueueIsFull: // 507
+            {
+            mappedError = KErrCouldNotConnect;
+            errorDetail = R_QTN_CHAT_ERROR_SERV_BUSY;
+            break;
+            }
+
+        case KPEngNwErrVersionNotSupported: // 505
+            {
+            mappedError = KErrGeneral;
+            errorDetail = R_QTN_CHAT_ERROR_GEN_ERROR;
+            break;
+            }
+
+        // flow through
+        case KPEngNwErrSessionExpired: // 600
+        case KErrTimedOut:
+        case KErrCouldNotConnect:
+        case KImpsErrorBearerSuspended:
+            {
+            mappedError = KErrCouldNotConnect;
+            errorDetail = R_QTN_CHAT_LOGIN_CONERROR_NOTE;
+            break;
+            }
+
+        default:
+            {
+            //General failure during login (no connection to network, etc..)
+            mappedError = KErrGeneral;
+            errorDetail = R_QTN_CHAT_LOGIN_CONERROR_NOTE;
+            break;
+            }
+        }
+
+    // if there was some other error than login data error, we must
+    // show a detailed error note if aa plugin requested so
+    if ( ( mappedError != KErrNone ) && ( mappedError != KErrArgument ) && ( iShowDetailedError ) )
+        {
+        //free first plug-in dynamic resources
+        TIMPSConnectionClient clientId = iCCntxt.ControlledClient();
+        iCCntxt.ClientPluginL( clientId, iNWSessionSlotID ).ReleaseDynamicResources();
+
+        iCCntxt.GlobalNotificationUiL().ShowLoginDetailedErrorL( iLoginSap.SAPName(), errorDetail );
+        }
+
+    return mappedError;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiAALoginCntrlStep::DoRunStepL()
+// -----------------------------------------------------------------------------
+//
+TInt CCnUiAALoginCntrlStep::DoRunStepL()
+    {
+    TIMPSConnectionClient clientId = iCCntxt.ControlledClient();
+
+    //First make sure that there isn't already another login
+    //operation running (if there is, then no need to select SAP...)
+    if ( iCCntxt.Signaller().OperationRunning() )
+        {
+        return KCnUiErrorLoginOperationAlreadyInUse;
+        }
+
+    // Check if client is already logged to DEFAULT server
+    CIMPSSAPSettings* defaultSap = CIMPSSAPSettings::NewLC();
+    LoadDefaultSapL( *defaultSap );
+    TCnUiSapCnStatus status = iCCntxt.ConnHandler().SapConnectionStatusL( *defaultSap, clientId );
+    CleanupStack::PopAndDestroy( defaultSap );
+
+    if ( status == ECnUiSCS_SapConnected )
+        {
+        // connected to the same server. otherwise logout
+        //
+        // or different server)
+        return KCnUiErrorClientAlreadyConnected;
+        }
+
+    //load SAP & handle its errors
+    TInt loadStatus = LoadDefaultSapL( iLoginSap );
+    if ( loadStatus != KErrNone )
+        {
+        iLoginSap.Reset();
+        return loadStatus;
+        }
+
+    //Signal to other clients that login operation is started.
+    if ( iCCntxt.Signaller().SignalOperationL( iLoginSap.SAPName() ) == KErrInUse )
+        {
+        //some other client has started the login during SAP load...
+        return KCnUiErrorLoginOperationAlreadyInUse;
+        }
+
+    if ( iLoginSap.ClientId().Length() == 0 )
+        {
+        iLoginSap.SetClientIdL( KClientId() );
+        }
+
+
+    // set the network session slot ID
+    iNWSessionSlotID.SetServiceAddressL( iLoginSap.SAPAddress() );
+    iNWSessionSlotID.SetUserIdL( iLoginSap.SAPUserId() );
+
+    if ( clientId == EIMPSConnClientIM )
+        {
+        iNWSessionSlotID.SetAppIdL( KPEngAppIdIM() );
+        }
+    else
+        {
+        iNWSessionSlotID.SetAppIdL( KPEngAppIdPEC() );
+        }
+
+    // create a network session slot to PEC engine
+    CPEngNWSessionSlotManager2* slotManager = CPEngNWSessionSlotManager2::NewLC();
+
+    TInt err = slotManager->CreateNWSessionSlot( iNWSessionSlotID );
+    // 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 );
+    //ok to try login
+    TInt loginTrieStatus = iConnOpener->MakeLoginForClient(
+                               clientId,
+                               iLoginSap,
+                               iCCntxt.ClientPluginL( clientId, iNWSessionSlotID ),
+                               iCCntxt.ConnHandler(),
+                               NULL,
+                               iNWSessionSlotID );
+
+
+    if ( loginTrieStatus == KCnUiErrorAlreadyConnectedToAnotherSap )
+        {
+        // we are already connected to another sap, so we need to logout first
+
+        // create global notification ui facade for sending channel message
+        MCnUiGlobalNotificationUiFacade* uiFacade = &( iCCntxt.GlobalNotificationUiL() );
+
+        RArray<TIMPSConnectionClient> loggedInClients;
+        CleanupClosePushL( loggedInClients );
+        iCCntxt.ConnHandler().GetLoggedInClientsL( loggedInClients );
+
+        // ask a confirmation from the user
+        if ( uiFacade->CGQActiveConnectionSuppressForScheduledConnectionL(
+                 iLoginSap.SAPName(),
+                 loggedInClients.Array() ) )
+            {
+            loginTrieStatus = KErrNone;
+
+            // user accepted logout of query timed out -> do the logout
+            CIMPSSAPSettings* logoutSap = CIMPSSAPSettings::NewLC();
+            //get SAP from where logging out..
+            iCCntxt.ConnHandler().GetLoggedInSapL( *logoutSap, clientId );
+
+            CPEngNWSessionSlotID2* logoutID = NULL;
+            logoutID = iCCntxt.GetActiveNWSessionSlotIDL( clientId );
+            CleanupStack::PushL( logoutID );
+            TInt logoutStatus( KErrNone );
+
+            delete iLogoutPlugin;
+            iLogoutPlugin = NULL;
+            iLogoutPlugin = CreateClientPluginL( clientId, *logoutID );
+
+            for ( TInt index = 0; index < loggedInClients.Count(); index++ )
+                {
+                //close the client connection using the connection closer
+                logoutStatus = iConnCloser->MakeLogoutForClient( loggedInClients.Array()[ index ],
+                                                                 *logoutSap,
+                                                                 *iLogoutPlugin,
+                                                                 iCCntxt.ConnHandler(),
+                                                                 NULL,
+                                                                 *logoutID );
+                if ( logoutStatus != KErrNone )
+                    {
+                    // logout did not succeed, exit the loop
+                    loginTrieStatus = logoutStatus;
+                    break;
+                    }
+                }
+
+            if ( loginTrieStatus == KErrNone )
+                {
+                // logout(s) successful -> do the login
+                loginTrieStatus = iConnOpener->MakeLoginForClient( clientId,
+                                                                   iLoginSap,
+                                                                   iCCntxt.ClientPluginL( clientId, iNWSessionSlotID ),
+                                                                   iCCntxt.ConnHandler(),
+                                                                   NULL,
+                                                                   iNWSessionSlotID );
+                }
+            delete iLogoutPlugin;
+            iLogoutPlugin = NULL;
+            CleanupStack::PopAndDestroy( logoutID );
+            CleanupStack::PopAndDestroy( logoutSap );
+            }
+        CleanupStack::PopAndDestroy(); // loggedInClients
+        }
+
+    return loginTrieStatus;
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CCnUiAALoginCntrlStep::HandleCompleteL()
+// -----------------------------------------------------------------------------
+//
+TCnUiHandleCompleteStatus CCnUiAALoginCntrlStep::HandleCompleteL()
+    {
+    iCCntxt.Signaller().CancelOperationSignal();
+    return ECnUiStepContinueTeardown;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiAALoginCntrlStep::HandleCompleteL()
+// -----------------------------------------------------------------------------
+//
+void CCnUiAALoginCntrlStep::UndoStepL()
+    {
+    iCCntxt.Signaller().CancelOperationSignal();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCnUiAALoginCntrlStep::LoadDefaultSapL()
+// -----------------------------------------------------------------------------
+//
+TInt CCnUiAALoginCntrlStep::LoadDefaultSapL( CIMPSSAPSettings& aSap )
+    {
+    CIMPSSAPSettingsStore& sapStore = iCCntxt.SapStoreL();
+
+    TIMPSConnectionClient client( ConnectionClient() );
+    TIMPSAccessGroup accessGroup;
+    if ( client == EIMPSConnClientIM )
+        {
+        accessGroup = EIMPSIMAccessGroup;
+        }
+    else
+        {
+        accessGroup = EIMPSPECAccessGroup;
+        }
+
+
+    //SAP store might not have any SAP => get default leaves
+    TRAPD( err, sapStore.GetDefaultL( &aSap, accessGroup ) );
+    if ( err == KErrNotFound )
+        {
+        //handle not found error by returning it
+        return KCnUiErrorNoProperDefaultSap;
+        }
+
+    //and others by leaving
+    User::LeaveIfError( err );
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CCnUiAALoginCntrlStep::DoShowLogoutOkNoteL()
+// -----------------------------------------------------------------------------
+//
+TIMPSConnectionClient CCnUiAALoginCntrlStep::ConnectionClient()
+    {
+    // rvct does not support casting from TAny* to enumeration value
+    TInt returnValue = ( TInt )Dll::Tls();
+    return ( TIMPSConnectionClient )returnValue;
+    }
+//  End of File