diff -r 000000000000 -r 3ad9d5175a89 remotestoragefw/remotefileengine/src/rsfwclosestatemachine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/remotestoragefw/remotefileengine/src/rsfwclosestatemachine.cpp Thu Dec 17 09:07:59 2009 +0200 @@ -0,0 +1,317 @@ +/* +* Copyright (c) 2005-2006 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: State machine for closing a file +* +*/ + +#include + +#include "rsfwclosestatemachine.h" +#include "rsfwfileentry.h" +#include "rsfwfiletable.h" +#include "rsfwvolumetable.h" +#include "rsfwvolume.h" +#include "rsfwfileengine.h" +#include "rsfwrfeserver.h" +#include "rsfwwaitnotemanager.h" +#include "rsfwlockmanager.h" +#include "mdebug.h" + + +// CRsfwCloseStateMachine + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::CRsfwCloseStateMachine +// ---------------------------------------------------------------------------- +// +CRsfwCloseStateMachine::CRsfwCloseStateMachine() + { + } + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::~CRsfwCloseStateMachine +// ---------------------------------------------------------------------------- +// +CRsfwCloseStateMachine::~CRsfwCloseStateMachine() + { + } + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::CompleteRequestL +// ---------------------------------------------------------------------------- +// +CRsfwCloseStateMachine::TState* CRsfwCloseStateMachine::CompleteRequestL(TInt aError) + { + DEBUGSTRING(("CRsfwCloseStateMachine::CompleteRequestL::ErrorL %d", aError)); + + // decrease count of files opened for writing + Node()->iFileTable->UpdateOpenFileCount(-1); + + if (iFlags != ECloseLastFlushFailed) + { + // file was closed successfully (not saved locally and deleted from filetable) + DEBUGSTRING(("file was closed successfully (not saved locally and deleted from filetable)")); + + // If we just wrote the file to the server set attributes from the cache + // file's attributes. + if (Node()->CacheFileName() && Node()->IsOpenedForWriting()) + { + Node()->SetCached(ETrue); + FileEngine()->SetupAttributes(*Node()); + } + + // Add new cached and closed file to LRU cache managemet list. + if ((Node()->Type() == KNodeTypeFile) && + (Node()->iCachedSize >0)) + { + Volumes()->AddToLRUPriorityListL(Node(), Node()->CachePriority()); + } + + // If no content is in the cache then add closed file to the metadata LRU list. + if ((Node()->Type() == KNodeTypeFile) && + (Node()->iCachedSize == 0)) + { + Volumes()->AddToMetadataLRUPriorityListL(Node(), Node()->CachePriority()); + } + + // uncommitted modifications have been resolved + Node()->SetOpenedForWriting(EFalse); + } + else + { + // remove the file from filetable as it was saved locally as a result of error + // (either ECloseLastFlushFailed was set or we attempted to write the data and + // there was error) + Node()->iFileTable->RemoveL(Node()); + delete Node(); + } + + CompleteAndDestroyState()->SetErrorCode(aError); + // remove the wait note + DeleteWaitNoteL(ETrue); + return CompleteAndDestroyState(); + } + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::ErrorOnStateEntry +// ---------------------------------------------------------------------------- +// +CRsfwCloseStateMachine::TState* CRsfwCloseStateMachine::ErrorOnStateEntry(TInt aError) + { + DEBUGSTRING16(("CRsfwCloseStateMachine::ErrorOnStateEntry %d", aError)); + + if (aError == KErrNotFound) + { + // the node was not found, do not try to clos it + return CRsfwRfeStateMachine::ErrorOnStateEntry(aError); + } + else + { + // don't show 'save as' note if transfer was cancelled explicitily by the user + if (iFlags == ECloseLastFlushFailed && !Node()->IsCancelled()) + { + // modified file, last flush failed so let user to save the file locally + return new CRsfwCloseStateMachine::TSaveLocallyState(this); + } + else + { + // in any case, we mark this file as closed + CRsfwCloseStateMachine::TState* nextstate = NULL; + TRAP_IGNORE(nextstate = CompleteRequestL(KErrNone)); + return nextstate; + } + } + + } + +// Release lock + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::TReleaseLockState::TReleaseLockState +// ---------------------------------------------------------------------------- +// +CRsfwCloseStateMachine:: +TReleaseLockState::TReleaseLockState(CRsfwCloseStateMachine* aParent) + : iOperation(aParent) + { + } + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::TReleaseLockState::EnterL +// ---------------------------------------------------------------------------- +// +void CRsfwCloseStateMachine::TReleaseLockState::EnterL() + { + DEBUGSTRING(("CRsfwCloseStateMachine::TReleaseLockState::EnterL")); + + if (!iOperation->Node()) + { + User::Leave(KErrNotFound); + } + + DEBUGSTRING16(("closing fid %d (%S)", + iOperation->Node()->Fid().iNodeId, + iOperation->Node()->Name())); + + + if (iOperation->Node()->Type() != KNodeTypeFile) + { + // Sanity + DEBUGSTRING(("closing something else than a file!!!")); + User::Leave(KErrArgument); + } + + TRfeCloseInArgs* inArgs = + static_cast(iOperation->iInArgs); + + DEBUGSTRING(("flags %d", inArgs->iFlags)); + + iOperation->iFlags = inArgs->iFlags; + + if (iOperation->Node()->IsLocked()) + { + // always attempt to unlock the file if it was locked + iOperation->FileEngine()->LockManager()->ReleaseLockL(iOperation->Node(), + iOperation); + } + else + { + // no need to release the lock + iOperation->HandleRemoteAccessResponse(0, KErrNone); + } + + } + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::TReleaseLockState::CompleteL +// ---------------------------------------------------------------------------- +// +CRsfwCloseStateMachine::TState* CRsfwCloseStateMachine::TReleaseLockState::CompleteL() + { + DEBUGSTRING(("CRsfwCloseStateMachine::TReleaseLockState::CompleteL")); + iOperation->Node()->RemoveLocked(); + + // don't show 'save as' note if transfer was cancelled explicitily by the user + if (iOperation->iFlags == ECloseLastFlushFailed && !iOperation->Node()->IsCancelled()) + { + // modified file, last flush failed so let user to save the file locally + return new CRsfwCloseStateMachine::TSaveLocallyState(iOperation); + } + else + { + return iOperation->CompleteRequestL(KErrNone); + } + + } + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::TReleaseLockState::ErrorL +// ---------------------------------------------------------------------------- +// +CRsfwCloseStateMachine::TState* +CRsfwCloseStateMachine::TReleaseLockState::ErrorL(TInt /* aCode */) + { + DEBUGSTRING(("CRsfwCloseStateMachine::TReleaseLockState::ErrorL")); + // Probably not really an error as according to the RFC locks + // can disappear anytime anyway, lets just run the logic in CompleteL + return CompleteL(); + } + + +// save as + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::TSaveLocallyState::TSaveLocallyState +// ---------------------------------------------------------------------------- +// +CRsfwCloseStateMachine:: +TSaveLocallyState::TSaveLocallyState(CRsfwCloseStateMachine* aParent) + : iOperation(aParent) + { + } + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::TSaveLocallyState::EnterL +// ---------------------------------------------------------------------------- +// +void CRsfwCloseStateMachine::TSaveLocallyState::EnterL() + { + DEBUGSTRING(("CRsfwCloseStateMachine::TSaveLocallyState::EnterL")); + TEntry fEntry; + CRsfwRfeServer::Env()->iFs.Entry((*(iOperation->Node()->CacheFileName())), fEntry); + iFileSizeString.Num(fEntry.iSize); + TPtrC cacheDriveLetter = iOperation->Node()->CacheFileName()->Left(1); + + iSaveToRequest.iMethod = TRsfwNotPluginRequest::ESaveToDlg; + iSaveToRequest.iDriveName = iOperation->Node()->iFileTable->Volume()->MountInfo() + ->iMountConfig.iName; + + iSaveToRequest.iFileName = *(iOperation->Node()->Name()); + iSaveToRequest.iCacheDrive = cacheDriveLetter; + iSaveToRequest.iFileSize = iFileSizeString; + + + iOperation->Volumes()->WaitNoteManager()->SetSaveToDialogRequestL(iSaveToRequest); + + iOperation->Volumes()->WaitNoteManager() + ->StartWaitNoteL(ERemoteSaveToLocal, iOperation); + } + + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::TSaveLocallyState::CompleteL +// ---------------------------------------------------------------------------- +// +CRsfwCloseStateMachine::TState* CRsfwCloseStateMachine::TSaveLocallyState::CompleteL() + { + DEBUGSTRING(("CRsfwCloseStateMachine::TSaveLocallyState::CompleteL")); + TInt err; + + // move the file from cache to the new location + HBufC* newName = HBufC::NewMaxLC(KMaxPath); + TPtr pathPtr = newName->Des(); + pathPtr = iSaveToRequest.iFileName; + CFileMan* fman = CFileMan::NewL(CRsfwRfeServer::Env()->iFs); + // we assume that this is local-to-local move, and can be synch. call + err = fman->Move((*(iOperation->Node()->CacheFileName())), + pathPtr, CFileMan::EOverWrite); + delete fman; + if (err == KErrNone) + { + iOperation->Volumes()->WaitNoteManager()->ShowFileSavedToDialogL(pathPtr); + } + else + { + iOperation->Volumes()->WaitNoteManager()->ShowFailedSaveNoteL(); + } + + CleanupStack::PopAndDestroy(newName); + + return iOperation->CompleteRequestL(KErrNone); + } + +// ---------------------------------------------------------------------------- +// CRsfwCloseStateMachine::TSaveLocallyState::ErrorL +// ---------------------------------------------------------------------------- +// +CRsfwCloseStateMachine::TState* +CRsfwCloseStateMachine::TSaveLocallyState::ErrorL(TInt aCode) + { + DEBUGSTRING(("CRsfwCloseStateMachine::TSaveLocallyState::ErrorL %d", aCode)); + return iOperation->CompleteRequestL(KErrNone); + } + + + +