devencdiskutils/DevEncStarter/src/DevEncStarterMmcObserver.cpp
changeset 0 164170e6151a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devencdiskutils/DevEncStarter/src/DevEncStarterMmcObserver.cpp	Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,491 @@
+/*
+* Copyright (c) 2007 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 CDevEncStarterMmcObserver
+*
+*  Version    : %version: 9 %, %date_modified: Fri Nov 13 11:16:40 2009 % by %derived_by: e0326969 %
+*/
+
+
+#include <centralrepository.h>
+#include <DevEncExternalCRKeys.h>
+#include <DevEncEngineConstants.h>
+#include "DevEncLog.h"
+#include "DevEncMmcObserver.h"
+#include "DevEncStarterMmcObserver.h"
+#include "DevEncStarterMemoryEntity.h"
+#include "DevEncStarterUtils.h"
+#include "DevEncUids.hrh"
+#include "MmcInfo.h"
+
+const TInt mmcDrive( /*EDriveE*/EDriveF );
+//const TInt KPowerKeyCode( EKeyPowerOff );
+//const TInt KPowerKeyScanCode( EStdKeyPowerOff );
+
+// -----------------------------------------------------------------------------
+// CDevEncStarterMmcObserver::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+CDevEncStarterMmcObserver* CDevEncStarterMmcObserver::NewL(
+                                               CDevEncStarterUtils*& aUtils )
+    {
+    CDevEncStarterMmcObserver* self =
+        new ( ELeave ) CDevEncStarterMmcObserver( aUtils );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CDevEncStarterMmcObserver::CDevEncStarterMmcObserver
+// 
+// -----------------------------------------------------------------------------
+CDevEncStarterMmcObserver::CDevEncStarterMmcObserver(
+                                               CDevEncStarterUtils*& aUtils )
+    : iUtils( aUtils )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CDevEncStarterMmcObserver::ConstructL
+// 
+// -----------------------------------------------------------------------------
+void CDevEncStarterMmcObserver::ConstructL()
+    {
+    DFLOG( "CDevEncStarterMmcObserver::ConstructL" );
+    // Central repository settings
+    iCrSettings = CRepository::NewL( TUid::Uid( KCRDevEncUiSettings ) );
+
+    DFLOG( "ObsCon 1" );
+    
+    // Create objects representing the different types of memory
+    // The order is important
+    CDevEncStarterMemoryEntity* phoneMemory =
+        CDevEncStarterMemoryEntity::NewLC( EPhoneMemory );
+    iMemEntities.AppendL( phoneMemory );
+    CleanupStack::Pop( phoneMemory );
+
+        DFLOG( "ObsCon 2" );
+
+    CDevEncStarterMemoryEntity* memoryCard =
+        CDevEncStarterMemoryEntity::NewLC( EMemoryCard );
+    iMemEntities.AppendL( memoryCard );
+    CleanupStack::Pop( memoryCard );
+
+        DFLOG( "ObsCon 3" );
+    CDevEncStarterMemoryEntity* massMemory =
+                CDevEncStarterMemoryEntity::NewLC( EPrimaryPhoneMemory );
+    
+    iMemEntities.AppendL( massMemory );
+    CleanupStack::Pop( massMemory );
+
+    // Create an MMC file system observer
+    User::LeaveIfError( iFs.Connect() );
+    iObserver = CMmcObserver::NewL( this, &iFs );
+    iObserver->StartObserver();
+    
+        DFLOG( "ObsCon 4" );
+
+    // Call the MMC callback function once to get the initial card status
+    MMCStatusChangedL();
+
+        DFLOG( "ObsCon 5" );
+
+    // This class needs to observe memory card status changes.
+    // (This call results in a call to UpdateInfo, hence we need to be fully
+    // constructed before this.)
+    iMemEntities[ EMemoryCard ]->AddObserverL( this );
+
+        DFLOG( "ObsCon 6" );
+
+    }
+
+// -----------------------------------------------------------------------------
+// CDevEncStarterMmcObserver::~CDevEncStarterMmcObserver
+// 
+// -----------------------------------------------------------------------------
+CDevEncStarterMmcObserver::~CDevEncStarterMmcObserver()
+    {
+    delete iObserver;
+    iFs.Close();
+
+    if ( iMemEntities.Count() > EMemoryCard ) 
+	    {
+        iMemEntities[ EMemoryCard ]->RemoveObserver( this );
+        for ( TInt i = 0; i < iMemEntities.Count(); i++ )
+            {
+            delete iMemEntities[i];
+            }
+        iMemEntities.Close();
+		}
+    delete iCrSettings;
+    }
+
+// -----------------------------------------------------------------------------
+// CDevEncStarterMmcObserver::MMCStatusChangedL
+// From MMemoryCardObserver
+// -----------------------------------------------------------------------------
+void CDevEncStarterMmcObserver::MMCStatusChangedL()
+    {
+    DFLOG( "CDevEncStarterMmcObserver::MMCStatusChangedL" );
+    TVolumeInfo volInfo;
+
+    TInt err = iFs.Volume( volInfo, /*EDriveE*/EDriveF );
+    switch ( err )
+        {
+        case KErrNone:
+            {
+            // Readable MMC inserted
+            DFLOG( "MMC inserted" );
+            iMmcStatus = EMmcOk;
+            
+            break;
+            }
+
+        case KErrNotReady:
+            {
+            // MMC ejected
+            DFLOG( "MMC ejected" );
+            iMmcStatus = EMmcNotPresent;
+            //This is because for some reason when the memory card is ejected the Disk status observer is not notified
+            //thus the Ui is started even if the MMC is removed.
+            iMemEntities[ EMemoryCard ]->SetState( EUnmounted );
+            break;
+            }
+
+        case KErrCorrupt:
+            {
+            // Corrupt or unformatted MMC, or wrong key
+            DFLOG( "MMC corrupt, unformatted or encrypted with other key" );
+            iMmcStatus = EMmcNotReadable;
+
+                break;
+            }
+
+        default:
+            {
+            DFLOG2( "RFs::Volume returned error %d", err );
+            break;
+            }
+        } // switch
+    }
+
+// -----------------------------------------------------------------------------
+// CDevEncStarterMmcObserver::GetInfo
+// From MMemoryCardObserver
+// -----------------------------------------------------------------------------
+TInt CDevEncStarterMmcObserver::GetInfo( TMmcInfo& aInfo )
+    {
+    TVolumeInfo volInfo;
+    TDriveInfo driveInfo;
+
+    // Check if MMC mounted
+    TInt err = CheckMMC();
+
+    DFLOG2( "CDevEncStarterMmcObserver::GetInfo - CheckMMC returned %d", err );
+    
+    if( !err )
+        {
+        // MMC is mounted, get further information
+        err = iFs.Drive( driveInfo, mmcDrive );
+        
+        DFLOG2( "CDevEncStarterMmcObserver::GetInfo - iFs.Drive returned %d", err );
+        DFLOG3( "CDevEncStarterMmcObserver::GetInfo - driveInfo.iDriveAtt %d, driveInfo.iMediaAtt %d",
+                driveInfo.iDriveAtt,
+                driveInfo.iMediaAtt );
+
+        if ( !err )
+            {
+            aInfo.iIsFormattable = driveInfo.iMediaAtt & KMediaAttFormattable;
+            aInfo.iIsLockable = driveInfo.iMediaAtt & KMediaAttLockable;
+            aInfo.iIsLocked = driveInfo.iMediaAtt & KMediaAttLocked;
+            aInfo.iIsReadOnly = driveInfo.iMediaAtt & KMediaAttWriteProtected;
+            aInfo.iIsPasswordSet = driveInfo.iMediaAtt & KMediaAttHasPassword;
+
+            if ( !aInfo.iIsLocked )
+                {
+                // Then get volume info for name etc.
+                err = iFs.Volume( volInfo, mmcDrive );
+//#if defined _DEBUG
+#if 0
+                TBuf<50> tempDes1; // helpers for showing valid memory amount, which do not fit in 32 bits
+                TBuf<50> tempDes2;
+
+                tempDes1.Num( volInfo.iSize );
+                tempDes2.Num( volInfo.iFree );
+                DFLOG2( "CDevEncStarterMmcObserver::GetInfo - iFs.Volume returned %d", err );
+                DFLOG2( "CDevEncStarterMmcObserver::GetInfo - volInfo iUniqueID %d, iSize, iFree, iName:", 
+                        volInfo.iUniqueID );
+                DFLOGBUF( tempDes1 );
+                DFLOGBUF( tempDes2 );
+                DFLOGBUF( volInfo.iName );
+#endif // _DEBUG
+                }
+            else
+                {
+                err = KErrLocked;
+                }
+            }
+        else
+            {
+            err = KErrNotReady;
+            }
+        }
+
+    DFLOG2( "CDevEncStarterMmcObserver::GetInfo - err %d", err );
+    
+    if( !err )
+        {
+        // MMC ok, get rest of the information
+        aInfo.iIsInserted = ETrue;
+        aInfo.iIsInUse = EFalse;
+        aInfo.iName = volInfo.iName;
+        aInfo.iUid = volInfo.iUniqueID;
+        // Use all 64 bits
+        aInfo.iCapacity = volInfo.iSize;
+        aInfo.iSpaceFree = volInfo.iFree;
+
+        // Check if the volume is formatted
+        aInfo.iIsFormatted = volInfo.iSize > 0;
+
+        // Test if a previous backup exists
+        aInfo.iBackupExists = EFalse; //BaflUtils::FileExists( iFs, aBackupFile );
+        }
+    else
+        {
+        // By default set values as 
+        aInfo.iIsInserted = EFalse;
+        aInfo.iIsInUse = EFalse;
+        aInfo.iIsFormatted = EFalse;
+        aInfo.iBackupExists = EFalse;
+
+        switch( err )
+            {
+            case KErrInUse:
+                {
+                aInfo.iIsInserted = ETrue;
+                aInfo.iIsInUse = ETrue;
+                break;
+                }
+            case KErrNotReady:
+                {
+                // If card is not ready, but media attributes set, it is reserved.
+                if ( driveInfo.iMediaAtt )
+                    {
+                    aInfo.iIsInserted = ETrue;
+                    aInfo.iIsInUse = ETrue;
+                    }
+                break;
+                }
+            case KErrCorrupt:
+                {
+                aInfo.iIsInserted = ETrue;
+                break;
+                }
+            case KErrLocked:
+                {
+                // Could not mount due card locked or volume info query returned card locked.
+                // Hence info-flags possibly set accoring to iMediaAtt are overridden.
+                aInfo.iIsInserted = ETrue;
+                aInfo.iIsFormatted = ETrue;
+                aInfo.iIsLocked = ETrue;
+                aInfo.iIsPasswordSet = ETrue;
+                aInfo.iIsLockable = ETrue;
+                break;
+                }
+            default:
+                {
+                break;
+                }
+            }
+        }
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CDevEncStarterMmcObserver::CheckMMC
+// 
+// -----------------------------------------------------------------------------
+TInt CDevEncStarterMmcObserver::CheckMMC()
+    {
+    // Check if MMC mounted, mount if required
+    TFullName fsname;
+
+    // If can't use the drive, returns KErrNotFound
+    TInt err = iFs.FileSystemName( fsname, mmcDrive );
+
+    if ( !err )
+        {
+        // MMC found. Checking if it is mounted
+        if ( fsname.Length( ) == 0 )
+            {
+            // MMC not mounted ( file system name is empty ) 
+            DFLOG( "Mmc not mounted" );
+            err = KErrDisMounted;
+            }
+        }
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CDevEncStarterMmcObserver::CheckMMC
+// 
+// -----------------------------------------------------------------------------
+void CDevEncStarterMmcObserver::LogInfo( const TMmcInfo& aInfo ) const
+    {
+    DFLOG2( "aInfo.iIsFormattable %d", aInfo.iIsFormattable ? 1 : 0 );
+    DFLOG2( "aInfo.iIsFormatted %d", aInfo.iIsFormatted ? 1 : 0 );
+    DFLOG2( "aInfo.iIsLockable %d", aInfo.iIsLockable ? 1 : 0 );
+    DFLOG2( "aInfo.iIsLocked %d", aInfo.iIsLocked ? 1 : 0 );
+    DFLOG2( "aInfo.iIsReadOnly %d", aInfo.iIsReadOnly ? 1 : 0 );
+    DFLOG2( "aInfo.iIsPasswordSet %d", aInfo.iIsPasswordSet ? 1 : 0 );
+    DFLOG2( "aInfo.iIsInserted %d", aInfo.iIsInserted ? 1 : 0 );
+    DFLOG2( "aInfo.iBackupExists %d", aInfo.iBackupExists ? 1 : 0 );
+    DFLOG2( "aInfo.iIsInUse %d", aInfo.iIsInUse ? 1 : 0 );
+    }
+
+// --------------------------------------------------------------------------
+// Called by memory entity when memory status changes.
+// 
+// --------------------------------------------------------------------------
+void CDevEncStarterMmcObserver::UpdateInfo( TDevEncUiMemoryType aType,
+                                            TUint aState,
+                                            TUint /*aProgress*/ )
+    {
+    DFLOG3( "CDevEncStarterMmcObserver::UpdateInfo, type %d, state %d",
+            aType, aState );
+    DFLOG2( "Phone state %d", iPhoneEncState );
+    DFLOG2( "Mmc state %d", iMmcStatus );
+
+    TBool startUi = NeedToStartUi( aType, aState );
+
+    if ( aType == EPhoneMemory )
+        {
+        iPhoneEncState = aState;
+        }
+    else // EMemoryCard
+        {
+        iMmcEncState = aState;    
+        }
+
+    if ( startUi )
+        {
+        TInt error( KErrNone );
+        TRAP( error, iUtils->StartAppL( KDevEncUiUid,
+                                        this ) );
+        DFLOG2( "App start requested, result %d", error );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CDevEncStarterMmcObserver::NeedToStartUi
+// 
+// -----------------------------------------------------------------------------
+TBool CDevEncStarterMmcObserver::NeedToStartUi( TDevEncUiMemoryType aType,
+                                                TUint aState )
+    {
+    TBool startUi( EFalse );
+    
+    DFLOG2( "CDevEncStarterMmcObserver::NeedToStartUi => aState = %d",
+    		aState );
+    DFLOG2( "CDevEncStarterMmcObserver::NeedToStartUi => iMmcStatus = %d",
+    		iMmcStatus );
+    DFLOG2( "CDevEncStarterMmcObserver::NeedToStartUi => iMmcEncState = %d",
+    		iMmcEncState );
+
+    // Check encryption key status
+    TInt mmcKeyInDriver( 0 );
+    TInt error = iCrSettings->Get( KDevEncUserSettingMemoryCard,
+                                   mmcKeyInDriver );
+    if ( error )
+        {
+        DFLOG2( "Cenrep get error %d", error );
+        return startUi;
+        }
+    
+    if ( ( iMmcStatus == EMmcOk ) && 
+         ( iMmcEncState == EUnmounted ) &&
+         ( aState == EDecrypted ) )
+        {
+        // A readable memory card has just been inserted
+    
+        if ( mmcKeyInDriver )
+            {
+            // We have a valid encryption key, but the newly inserted
+            // card is decrypted. Ask if the user wants to encrypt.
+            // (see UI spec 2.13)
+            startUi = ETrue;
+            }
+        }
+
+    if ( ( iMmcStatus == EMmcNotReadable ) && 
+         ( iMmcEncState == EUnmounted ) &&
+         ( aState == ECorrupted ) )
+        {
+        // An unreadable memory card has just been inserted
+        
+        if ( mmcKeyInDriver )
+            {
+            // We seem to have the wrong encryption key in the driver.
+            // Inform the user that the card cannot be used.
+            // (see UI spec 2.16)
+            startUi = ETrue;
+            }
+        else
+            {
+            // We have no encryption key in the driver.
+            // Ask if the user wants to import a key and decrypt.
+            // (see UI spec 2.17)
+            startUi = ETrue;
+            }
+        }
+
+    if ( ( iMmcStatus == EMmcNotReadable ) && 
+         ( iMmcEncState == ECorrupted ) &&
+         ( aState == ECorrupted ) )
+        {
+        // We have an unreadable memory card, and tried to load a new key
+        // but the card is still unreadable. Inform the user and let the user
+        // select some other key. (see UI spec 2.10)
+        startUi = ETrue;
+        }
+
+    if ( ( iMmcStatus == EMmcOk ) && 
+         ( iMmcEncState == ECorrupted ) &&
+         ( aState == EEncrypted ) )
+        {
+        // We have just imported the correct key and the card is now
+        // readable. Show a note to the user.
+        // (see UI spec 2.7)
+        startUi = ETrue;
+        }
+    return startUi;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CDevEncStarterMmcObserver::AppStarted
+// 
+// -----------------------------------------------------------------------------
+void CDevEncStarterMmcObserver::AppStarted( const TUint32& aUid )
+    {
+    if ( !iUtils )
+        {
+        DFLOG( "CDevEncStarterMmcObserver::AppStarted error: no utils" );
+        return;
+        }
+    }
+
+// End of file