deviceencryption/DevEncUi/src/DevEncUiMemoryEntity.cpp
author Simon Howkins <simonh@symbian.org>
Tue, 16 Nov 2010 11:00:04 +0000
branchRCL_3
changeset 55 58ed58285a84
parent 0 6a9f87576119
permissions -rw-r--r--
Fixed path to IBY files to be exported

/*
* Copyright (c) 2005 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:  Implementation of CDevEncUiMemoryEntity.
*
*/

#include "DevEncLog.h"
#include "DevEncUiMemoryEntity.h"
#include "DevEncUiMemInfoObserver.h"

#include "DevEncDiskUtils.h"
#include "DevEncSession.h"
#include <f32file.h> // for TDriveNumer
#include <DevEncEngineConstants.h>
#include <TerminalControl3rdPartyAPI.h>

// Local definitions
const TInt KPercent100( 100 );
const TTimeIntervalMicroSeconds32 KProgressInterval( 500000 ); // ms, 0.5 seconds
const TTimeIntervalMicroSeconds32 KPollInterval( 2000000 ); // ms, 2 seconds

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::CDevEncUiMemoryEntity()
// 
// --------------------------------------------------------------------------
CDevEncUiMemoryEntity::CDevEncUiMemoryEntity(
                        CEikonEnv* aEikonEnv,
                        TDevEncUiMemoryType aType )
    : iEikEnv( aEikonEnv ),
      iType( aType )
    {
    // TBI: Get the real states from the underlying SW levels
	iState = EDecrypted;
    }


// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::~CDevEncUiMemoryEntity()
// 
// --------------------------------------------------------------------------
CDevEncUiMemoryEntity::~CDevEncUiMemoryEntity()
    {
    if ( iPeriodic )
        {
        iPeriodic->Cancel();
        delete iPeriodic;
        }
    iObservers.Close();
    if ( iSession )
        {
        iSession->Close();
        delete iSession;
        }
    delete iDiskStatusObserver;
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::NewL()
// 
// --------------------------------------------------------------------------
CDevEncUiMemoryEntity* CDevEncUiMemoryEntity::NewL(
                                CEikonEnv* aEikonEnv,
                                TDevEncUiMemoryType aType )
	{
	CDevEncUiMemoryEntity* self =
	    CDevEncUiMemoryEntity::NewLC( aEikonEnv, aType );
	CleanupStack::Pop( self );
	return self;
	}

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::NewLC()
// 
// --------------------------------------------------------------------------
CDevEncUiMemoryEntity* CDevEncUiMemoryEntity::NewLC(
                                CEikonEnv* aEikonEnv,
                                TDevEncUiMemoryType aType )
	{
	CDevEncUiMemoryEntity* self =
	    new ( ELeave ) CDevEncUiMemoryEntity( aEikonEnv, aType );
	CleanupStack::PushL( self );
	self->ConstructL();
	return self;
	}

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::ConstructL()
// 
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::ConstructL()
	{
    DFLOG2( ">>CDevEncUiMemoryEntity::ConstructL, drive = %d", iType );

    switch( iType )
        {
    	case EPhoneMemory: iSession = new ( ELeave ) CDevEncSession( /*EDriveC*/EDriveE );
                           iDiskStatusObserver = CDiskStatusObserver::NewL( this, /*EDriveC*/EDriveE ); 
    		               break;
    		               
    	case EPrimaryPhoneMemory: iSession = new ( ELeave ) CDevEncSession( EDriveC );
                          iDiskStatusObserver = CDiskStatusObserver::NewL( this, EDriveC );
    	    		      break;
    	    		      
    	case EMemoryCard: iSession = new ( ELeave ) CDevEncSession( /*EDriveE*/EDriveF );
                          iDiskStatusObserver = CDiskStatusObserver::NewL( this, /*EDriveE*/EDriveF );
    	    		      break;    	    		               
        }

    // Get initial memory state
    TInt nfeDiskStatus( EUnmounted );
#ifndef __WINS__
    User::LeaveIfError( iSession->Connect() );
    TInt err = iSession->DiskStatus( nfeDiskStatus );
    if ( err )
        {
        DFLOG2( "Could not get disk status, error %d", err );
        nfeDiskStatus = EDecrypted;
        //User::Leave( err );
        }
#else
    nfeDiskStatus = EDecrypted;
#endif
    SetState( nfeDiskStatus );

    if ( ( iState == EEncrypting ) ||
         ( iState == EDecrypting ) )
        {
        // If the app was started in the middle of an ongoing operation,
        // start polling the progress
        StartPolling( KProgressInterval );
        }
    else
        {
        // Otherwise poll every once in a while to see if the status changes
        //StartPolling( KPollInterval );
        }

    DFLOG( "<<CDevEncUiMemoryEntity::ConstructL" );
	}

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::AddObserverL()
// 
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::AddObserverL( MDevEncUiMemInfoObserver* aInfoObserver )
    {
    DFLOG( "CDevEncUiMemoryEntity::AddObserverL" );
    if ( !aInfoObserver )
        {
        User::Leave( KErrArgument );
        }
    iObservers.AppendL( aInfoObserver );

    // The new observer probably wants to know the current states
    UpdateMemoryInfo();
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::RemoveObserver()
// 
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::RemoveObserver( MDevEncUiMemInfoObserver* aInfoObserver )
    {
    if ( !aInfoObserver )
        {
        return;
        }
    TInt index( iObservers.Find( aInfoObserver ) );
    if ( index != KErrNotFound )
        {
        iObservers.Remove( index );
        }
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::StartEncryptionL()
// 
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::StartEncryptionL()
    {
    DFLOG( ">>CDevEncUiMemoryEntity::StartEncryptionL" );

#ifndef __WINS__

    if ( ! iSession->Connected() )
        {
        User::LeaveIfError( iSession->Connect() );
        DFLOG( "Connected" );
        }

    // Make sure the memory is decrypted
    TInt nfeDiskStatus( EUnmounted );
    TInt err = iSession->DiskStatus( nfeDiskStatus );
    if ( err )
        {
        DFLOG2( "Could not get disk status, error %d", err );
        User::Leave( err );
        }
    if ( nfeDiskStatus != EDecrypted )
        {
        DFLOG2( "Memory is in wrong state (%d), leaving", nfeDiskStatus );
        User::Leave( KErrNotReady );
        }

    // Launch the encryption process
    err = iSession->StartDiskEncrypt();
    if ( err )
        {
        DFLOG2( "Could not start encryption, error %d", err );
        User::Leave( err );
        }

    // Set our internal state and update UI
    iPercentDone = 0;
    SetState( EEncrypting );

    // Start a timer to periodically update the memory state in the UI
    StartPolling( KProgressInterval );

#endif // __WINS__

    DFLOG( "<<CDevEncUiMemoryEntity::StartEncryptionL" );
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::StartPolling()
// Starts a timer to periodically update the memory state in the UI
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::StartPolling(
                                      TTimeIntervalMicroSeconds32 aInterval )
    {
    TInt error( KErrNone );
    TRAP( error, DoStartPollingL( aInterval ) );
    DFLOG2( "CDevEncUiMemoryEntity::StartPolling result %d", error );
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::DoStartPollingL()
// Starts a timer to periodically update the memory state in the UI
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::DoStartPollingL(
                                      TTimeIntervalMicroSeconds32 aInterval )
    {
    TCallBack pollCallBack( PollTick, static_cast<TAny*>( this ) );
    TCallBack progressCallBack( ProgressTick, static_cast<TAny*>( this ) );

    if ( !iPeriodic )
        {
        iPeriodic = CPeriodic::NewL( EPriorityNormal );
        }
    iPeriodic->Cancel();

    if ( aInterval == KProgressInterval )
        {
        iPeriodic->Start( 0, aInterval, progressCallBack );
        }
    else
        {
        iPeriodic->Start( 0, aInterval, pollCallBack );
        }
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::StartDecryptionL()
// 
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::StartDecryptionL()
    {
    DFLOG( ">>CDevEncUiMemoryEntity::StartDecryptionL" );

#ifndef __WINS__

    if ( ! iSession->Connected() )
        {
        User::LeaveIfError( iSession->Connect() );
        DFLOG( "Connected " );
        }

    // Make sure the memory is encrypted
    TInt nfeDiskStatus( EUnmounted );
    TInt err = iSession->DiskStatus( nfeDiskStatus );
    if ( err )
        {
        DFLOG2( "Could not get disk status, error %d", err );
        //User::Leave( err );
        }
    if ( nfeDiskStatus != EEncrypted )
        {
        DFLOG2( "Memory is in wrong state (%d), leaving", nfeDiskStatus );
        User::Leave( KErrNotReady );
        }

    // Launch the decryption process
    err = iSession->StartDiskDecrypt();
    if ( err )
        {
        DFLOG2( "Could not start decryption, error %d", err );
        User::Leave( err );
        }

    // Set our internal state and update UI
    iPercentDone = 0;
    SetState( EDecrypting );

    // Start a timer to periodically update the memory state in the UI
    StartPolling( KProgressInterval );

#endif // __WINS__
    
    DFLOG( "<<CDevEncUiMemoryEntity::StartDecryptionL" );
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::ProgressTick()
// 
// --------------------------------------------------------------------------
TInt CDevEncUiMemoryEntity::ProgressTick( TAny* aPtr )
    {
    CDevEncUiMemoryEntity* self = static_cast<CDevEncUiMemoryEntity*>( aPtr );
    self->DoProgressTick();
    return 0;
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::DoProgressTick()
// 
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::DoProgressTick()
    {
    CheckProgress();
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::PollTick()
// 
// --------------------------------------------------------------------------
TInt CDevEncUiMemoryEntity::PollTick( TAny* aPtr )
    {
    CDevEncUiMemoryEntity* self = static_cast<CDevEncUiMemoryEntity*>( aPtr );
    TInt error( KErrNone );
    TRAP( error, self->DoPollTickL() );
    DFLOG2( "CDevEncUiMemoryEntity::PollTick result %d", error );
    return 0;
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::DoPollTickL()
// 
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::DoPollTickL()
    {
    DFLOG( "CDevEncUiMemoryEntity::DoPollTickL" );
    TInt nfeDiskStatus( EUnmounted );
    TInt err = iSession->DiskStatus( nfeDiskStatus );
    if ( err )
        {
        DFLOG2( "Could not get disk status, error %d", err );
        // Ignore error
        return;
        }
    if ( ( nfeDiskStatus == EEncrypting ) ||
         ( nfeDiskStatus == EDecrypting ) )
        {
        // Some other component has started an encryption operation.
        // Indicate this to the UI and start polling the progress.
        DFLOG2( "CDevEncUiMemoryEntity::DoPollTick: New operation %d",
                nfeDiskStatus );
        SetState( nfeDiskStatus );
        StartPolling( KProgressInterval );
        }
    else
        {
        if ( iState != nfeDiskStatus )
            {
            DFLOG( "CDevEncUiMemoryEntity::DoPollTickL => SetState" );
            // The Mmc status has changed, but we are not in the middle of
            // any operation. Just set the new state.
            SetState( nfeDiskStatus );
            }
        }
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::SetState()
// 
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::SetState( TUint aState )
    {
    DFLOG3( "CDevEncUiMemoryEntity::SetState, prev %d, new %d",
            iState, aState );
    iState = aState;
    UpdateMemoryInfo();
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::CheckProgress()
// 
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::CheckProgress()
    {
    ASSERT( iSession );
    ASSERT( iSession->Connected() );

    TInt err = iSession->Progress( iPercentDone );

    if ( err )
        {
        DFLOG( "Could not get progress" );
        iPeriodic->Cancel();
        }
    else if ( iPercentDone >= KPercent100 )
        {
        DFLOG( "Operation complete" );
        iPeriodic->Cancel();
        iPercentDone = 0;

        // The disk needs to be finalized, but the finalization is done in
        // the starter component.
        
        DFLOG2( "CDevEncUiMemoryEntity::CheckProgress => iSession->DriveNumber() = %d", iSession->DriveNumber()  );

        if ( iState == EDecrypted && iSession->DriveNumber() == EDriveC )
            {
            DFLOG( "CDevEncUiMemoryEntity::CheckProgress => RestoreAutolockSettings" );
            RestoreAutolockSettings();
            }
        // Restart the polling at a slower pace
        // StartPolling( KPollInterval );
        }
    else // Not yet finished...
        {
        UpdateMemoryInfo();
        }
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::RestoreAutolockSettings()
// 
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::RestoreAutolockSettings()
    {
#ifndef __WINS__
    //the user chose to decrypt the phone memory. restore the previuos autolock settings
    RTerminalControl terminalCtrl;
    TInt ctrlConnect = terminalCtrl.Connect();
    DFLOG2( "DEVENC: terminal control connected %d", ctrlConnect );
    
    RTerminalControl3rdPartySession session;
    TInt retValue = session.Open( terminalCtrl );
    DFLOG2( "DEVENC: terminal control session open %d", retValue );
    
    //read the current autolock period
    TBuf8<21> autoLockPeriodBuf;
    TInt err2 = session.GetDeviceLockParameter( RTerminalControl3rdPartySession::ETimeout, autoLockPeriodBuf );
    DFLOG2( "DEVENC: max value get returned value %d", err2 );
    
    //this is set to 0 because the Tarm control prevent the autolock from being disabled otherwise.
    TBuf8<21> oldMaxPeriodBuf;
    oldMaxPeriodBuf.AppendNum( 0 );
    TInt err = session.SetDeviceLockParameter( RTerminalControl3rdPartySession::EMaxTimeout, oldMaxPeriodBuf );
    DFLOG2( "DEVENC: max value set returned value %d", err );
    
    //set the autolock period as it was previously
    err = session.SetDeviceLockParameter( RTerminalControl3rdPartySession::ETimeout, autoLockPeriodBuf );
    DFLOG2( "DEVENC: max value set returned value %d", err );
    
    session.Close();
    terminalCtrl.Close();
#endif
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::UpdateMemoryInfo()
// 
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::UpdateMemoryInfo()
    {
    DFLOG( "CDevEncUiMemoryEntity::UpdateMemoryInfo" );
    for ( TInt i = 0; i < iObservers.Count(); i++ )
        {
        iObservers[i]->UpdateInfo( iType, iState, iPercentDone );
        }
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::State()
// 
// --------------------------------------------------------------------------
TUint CDevEncUiMemoryEntity::State() const
    {
    return iState;
    }

// --------------------------------------------------------------------------
// CDevEncUiMemoryEntity::DiskStatusChangedL()
// From MDiskStatusObserver
// --------------------------------------------------------------------------
void CDevEncUiMemoryEntity::DiskStatusChangedL( TInt aNfeStatus )
    {
    if ( ( aNfeStatus == EEncrypting ) ||
         ( aNfeStatus == EDecrypting ) )
        {
        // Some other component has started an encryption operation.
        // Indicate this to the UI and start polling the progress.
        DFLOG2( "CDevEncStarterMemoryEntity::DoPollTick: New operation %d",
        		aNfeStatus );
        SetState( aNfeStatus );
        StartPolling( KProgressInterval );
        }
    else
        {
        if ( iState != aNfeStatus )
            {
            // The Mmc status has changed, but we are not in the middle of
            // any operation. Just set the new state.
            SetState( aNfeStatus );
            }
        }
    }

// End of File