videofeeds/livetvutils/src/CIptvEpgFileSwapper.cpp
changeset 0 96612d01cf9f
equal deleted inserted replaced
-1:000000000000 0:96612d01cf9f
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include "CIptvEpgFileSwapper.h"
       
    22 #include "IptvLiveLogger.h"
       
    23 #include <babackup.h>					// For CBaBackupSessionWrapper
       
    24 #include "MIptvEpgFileSwapObserver.h"
       
    25 #include <bautils.h>					// For BaflUtils
       
    26 
       
    27 // Constants
       
    28 const TInt KMicrosecondsToWasteAtOnce = 2000000; // 0.2 seconds
       
    29 const TInt KMaxSwapTries = 10; // We wait max 10*0.2 seconds for file releases
       
    30 
       
    31 // -----------------------------------------------------------------------------
       
    32 // CIptvEpgFileSwapper::NewL
       
    33 // Symbian two phase constructor
       
    34 // -----------------------------------------------------------------------------
       
    35 EXPORT_C CIptvEpgFileSwapper* CIptvEpgFileSwapper::NewL( const TFileName& aOldFileName,
       
    36 														 const TFileName& aNewFileName,
       
    37 														 MIptvEpgFileSwapObserver& aSwapObserver )
       
    38 	{
       
    39 	LIVE_TV_TRACE1( _L("CIptvEpgFileSwapper::NewL IN") );
       
    40 	CIptvEpgFileSwapper* self = new (ELeave) CIptvEpgFileSwapper( aOldFileName,
       
    41 																  aNewFileName,
       
    42 																  aSwapObserver );
       
    43 	CleanupStack::PushL( self );
       
    44 	self->ConstructL();
       
    45 	CleanupStack::Pop( self );
       
    46 	LIVE_TV_TRACE1( _L("CIptvEpgFileSwapper::NewL OUT") );
       
    47 	return self;
       
    48 	}
       
    49 	
       
    50 // -----------------------------------------------------------------------------
       
    51 // CIptvEpgFileSwapper::CIptvEpgFileSwapper
       
    52 // Default constructor
       
    53 // -----------------------------------------------------------------------------
       
    54 CIptvEpgFileSwapper::CIptvEpgFileSwapper( const TFileName& aOldFileName,
       
    55 										  const TFileName& aNewFileName,
       
    56 										  MIptvEpgFileSwapObserver& aSwapObserver ) :
       
    57 										  CActive( EPriorityLow ),
       
    58 										  iOldFileName( aOldFileName ),
       
    59 										  iNewFileName( aNewFileName ),
       
    60 										  iSwapObserver( aSwapObserver )
       
    61 	{
       
    62 	}
       
    63 	
       
    64 // -----------------------------------------------------------------------------
       
    65 // CIptvEpgFileSwapper::ConstructL
       
    66 // Second phase construction.
       
    67 // -----------------------------------------------------------------------------
       
    68 void CIptvEpgFileSwapper::ConstructL()
       
    69 	{
       
    70 	LIVE_TV_TRACE1( _L("CIptvEpgFileSwapper::ConstructL IN") );
       
    71 	// First create backupwrapper
       
    72 	iBackupWrapper = CBaBackupSessionWrapper::NewL();
       
    73 	User::LeaveIfError( iTimeWaster.CreateLocal() );
       
    74 	User::LeaveIfError( iFs.Connect() );
       
    75 	CActiveScheduler::Add( this );
       
    76 	LIVE_TV_TRACE1( _L("CIptvEpgFileSwapper::ConstructL OUT") );
       
    77 	}
       
    78 	
       
    79 // -----------------------------------------------------------------------------
       
    80 // CIptvEpgFileSwapper::~CIptvEpgFileSwapper
       
    81 // Destructor
       
    82 // -----------------------------------------------------------------------------
       
    83 CIptvEpgFileSwapper::~CIptvEpgFileSwapper()
       
    84 	{
       
    85 	LIVE_TV_TRACE1( _L("CIptvEpgFileSwapper::~CIptvEpgFileSwapper IN") );
       
    86 	Cancel();
       
    87 	iTimeWaster.Close();
       
    88 	iFs.Close();
       
    89 	delete iBackupWrapper;
       
    90 	LIVE_TV_TRACE1( _L("CIptvEpgFileSwapper::~CIptvEpgFileSwapper OUT") );
       
    91 	}
       
    92 	
       
    93 // -----------------------------------------------------------------------------
       
    94 // CIptvEpgFileSwapper::SwapFilesL
       
    95 // 
       
    96 // -----------------------------------------------------------------------------
       
    97 EXPORT_C void CIptvEpgFileSwapper::SwapFilesL()
       
    98 	{
       
    99 	LIVE_TV_TRACE1( _L("CIptvEpgFileSwapper::SwapFilesL IN") );
       
   100 	// If one of the files to be swapped does not exist what do people expect
       
   101 	// us to do here? Yes, we'll leave!
       
   102 	if( !BaflUtils::FileExists( iFs, iNewFileName ) ||
       
   103 		!BaflUtils::FileExists( iFs, iOldFileName ) )
       
   104 		{
       
   105 		LIVE_TV_TRACE1( _L("Either iNewFileName or iOldFileName was not found -> we are leaving with KErrPathNotFound") );
       
   106 		User::Leave( KErrPathNotFound );
       
   107 		}
       
   108 	// Request backup wrapper to signalize observers to close handles to
       
   109 	// files to allow swapping.
       
   110 	iBackupWrapper->CloseFileL( iNewFileName, MBackupObserver::EReleaseLockNoAccess );
       
   111 	iBackupWrapper->CloseFileL( iOldFileName, MBackupObserver::EReleaseLockNoAccess );
       
   112 	Cancel();
       
   113 	iTimeWaster.After( iStatus, KMicrosecondsToWasteAtOnce );
       
   114 	SetActive();
       
   115 	LIVE_TV_TRACE1( _L("CIptvEpgFileSwapper::SwapFilesL OUT") );
       
   116 	}
       
   117 	
       
   118 // -----------------------------------------------------------------------------
       
   119 // CIptvEpgFileSwapper::ReleaseFileLocks
       
   120 // 
       
   121 // -----------------------------------------------------------------------------
       
   122 void CIptvEpgFileSwapper::ReleaseFileLocks()
       
   123 	{
       
   124 	LIVE_TV_TRACE1( _L("CIptvEpgFileSwapper::ReleaseFileLocks IN") );
       
   125 	iBackupWrapper->RestartFile( iOldFileName );
       
   126 	iBackupWrapper->RestartFile( iNewFileName );
       
   127 	iSwapTriesAmount = 0;
       
   128 	LIVE_TV_TRACE1( _L("CIptvEpgFileSwapper::ReleaseFileLocks OUT") );
       
   129 	}
       
   130 	
       
   131 // Methods from CActive
       
   132 // -----------------------------------------------------------------------------
       
   133 // CIptvEpgFileSwapper::RunL
       
   134 // 
       
   135 // -----------------------------------------------------------------------------
       
   136 TInt CIptvEpgFileSwapper::RunError( TInt aError )
       
   137 	{
       
   138 	LIVE_TV_TRACE2( _L("CIptvEpgFileSwapper::RunError( %d ) IN"), aError );
       
   139 	if( aError != KErrNone )
       
   140 		{
       
   141 		// What shall we do... Any ideas? Anyone?
       
   142 		}
       
   143 	// In any case we need to cancel backup requests -> Tell observer to allow
       
   144 	// files to be opened again.
       
   145 	ReleaseFileLocks();
       
   146 	
       
   147 	iSwapObserver.FileSwapComplete( aError );
       
   148 	
       
   149 	// Return KErrNone to avoid active scheduler panic
       
   150 	return KErrNone;
       
   151 	}
       
   152 	
       
   153 // -----------------------------------------------------------------------------
       
   154 // CIptvEpgFileSwapper::RunL
       
   155 // 
       
   156 // -----------------------------------------------------------------------------
       
   157 void CIptvEpgFileSwapper::RunL()
       
   158 	{
       
   159 	LIVE_TV_TRACE2( _L("CIptvEpgFileSwapper::RunL IN, iStatus: %d"), iStatus.Int() );
       
   160 
       
   161 	if ( iStatus.Int() == KErrNone )
       
   162 		{
       
   163 		// Check if both files are not used anymore
       
   164 		TBool oldFileOpen = ETrue;
       
   165 		TBool newFileOpen = ETrue;
       
   166 		
       
   167 		// Check if files are open...
       
   168 		User::LeaveIfError( iFs.IsFileOpen( iOldFileName, oldFileOpen ) );
       
   169 		User::LeaveIfError( iFs.IsFileOpen( iNewFileName, newFileOpen ) );
       
   170 		
       
   171 		if( !oldFileOpen && !newFileOpen ) // Both files are closed -> we can do the swap
       
   172 			{
       
   173 			LIVE_TV_TRACE1( _L("both files are closed -> we can start swapping") );
       
   174 
       
   175 			// Get path to the "official" directory		
       
   176 			TFileName oldFileNamePath = BaflUtils::DriveAndPathFromFullName( iOldFileName );
       
   177 			
       
   178 			// Get path to the temp directory that contains the new stuff
       
   179 			TFileName newFileNamePath = BaflUtils::DriveAndPathFromFullName( iNewFileName );
       
   180 			
       
   181 			TInt error = KErrNone;
       
   182 			// Get rid of content in "official" directory (meaning the one under \videocenter\ecg\live\<serviceId>
       
   183 			LIVE_TV_TRACE2( _L("Deleting all files from %S"), &oldFileNamePath );
       
   184 			error = BaflUtils::DeleteFile( iFs, oldFileNamePath, CFileMan::ERecurse );
       
   185 			if( error != KErrNone )
       
   186 				{
       
   187 				LIVE_TV_TRACE2( _L("BaflUtils::DeleteFile( iFs, oldFileNamePath, ERecurse ); returned %d"), error );
       
   188 				User::Leave( error );
       
   189 				}
       
   190 			
       
   191 			LIVE_TV_TRACE3( _L("Moving all files from %S to %S"), &newFileNamePath, &oldFileNamePath );
       
   192 			error = BaflUtils::RenameFile( iFs, newFileNamePath, oldFileNamePath, CFileMan::EOverWrite );
       
   193 			
       
   194 			if( error != KErrNone )
       
   195 				{
       
   196 				LIVE_TV_TRACE2( _L("BaflUtils::CopyFile( newFileNamePath, oldFileNamePath, EOverWrite ); returned %d"), error );
       
   197 				User::Leave( error );
       
   198 				}
       
   199 			
       
   200 			// Release file locks for the given files
       
   201 			ReleaseFileLocks();
       
   202 			// Tell observer that everything went more than fine
       
   203 			iSwapObserver.FileSwapComplete( KErrNone );
       
   204 			}
       
   205 		else // At least one of the files is open -> waste some more time...
       
   206 			{
       
   207 			// We dont have time to wait all day for the file releases.
       
   208 			// If things didn't happen in 2 seconds we are done here.
       
   209 			if( iSwapTriesAmount > KMaxSwapTries )
       
   210 				{
       
   211 				LIVE_TV_TRACE3( _L("iSwapTriesAmount (%d) > KMaxSwapTries (%d) -> we are aborting the mission here"), iSwapTriesAmount, KMaxSwapTries );
       
   212 				ReleaseFileLocks();
       
   213 				iSwapObserver.FileSwapComplete( KErrAccessDenied );
       
   214 				}
       
   215 			else // Let's try again
       
   216 				{
       
   217 				LIVE_TV_TRACE4( _L("oldFileOpen = %d, newFileOpen = %d -> Wasting more time to make those close. Time already wasted %d times"), oldFileOpen, newFileOpen, iSwapTriesAmount );
       
   218 				iSwapTriesAmount++;
       
   219 				if ( !IsActive() )
       
   220 					{
       
   221 					iTimeWaster.After( iStatus, KMicrosecondsToWasteAtOnce );
       
   222 					SetActive();	
       
   223 					}
       
   224 				}
       
   225 			}	
       
   226 		}
       
   227 	LIVE_TV_TRACE1( _L("CIptvEpgFileSwapper::RunL OUT") );
       
   228 	}
       
   229 
       
   230 // -----------------------------------------------------------------------------
       
   231 // CIptvEpgFileSwapper::DoCancel
       
   232 // 
       
   233 // -----------------------------------------------------------------------------
       
   234 void CIptvEpgFileSwapper::DoCancel()
       
   235 	{
       
   236 	iTimeWaster.Cancel();
       
   237 	ReleaseFileLocks();
       
   238 	}
       
   239 	
       
   240 // End of file