coreapplicationuis/Rfs/src/rfsHandler.cpp
changeset 0 2e3d3ce01487
child 21 c4cbaa4fb734
child 62 924385140d98
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/coreapplicationuis/Rfs/src/rfsHandler.cpp	Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,509 @@
+/*
+* Copyright (c) 2008-2009 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: 
+*		Implements CRfsHandles class.
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <e32std.h>
+#include <bautils.h>                // BaflUtils
+#include <eikenv.h>                 // CEikonEnv
+#include <rfs.rsg>                  // rfs resource file
+#include <etelmm.h>
+#include <mmtsy_names.h>
+
+#include <featmgr.h>
+#include <e32property.h>
+#include <PSVariables.h>
+#include <ctsydomainpskeys.h>
+#include <ir_sock.h>
+#include <bt_subscribe.h>
+#include <wlaninternalpskeys.h>
+
+#include <starterclient.h>
+#include <syslangutil.h>            // default language
+
+#include <secui.h>                  // security UI
+#include <secuisecurityhandler.h>
+
+#include <aknnotewrappers.h>
+#include <AknQueryDialog.h>
+
+#include <hal.h>
+#include <centralrepository.h>
+#include <CommonEngineDomainCRKeys.h>
+
+#include <data_caging_path_literals.hrh>
+
+#include "CleanupResetPointer.h"
+#include <AknWaitDialog.h>
+#include <pdpcontextmanagerpskeys.h>
+#include <pdpcontextmanagerinternalcrkeys.h>
+#include "rfsConnectionObserver.h"
+#include "rfsHandler.h"
+#include "rfsClient.h"
+#include "RfsTraces.h"
+
+
+_LIT( KRfsResourceFileName, "Z:rfs.rsc");
+
+// CONSTANTS
+const TInt KPhoneIndex = 0;
+const TInt KRfsHandlerActivated             = 0x0001;
+const TInt KRfsHandlerPhoneModuleLoaded     = 0x0002;
+const TInt KRfsHandlerSecUiInitialized      = 0x0004;
+const TInt KRfsHandlerInitDone              = 0x0008;
+
+
+EXPORT_C CRfsHandler::CRfsHandler()
+    {
+    }
+
+EXPORT_C CRfsHandler::~CRfsHandler()
+    {
+    if ( iDestroyedPtr )
+        {
+        *iDestroyedPtr = ETrue;
+        iDestroyedPtr = NULL;
+        }
+    Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CRfsHandler::ActivateRfsL()
+// -----------------------------------------------------------------------------
+EXPORT_C void CRfsHandler::ActivateRfsL( TRfsType aType, TBool aAskSecurityCodeFirst )
+    {
+    TRACES("CRfsHandler::ActivateRfsL()");
+    
+    // if already activated, do nothing
+    if ( iFlags & KRfsHandlerActivated )
+        {
+        TRACES("CRfsHandler::ActivateRfsL(): return");
+        return;
+        }
+
+    // load the resource file
+    if ( !iResourceFileOffset )
+        {
+        LoadResourceL();
+        }
+	
+    // Create a generic connection observer for closing all the active connections
+    // if they exist. Currently there are only 2 types i.e. SIP and PDP
+    CRfsConnectionObserver* connectionObserver = CRfsConnectionObserver::NewLC();
+ 
+    // This wil return a boolean:
+    //  ETrue:  if all the active connections are closed  i.e. both SIP and PDP
+    //  EFalse: if the user pressed 'Cancel' button in between any of the connection closing process
+    iAlwaysOnlineConnectionClosed = connectionObserver->CloseAlwaysOnConnectionL();
+    
+	// Ensure there aren't any active calls or data sessions
+    if ( CheckConnectionsL() )
+        {
+        // If there are some connections active, then we publish that the RFS has failed/stoped
+        connectionObserver->ReOpenPDPConnection();
+        connectionObserver->ReportRfsFailureToSip();
+        CleanupStack::PopAndDestroy(connectionObserver);
+        return;
+        }
+
+    // Puts 'this' in the cleanup stack so that Cancel() is called on leave
+    CleanupStack::PushL( TCleanupItem( DoCleanup, this ) );
+
+    // Do other initialisations if not already done
+    if ( !(iFlags & KRfsHandlerInitDone) )
+        {
+        // create or open the needed resources
+        User::LeaveIfError( iTelServer.Connect() );
+        iTelServer.LoadPhoneModule( KMmTsyModuleName );
+        iFlags |= KRfsHandlerPhoneModuleLoaded;
+        iTelServer.SetExtendedErrorGranularity( RTelServer::EErrorExtended );
+        
+        RTelServer::TPhoneInfo info;
+        // get info about default phone (KPhoneIndex)
+        User::LeaveIfError( iTelServer.GetPhoneInfo( KPhoneIndex, info ) );
+        User::LeaveIfError( iPhone.Open( iTelServer, info.iName ) );
+        TSecUi::InitializeLibL();
+        iFlags |= KRfsHandlerSecUiInitialized;
+        iSecurityHandler = new( ELeave ) CSecurityHandler( iPhone );
+        }
+
+    iFlags |= ( KRfsHandlerActivated | KRfsHandlerInitDone );
+    TBool proceed( ETrue );
+
+    // Setup information of whether the CRfsHandler instance has been
+    // destroyed while one of the queries was on the screen.
+    TBool thisDestroyed( EFalse );
+    iDestroyedPtr = &thisDestroyed;
+    CleanupResetPointerPushL( iDestroyedPtr );
+
+    // Ask first query.
+    if ( aAskSecurityCodeFirst )
+        {
+        proceed = iSecurityHandler->AskSecCodeL();
+        }
+    else
+        {
+        proceed = AskConfirmationL( thisDestroyed, aType );
+        }
+
+    // If OK, ask second query.
+    if ( proceed )
+        {
+        if ( aAskSecurityCodeFirst )
+            {
+            proceed = AskConfirmationL( thisDestroyed, aType );
+            }
+        else
+            {
+            proceed = iSecurityHandler->AskSecCodeL();
+            }
+        }
+
+    // If all OK, then perform RFS.
+    if ( proceed && !CheckConnectionsL() )
+        {
+        // In case of deep level RFS, set the default language code here, before RFS reboot.
+        if ( aType == ERfsDeep )
+            {
+            SetDefaultLanguage();
+            }
+        RStarterSession startersession;
+        if( startersession.Connect() == KErrNone )
+            {
+			// Displays information note to the user telling that the device will restart
+            HBufC* prompt = iEnv->AllocReadResourceLC( R_DEVICE_RESTART );
+            CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue );
+            note->ExecuteLD( *prompt );
+            CleanupStack::PopAndDestroy( prompt );
+			
+            if (aType == ERfsNormal ) startersession.Reset( RStarterSession::ENormalRFSReset );
+            else if (aType == ERfsDeep ) startersession.Reset( RStarterSession::EDeepRFSReset );
+            else startersession.Reset( RStarterSession::EUnknownReset );
+            startersession.Close();
+            }
+        }
+    // Inform SIP and PDP that the RFS has completed its operation.
+    // The method is used for two purposes
+    //  1. When we reopen the connection due to RFS failure.
+    //  2. when we have successfully completed the RFS operation.
+    // In both of the above cases the RFS has completed either successfully or not 
+    connectionObserver->ReOpenPDPConnection();
+    
+    if(!proceed)
+        {
+        // Inform SIP that user has either selected not to perform the RFS
+        // or has failed to provide the right security code due to which
+        // RFS operation is not performed. So in this case the SIP should reopen 
+        // its connection.
+        connectionObserver->ReportRfsFailureToSip();
+        }
+    else
+        {
+        connectionObserver->ReportRfsCompletionToSip();
+        }
+    
+    if ( thisDestroyed ) // this object has already been destroyed
+        {
+        // remove cleanup items
+        CleanupStack::Pop( 2 ); // this, iDestroyedPtr
+        }
+    else
+        {
+        // NULLs iDestroyedPtr and calls DoCleanup()
+        CleanupStack::PopAndDestroy( 2 ); // this, iDestroyedPtr
+        }
+    
+    CleanupStack::PopAndDestroy(connectionObserver);
+    }
+
+// -----------------------------------------------------------------------------
+// CRfsHandler::Cancel()
+// -----------------------------------------------------------------------------
+EXPORT_C void CRfsHandler::Cancel()
+    {
+    TRACES("CRfsHandler::Cancel()");
+
+    // delete confirmation query
+    delete iQuery;
+    iQuery = NULL;
+
+    // delete security handler
+    if ( iSecurityHandler )
+        {
+        iSecurityHandler->CancelSecCodeQuery();
+
+        delete iSecurityHandler;
+        iSecurityHandler = NULL;
+        }
+
+    // uninitialize security UI
+    if ( iFlags & KRfsHandlerSecUiInitialized )
+        {
+        TSecUi::UnInitializeLib();
+        }
+
+    // close ETel connection
+    iPhone.Close();
+
+    if ( iFlags & KRfsHandlerPhoneModuleLoaded )
+        {
+        iTelServer.UnloadPhoneModule( KMmTsyModuleName );
+        }
+
+    iTelServer.Close();
+
+    // close the resource file
+    if ( iResourceFileOffset )
+        {
+        iEnv->DeleteResourceFile( iResourceFileOffset );
+        iResourceFileOffset = 0;
+        }
+
+    // finally, reset the flags
+    iFlags = 0;
+    }
+
+// -----------------------------------------------------------------------------
+// CRfsHandler::LoadResourceL()
+// -----------------------------------------------------------------------------
+void CRfsHandler::LoadResourceL()
+    {
+    TRACES("CRfsHandler::LoadResourceL()");
+    iEnv = CEikonEnv::Static();
+
+    // eikon environment is needed
+    __ASSERT_DEBUG( iEnv, User::Invariant() );
+
+    TParse* fp = new(ELeave) TParse(); 
+    fp->Set(KRfsResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL);
+    TFileName fileName( fp->FullName() );
+    delete fp;
+
+    BaflUtils::NearestLanguageFile( iEnv->FsSession(), fileName );
+    iResourceFileOffset = iEnv->AddResourceFileL( fileName );
+    }
+
+// -----------------------------------------------------------------------------
+// CRfsHandler::SetDefaultLanguage()
+// -----------------------------------------------------------------------------
+void CRfsHandler::SetDefaultLanguage() const
+    {
+    TRACES("CRfsHandler::SetDefaultLanguage()");
+
+    CRepository* repository = NULL;
+    TRAPD( err, repository = CRepository::NewL( KCRUidCommonEngineKeys ) );
+    if ( err == KErrNone )
+        {
+        err = repository->Reset( KGSDisplayTxtLang );
+        TRACE_IF_ERROR_1("CRfsHandler::SetDefaultLanguage(): Failed to write language code: %d",err)
+        delete repository;
+        }
+    else
+        {
+        TRACES1("CRfsHandler::SetDefaultLanguage(): Failed to open repository: %d", err);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CRfsHandler::AskConfirmationL()
+// -----------------------------------------------------------------------------
+TBool CRfsHandler::AskConfirmationL( const TBool& aThisDestroyed, TRfsType aType )
+    {
+    TRACES("CRfsHandler::AskConfirmationL()");
+    CleanupResetPointerPushL( iQuery );
+
+    // Show the confirmation query.
+
+    iQuery = CAknQueryDialog::NewL(); // no tone as default
+
+    TInt resourceId = ( aType == ERfsNormal ) ? R_CONFIRM_RFS : R_CONFIRM_DEEP_RFS;
+    //iQuery->SetSize();
+    //iQuery->pref
+    
+    TBool ret = iQuery->ExecuteLD( resourceId );
+
+    if ( aThisDestroyed )
+        {
+        // this object was destroyed
+        ret = EFalse;
+        // remove cleanup item
+        CleanupStack::Pop();
+        }
+    else
+        {
+        // NULLs iQuery
+        CleanupStack::PopAndDestroy();
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CRfsHandler::DoCleanup()
+// -----------------------------------------------------------------------------
+void CRfsHandler::DoCleanup( TAny* aAny )
+    {
+    TRACES("CRfsHandler::DoCleanup()");
+    REINTERPRET_CAST( CRfsHandler*, aAny )->Cancel();
+    }
+
+// -----------------------------------------------------------------------------
+// CRfsHandler::CheckConnectionsL()
+// -----------------------------------------------------------------------------
+TBool CRfsHandler::CheckConnectionsL()
+	{
+    TInt callState( 0 );
+    TInt gprsState( 0 );
+    TInt wcdmaState( 0 );
+    TInt btState( 0 );
+    TInt irdaState( 0 );
+    TInt wlanState( 0 );
+    
+    RProperty property;
+
+    property.Attach( KPSUidCtsyCallInformation, KCTsyCallState );
+    property.Get( callState );
+
+    property.Attach( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothGetPHYCount );
+    property.Get( btState );
+
+    property.Attach( KIrdaPropertyCategory, KIrdaStatus );
+    property.Get( irdaState );
+
+    TUid categoryUid = { KUidSystemCategoryValue };
+    property.Attach( categoryUid, KPSUidGprsStatusValue );
+    property.Get( gprsState );
+
+    property.Attach( categoryUid, KPSUidWcdmaStatusValue );
+    property.Get( wcdmaState );
+
+    property.Attach( KPSUidWlan, KPSWlanIndicator );
+    property.Get( wlanState );
+    
+    property.Close();
+
+    if (IsGprs())
+        {
+        wcdmaState = EPSWcdmaUnattached;
+        }
+    else
+        {
+        gprsState = EPSGprsUnattached;
+        }
+
+    TRACES1("CRfsHandler::ActivateRfsL(): Call state:     %d", callState);
+    TRACES1("CRfsHandler::ActivateRfsL(): Gprs state:     %d", gprsState);
+    TRACES1("CRfsHandler::ActivateRfsL(): Wcdma state:    %d", wcdmaState);
+    TRACES1("CRfsHandler::ActivateRfsL(): BT state:       %d", btState);
+    TRACES1("CRfsHandler::ActivateRfsL(): IrDa State:     %d", irdaState);
+    TRACES1("CRfsHandler::ActivateRfsL(): WLan State:     %d", wlanState);
+
+    if( FeatureManager::FeatureSupported( KFeatureIdAlwaysOnlinePDPContext2 ) )
+        {
+        if (iAlwaysOnlineConnectionClosed)
+            {
+            gprsState = KErrUnknown;
+            wcdmaState = KErrUnknown;
+            }
+        }    
+
+#ifndef __WINS__ //Do not allow RFS in emulator
+    if (( callState != KErrUnknown &&
+          callState != EPSCTsyCallStateNone ) ||
+        ( gprsState != KErrUnknown &&
+          gprsState != EPSGprsUnattached &&
+          gprsState != EPSGprsAttach &&
+          gprsState != EPSGprsSuspend) ||
+        ( wcdmaState != KErrUnknown &&
+          wcdmaState != EPSWcdmaUnattached &&
+          wcdmaState != EPSWcdmaAttach &&
+          wcdmaState != EPSWcdmaSuspend) ||
+        ( btState ) ||
+        ( irdaState == TIrdaStatusCodes::EIrConnected ) ||
+        ( wlanState == EPSWlanIndicatorActive || wlanState == EPSWlanIndicatorActiveSecure ))
+#endif //__WINS__
+        {
+        HBufC* prompt = iEnv->AllocReadResourceLC( R_ACTIVE_CALLS );
+
+        CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue );
+
+        note->ExecuteLD( *prompt );
+
+        CleanupStack::PopAndDestroy( prompt );
+        return ETrue;
+        }
+
+    return EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// CRfsHandler::IsGprs()
+// -----------------------------------------------------------------------------
+TBool CRfsHandler::IsGprs() const
+    {
+    TRACES("CRfsHandler::IsGprs()");
+    RTelServer telServer;
+    RMobilePhone mobilePhone;
+    TInt error = telServer.Connect();
+    if ( error != KErrNone )
+        {
+        TRACES("CRfsHandler::IsGprs(): Connect to RTelServer failed");
+        return ETrue;
+        }
+    error = telServer.LoadPhoneModule( KMmTsyModuleName );
+    if ( error != KErrNone )
+        {
+        TRACES("CRfsHandler::IsGprs(): Loading phone module failed");
+        telServer.Close();
+        return ETrue;
+        }
+    RTelServer::TPhoneInfo phoneInfo;
+    error = telServer.GetPhoneInfo( KPhoneIndex, phoneInfo );
+    if ( error != KErrNone )
+        {
+        TRACES("CRfsHandler::IsGprs(): Getting phone info failed");
+        telServer.Close();
+        return ETrue;
+        }
+    error = mobilePhone.Open( telServer, phoneInfo.iName );
+    if ( error != KErrNone )
+        {
+        TRACES("CRfsHandler::IsGprs(): Opening RMobilePhone failed");
+        telServer.Close();
+        return ETrue;
+        }
+    RMobilePhone::TMobilePhoneNetworkMode networkMode = RMobilePhone::ENetworkModeGsm;
+    error = mobilePhone.GetCurrentMode( networkMode );
+
+    mobilePhone.Close();
+    telServer.Close();
+
+    if ( error == KErrNone && networkMode == RMobilePhone::ENetworkModeWcdma )
+        {
+        TRACES("CRfsHandler::IsGprs(): Currently in 3G network");
+        return EFalse;
+        }
+    else
+        {
+        TRACES("CRfsHandler::IsGprs(): Currently in 2G network");
+        return ETrue;
+        }
+    }
+
+//  End of File