commonuis/CommonUi/src/DocumentHandler.cpp
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commonuis/CommonUi/src/DocumentHandler.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,1740 @@
+/*
+* Copyright (c) 2002-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:  Implementation of CDocumentHandler class.
+*
+*/
+
+
+// INCLUDE FILES
+
+#include "DocumentHandler.h"        // Class Declaration
+#include "DocConstants.h"
+
+// All special handlers and the default handler
+#include "DocDefaultHandler.h"
+#include "DocImageHandler.h"
+#include "DocGameHandler.h"
+#include "DocAppInstHandler.h"
+//#include "DocMidletHandler.h"
+
+#ifdef ENABLE_DRM
+#include "DocDCFHandler.h"
+#include <Oma2Agent.h>
+#endif // ENABLE_DRM
+
+#include <AiwGenericParam.h>
+
+#include <featmgr.h>
+
+#include <centralrepository.h>
+#include <CommonUiInternalCRKeys.h>
+
+#define LEAVEONERROR( error ) if( error != KUserCancel && error != KErrNone )\
+                                   User::Leave( error )
+
+const TInt KDocMaxCenRepBufLen = 1024;
+const TInt KDocPDMaxMimeLen = 64;
+const TInt KDocPDMaxUids = 24;
+const TInt KDocPDMaxUidLen = 12;
+const TInt KDocMaxDigitsInHexString = 8; // 32 bits.
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// @since Series60 3.0
+//
+CDocumentHandler::CDocumentHandler()
+    {
+    }
+
+// Two-phased constructor.
+// @since Series60 3.0
+EXPORT_C CDocumentHandler* CDocumentHandler::NewL( )
+    {
+    CDocumentHandler* self = NewLC( );
+    CleanupStack::Pop();
+    return self;
+    }
+
+// Two-phased constructor.
+// @since Series60 3.0
+EXPORT_C CDocumentHandler* CDocumentHandler::NewLC( )
+    {
+    CDocumentHandler* self = new( ELeave ) CDocumentHandler ( );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+// EPOC default constructor can leave.
+void CDocumentHandler::ConstructL()
+    {
+    iApaLs = new ( ELeave ) RApaLsSession;
+    User::LeaveIfError(iApaLs->Connect());
+
+    FeatureManager::InitializeLibL();
+
+    iTempFileName.Zero();
+    }
+
+// Two-phased constructor.
+EXPORT_C CDocumentHandler* CDocumentHandler::NewL( CEikProcess* /*aProcess*/ )
+    {
+    CDocumentHandler* self = NewLC( );
+    CleanupStack::Pop();
+    return self;
+    }
+
+// Two-phased constructor.
+EXPORT_C CDocumentHandler* CDocumentHandler::NewLC( CEikProcess* /*aProcess*/ )
+    {
+    CDocumentHandler* self = new( ELeave ) CDocumentHandler (  );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+// Destructor
+EXPORT_C CDocumentHandler::~CDocumentHandler()
+    {
+    FeatureManager::UnInitializeLib();
+
+    if ( iApaLs )
+        {
+        iApaLs->Close();
+        delete iApaLs;
+        }
+
+    CloseSharableFS();
+
+    // If we have temp file, we use iHandler services to delete this file
+    if ( iTempFileName.Length() != 0 && iHandler )
+        {
+        iHandler->DeleteFile(iTempFileName);
+        }
+
+    delete iHandler;
+
+    if ( iInParams )
+        {
+        delete iInParams;
+        }
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler instance destructed succesfully!"));
+    #endif
+    }
+
+
+// ---------------------------------------------------------
+// RApaLsSession* CDocumentHandler::ApaLs()
+// Returns Application list server object
+// ---------------------------------------------------------
+RApaLsSession* CDocumentHandler::ApaLs()
+    {
+    return iApaLs;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::DocOperation()
+// Returns CDocumentHandler::iOperation.
+// ---------------------------------------------------------
+TDocOperation CDocumentHandler::DocOperation() const
+    {
+    return iOperation;
+    }
+
+// ---------------------------------------------------------
+// MApaEmbeddedDocObserver* CDocumentHandler::ExitObserver()
+// Returns ExitObserver
+// @since Series60 3.0
+// ---------------------------------------------------------
+MAknServerAppExitObserver* CDocumentHandler::ServerAppExitObserver() const
+    {
+    return iServerAppExitObserver;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::SaveL
+// Save content to the correct directory based on aDataType
+// with a generated filename and attributes.
+//
+// This functions calls other SaveL version.
+//
+// Returns: KErrNone:           Everything went ok
+//          KUserCancel:      The user cancelled the operation
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::SaveL(
+    const TDesC8& aContent,     // Content buffer
+    TDataType& aDataType,       // Mime type of the content
+    const TUint aAttr )         // Save with these attributes
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::SaveL(aContent, aDataType, aAttr) Called"));
+    TPtrC mimetype = aDataType.Des();
+    RDebug::Print( _L("DocumentHandler: Parameters are: aDataType: %S "), &mimetype);
+    #endif
+
+    TFileName nullFileName;
+
+    return SaveL(aContent, aDataType, nullFileName, aAttr);
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::SaveL
+// Save content to the correct directory based on aDataType
+// with aFileName and attributes.
+//
+// We first save wile with SaveTempFileL command.
+// After that we use MoveL command.
+//
+// Returns: KErrNone:           Everything went ok
+//          KUserCancel:      The user cancelled the operation
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::SaveL(
+    const TDesC8& aContent,     // Content buffer
+    TDataType& aDataType,       // Mime type of the content
+    const TDesC& aName,         // Save with this name
+    const TUint aAttr )         // Save with these attributes
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::SaveL(aContent, aDataType, aFileName, aAttr) Called"));
+    TPtrC mimetype = aDataType.Des();
+    RDebug::Print( _L("DocumentHandler: Parameters are: aDataType: %S -- aFileName: %S  "), &mimetype, &aName);
+    #endif
+
+    TUid uid = { 0 };
+    TInt error;
+
+    if (aDataType.Des8().FindF( KDummyMimeType ) != KErrNotFound)
+        {
+        return KErrNone;
+        }
+
+    TFileName tempFileName;
+
+    iOperation = EDocSaveTemp; // First save temp file
+
+    // Use Default Handler for saving whatever mimetype actually is
+    delete iHandler;            // delete the old handler
+    iHandler = NULL;
+    iHandler = CDocDefaultHandler::NewL( aDataType,
+                                             uid, this, EDocSaveOnly );
+
+    error = iHandler->SetDestName( aName );     // Save with this file name
+
+    // Close if existing sharable RFs and create new for sharing purposes.
+    if ( error == KErrNone )
+        {
+        CloseSharableFS();
+        User::LeaveIfError(iSharableFS.Connect());
+        iSharableFS.ShareProtected();
+        }
+
+    if ( error == KErrNone )
+        {
+        error = iHandler->SaveTempFileL( aContent, KEntryAttNormal, tempFileName);
+        }
+
+    iOperation = EDocMove; // Move temp file to correct folder
+
+    if ( error == KErrNone )
+        {
+        RecognizeAndCheckFileL( tempFileName, aDataType, uid );
+
+        TRAP( error, FindHandlerL( aDataType, uid ) ); // allow unsupported.
+        if ( error == KMimeNotSupported )
+            {
+            iHandler = CDocDefaultHandler::NewL( aDataType, uid, this, EDocSaveOnly );
+            error = KErrNone;
+            }
+        else
+            {
+            User::LeaveIfError( error );
+            }
+        }
+
+    if ( !iHandler->CanSave() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    if ( error == KErrNone )
+        {
+        error = iHandler->SetSrcFileName( tempFileName );
+        }
+
+    if ( error == KErrNone )
+        {
+        error = iHandler->SetDestName( aName );
+        }
+
+    // We use CopyOrMoveL-function, iOperation is checked there
+    if ( error == KErrNone )
+        {
+        error = iHandler->CopyOrMoveL( aAttr );
+        }
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::SaveL: finished with error=%d."), error);
+    #endif
+
+    LEAVEONERROR( error );
+
+// Because DCF files are not tried to be recognized we return empty
+// type here. Normally the return value has the type which was used
+// when handler was selected.
+#ifdef ENABLE_DRM
+#ifdef __DRM_OMA2
+    if ( aDataType.Des8().FindF( KOma1DcfContentType ) != KErrNotFound ||
+         aDataType.Des8().FindF( KOma2DcfContentType ) != KErrNotFound )
+#else // __DRM_OMA2
+    if ( aDataType.Des8().FindF( KOma1DcfContentType ) != KErrNotFound )
+#endif // __DRM_OMA2
+        {
+        TDataType emptyDataType;
+        aDataType = emptyDataType;
+        }
+#endif // ENABLE_DRM
+
+    return error;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::CopyL
+// Copy file to the correct directory based on it's mime type.
+//
+// Returns: KErrNone:           Everything went ok
+//          KUserCancel:      The user cancelled the operation
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::CopyL(
+    const TDesC& aFileNameOld,  // copy data from this file
+    const TDesC& aFileNameNew,  // using this filename
+    TDataType& aDataType,       // Mime type of data
+    const TUint aAttr )         // use these attributes
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::CopyL(aFileNameOld, aFileNameNew, aDataType, aAttr) Called"));
+    TPtrC mimetype = aDataType.Des();
+    RDebug::Print( _L("DocumentHandler: Parameters are: aDataType: %S -- aFileNameOld: %S -- aFileNameNew: %S"), &mimetype, &aFileNameOld, &aFileNameNew);
+    #endif
+
+    TInt error = KErrNone;
+    TUid uid = { 0 };
+
+    if (aDataType.Des8().FindF( KDummyMimeType ) != KErrNotFound)
+        {
+        return KErrNone;
+        }
+
+    iOperation = EDocCopy;
+
+    RecognizeAndCheckFileL( aFileNameOld, aDataType, uid );
+
+    TRAP( error, FindHandlerL( aDataType, uid ) ); // allow unsupported.
+    if ( error == KMimeNotSupported )
+        {
+        iHandler = CDocDefaultHandler::NewL( aDataType, uid, this, EDocSaveOnly );
+        error = KErrNone;
+        }
+    else
+        {
+        User::LeaveIfError( error );
+        }
+
+    if ( !iHandler->CanSave() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    error = iHandler->SetSrcFileName( aFileNameOld );
+    if ( error == KErrNone )
+        {
+        // If aFileNameNew is not set, use source file name
+        if (aFileNameNew.Length() != 0)
+            {
+            error = iHandler->SetDestName( aFileNameNew );
+            }
+        else
+            {
+            error = iHandler->SetDestName( aFileNameOld );
+            }
+        }
+
+    // We use CopyOrMoveL-function, iOperation is checked there
+    if ( error == KErrNone )
+        {
+        error = iHandler->CopyOrMoveL( aAttr );
+        }
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::CopyL: finished with error=%d."), error);
+    #endif
+
+    LEAVEONERROR( error );
+
+    return error;
+    }
+
+
+// ---------------------------------------------------------
+// CDocumentHandler::CopyL
+// Copy file to the correct directory based on it's mime type.
+//
+// Returns: KErrNone:           Everything went ok
+//          KUserCancel:      The user cancelled the operation
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::CopyL(
+    const RFile& aFileOld,      // copy data from this file
+    const TDesC& aFileNameNew,  // using this filename
+    TDataType& aDataType,       // Mime type of data
+    const TUint aAttr )         // use these attributes
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::CopyL(aFileOld, aFileNameNew, aDataType, aAttr) Called"));
+    TPtrC mimetype = aDataType.Des();
+    TFileName fileNameOld;
+    aFileOld.FullName(fileNameOld);
+    RDebug::Print( _L("DocumentHandler: Parameters are: aDataType: %S -- aFileOld (name): %S -- aFileNameNew: %S"), &mimetype, &fileNameOld, &aFileNameNew);
+    #endif
+
+    TInt error = KErrNone;
+    TUid uid = { 0 };
+
+    if (aDataType.Des8().FindF( KDummyMimeType ) != KErrNotFound)
+        {
+        return KErrNone;
+        }
+
+    iOperation = EDocCopy;
+
+    RecognizeAndCheckFileL( const_cast<RFile&>(aFileOld), aDataType, uid );
+
+    TRAP( error, FindHandlerL( aDataType, uid ) ); // allow unsupported.
+    if ( error == KMimeNotSupported )
+        {
+        iHandler = CDocDefaultHandler::NewL( aDataType, uid, this, EDocSaveOnly );
+        error = KErrNone;
+        }
+    else
+        {
+        User::LeaveIfError( error );
+        }
+
+    if ( !iHandler->CanSave() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+	
+	TFileName filenameold;
+    aFileOld.FullName( filenameold );
+    iHandler->SetSrcFileName( filenameold );
+
+    // If aFileNameNew is not set, use source file name
+    if (aFileNameNew.Length() != 0)
+        {
+        error = iHandler->SetDestName( aFileNameNew );
+        }
+    else
+        {
+        aFileOld.Name( filenameold );
+        error = iHandler->SetDestName( filenameold );
+        }
+
+    // Let's do actual copying using CopyHandleL method
+    if ( error == KErrNone )
+        {
+        error = iHandler->CopyHandleL( aFileOld, aAttr );
+        }
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::CopyL: finished with error=%d."), error);
+    #endif
+
+    LEAVEONERROR( error );
+
+    return error;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::MoveL
+// Move file to the correct directory based on it's mime type.
+//
+// Returns: KErrNone:           Everything went ok
+//          KUserCancel:      The user cancelled the operation
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::MoveL(
+    const TDesC& aFileNameOld,  // Move this file ...
+    const TDesC& aFileNameNew,  // ...to this filename
+    TDataType& aDataType,       // Mime type of data
+    const TUint aAttr )         // use these attributes to new file
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::MoveL(aFileNameOld, aFileNameNew, aDataType, aAttr) Called"));
+    TPtrC mimetype = aDataType.Des();
+    RDebug::Print( _L("DocumentHandler: Parameters are: aDataType: %S -- aFileNameOld: %S -- aFileNameNew: %S"), &mimetype, &aFileNameOld, &aFileNameNew);
+    #endif
+
+    TInt error = KErrNone;
+    TUid uid = { 0 };
+
+    if (aDataType.Des8().FindF( KDummyMimeType ) != KErrNotFound)
+        {
+        return KErrNone;
+        }
+
+    iOperation = EDocMove;
+
+    RecognizeAndCheckFileL( aFileNameOld, aDataType, uid );
+
+    TRAP( error, FindHandlerL( aDataType, uid ) ); // allow unsupported.
+    if ( error == KMimeNotSupported )
+        {
+        iHandler = CDocDefaultHandler::NewL( aDataType, uid, this, EDocSaveOnly );
+        error = KErrNone;
+        }
+    else
+        {
+        User::LeaveIfError( error );
+        }
+
+    if ( !iHandler->CanSave() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    error = iHandler->SetSrcFileName( aFileNameOld );
+    if ( error == KErrNone )
+        {
+        error = iHandler->SetDestName( aFileNameNew );
+        }
+
+    // We use CopyOrMoveL-function, iOperation is checked there
+    if ( error == KErrNone )
+        {
+        error = iHandler->CopyOrMoveL( aAttr );
+        }
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::MoveL: finished with error=%d."), error);
+    #endif
+
+    LEAVEONERROR( error );
+
+    return error;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::SilentMoveL
+// Move file to the correct directory based on it's mime type.
+// Not any user interaction.
+//
+// Returns: KErrNone:           Everything went ok
+//          KUserCancel:      The user cancelled the operation
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::SilentMoveL(
+    const TDesC& aFileNameOld,
+    const TDesC& aNameNew,
+    const TDesC& aRootPath,
+    TDataType& aDataType,
+    const TUint aAttr )
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::SilentMoveL(aFileNameOld, aFileNameNew, aDataType, aAttr) Called"));
+    TPtrC mimetype = aDataType.Des();
+    RDebug::Print( _L("DocumentHandler: Parameters are: aDataType: %S -- aFileNameOld: %S -- aFileNameNew: %S"), &mimetype, &aFileNameOld, &aNameNew);
+    #endif
+
+    TInt error = KErrNone;
+    TUid uid = { 0 };
+
+    if (aDataType.Des8().FindF( KDummyMimeType ) != KErrNotFound)
+        {
+        return KErrNone;
+        }
+
+    iOperation = EDocSilentMove;
+
+    RecognizeAndCheckFileL( aFileNameOld, aDataType, uid );
+
+    TRAP( error, FindHandlerL( aDataType, uid ) ); // allow unsupported.
+    if ( error == KMimeNotSupported )
+        {
+        iHandler = CDocDefaultHandler::NewL( aDataType, uid, this, EDocSaveOnly );
+        error = KErrNone; 
+        }
+    else
+        {
+        User::LeaveIfError( error );
+        }
+
+    if ( !iHandler->CanSave() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    error = iHandler->SetRootPath( aRootPath );
+
+    if ( error == KErrNone )
+        {
+        error = iHandler->SetSrcFileName( aFileNameOld );
+        }
+    if ( error == KErrNone )
+        {
+        error = iHandler->SetDestName( aNameNew );
+        }
+
+    // We use CopyOrMoveL-function, iOperation is checked there
+    if ( error == KErrNone )
+        {
+        error = iHandler->CopyOrMoveL( aAttr );
+        }
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::SilentMoveL: finished with error=%d."), error);
+    #endif
+
+    LEAVEONERROR( error );
+
+    return error;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::OpenFileL
+//
+// Open a file with a given data type standalone.
+// Calls other version of OpenFileL.
+//
+// Returns: KErrNone:           Everything went ok
+//          KUserCancel:      The user cancelled the operation
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::OpenFileL(
+    const TDesC& aFileName,     // Read data from here
+    TDataType& aDataType )      // mime type of the data
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::OpenFileL(aFileName, aDataType) Called"));
+    TPtrC mimetype = aDataType.Des();
+    RDebug::Print( _L("DocumentHandler: Parameters are: aDataType: %S -- aFileName: %S  "), &mimetype, &aFileName);
+    #endif
+
+    RFile fileHandle;
+    OpenTempFileL(aFileName, fileHandle);
+    TInt error = OpenFileL(fileHandle, aDataType);
+    fileHandle.Close();
+    return error;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::OpenFileL
+//
+// Open a file with a given data type standalone. First
+// check that the content is supported and get the handler
+// application's UID. Based on that UID find the correct
+// handler for the content. File data is not copied over.
+//
+// Returns: KErrNone:           Everything went ok
+//          KUserCancel:      The user cancelled the operation
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::OpenFileL(
+          RFile& aSharableFile,
+          TDataType& aDataType)
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::OpenFileL(aSharableFile, aDataType) Called"));
+    TPtrC mimetype = aDataType.Des();
+    TFileName filename;
+    aSharableFile.FullName(filename);
+    RDebug::Print( _L("DocumentHandler: Parameters are: aDataType: %S -- fullname of filehandle: %S  "), &mimetype, &filename);
+    #endif
+
+    TUid uid = { 0 };
+    TInt error;
+
+    if (aDataType.Des8().FindF( KDummyMimeType ) != KErrNotFound)
+        {
+        return KErrNone;
+        }
+
+    iOperation = EDocOpenFile;
+
+    RecognizeAndCheckFileL( aSharableFile, aDataType, uid );
+
+    FindHandlerL( aDataType, uid );
+
+    if ( !iHandler->CanOpen() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    error = iHandler->OpenFileL(aSharableFile);            // Do open file
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::OpenFileL: finished with error=%d."), error);
+    #endif
+
+    LEAVEONERROR( error );
+
+    return error;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::OpenFileEmbeddedL
+// Open a file with a given data type embedded.
+// Calls other version of OpenFileEmbeddedL.
+//
+// Returns: KErrNone:           Everything went ok
+//          KUserCancel:      The user cancelled the operation
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::OpenFileEmbeddedL(
+    const TDesC& aFileName,     // Read data from here
+    TDataType& aDataType )      // mime type of the data
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::OpenFileEmbeddedL(aFileName, aDataType) Called"));
+    TPtrC mimetype = aDataType.Des();
+    RDebug::Print( _L("DocumentHandler: Parameters are: aDataType: %S -- aFileName: %S  "), &mimetype, &aFileName);
+    #endif
+
+    RFile fileHandle;
+    OpenTempFileL(aFileName, fileHandle);
+    TInt error = OpenFileEmbeddedL(fileHandle, aDataType, InParamListL());
+    fileHandle.Close();
+    return error;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::OpenFileEmbeddedL
+// Calls other version of OpenFileEmbeddedL.
+//
+// Returns: KErrNone:           Everything went ok
+//          KUserCancel:      The user cancelled the operation
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::OpenFileEmbeddedL(
+          RFile& aSharableFile,
+          TDataType& aDataType)
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::OpenFileEmbeddedL(aSharableFile, aDataType) Called"));
+    #endif
+
+    return OpenFileEmbeddedL(aSharableFile, aDataType, InParamListL());
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::OpenFileEmbeddedL
+// Open a file with a given data type embedded. First
+// check that the content is supported and get the handler
+// application's UID. Based on that UID find the correct
+// handler for the content. File data is not copied over.
+//
+// Returns: KErrNone:           Everything went ok
+//          KUserCancel:      The user cancelled the operation
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::OpenFileEmbeddedL(
+          RFile& aSharableFile,
+          TDataType& aDataType,
+          const CAiwGenericParamList& aParamList)
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::OpenFileEmbeddedL(aSharableFile, aDataType, aParamList) Called"));
+    TPtrC mimetype = aDataType.Des();
+    TFileName filename;
+    aSharableFile.FullName(filename);
+    RDebug::Print( _L("DocumentHandler: Parameters are: aDataType: %S -- fullname of filehandle: %S  "), &mimetype, &filename);
+    #endif
+
+    TUid uid = { 0 };
+    TInt error;
+
+    if (aDataType.Des8().FindF( KDummyMimeType ) != KErrNotFound)
+        {
+        return KErrNone;
+        }
+
+    iOperation = EDocOpenFileEmb;
+
+    error = RecognizeAndCheckFileL( aSharableFile, aDataType, uid );
+
+    if ( error != KErrNone )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    FindHandlerL( aDataType, uid );
+
+    if ( !iHandler->CanOpen() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    iHandler->AddToParamListL( aParamList );
+
+
+     // Default to true.
+    TBool supportsEmbeddability = ETrue;
+
+    // Check from AppArc whether the handler app. supports embeddability.
+    TUid handlerUid;
+    iHandler->HandlerAppUid( handlerUid );
+
+    TApaAppCapability caps;
+    TPckg<TApaAppCapability> pack( caps );
+    TInt err = iApaLs->GetAppCapability( pack, handlerUid );
+
+    if ( err == KErrNone && caps.iEmbeddability == TApaAppCapability::ENotEmbeddable )
+        {
+        supportsEmbeddability = EFalse;
+        }
+
+    if ( supportsEmbeddability )
+        {
+        error = iHandler->OpenFileEmbeddedL(aSharableFile); // Open embedded
+        }
+    else
+        {
+        error = iHandler->OpenFileL(aSharableFile); // Open stand-alone
+        }
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::OpenFileEmbeddedL: finished with error=%d."), error);
+    #endif
+
+    LEAVEONERROR( error );
+
+    return error;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::CanHandleL
+// Check if there is a handler application for aDataType.
+//
+// Returns: ETrue:  The system is capable of handling aDataType
+//          EFalse: The system is not capable of handling aDataType
+// ---------------------------------------------------------
+//
+EXPORT_C TBool CDocumentHandler::CanHandleL( const TDataType& aDataType )
+    {
+    TUid appUid;
+    TInt error;
+    TBool response = EFalse;
+
+    #ifdef _DEBUG
+    TPtrC mimetype = aDataType.Des();
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::CanHandleL called with aDataType: %S "), &mimetype );
+    #endif
+
+    error = iApaLs->AppForDataType( aDataType, appUid );
+    if ( error == KErrNone )
+        {
+        TRAP( error, FindHandlerL( aDataType, appUid ) ); // allow unsupported.
+        if ( error == KMimeNotSupported )
+            {
+            iHandler = CDocDefaultHandler::NewL( aDataType, appUid, this, EDocSaveOnly );
+            error = KErrNone;
+            }
+        else
+            {
+            User::LeaveIfError( error );
+            }
+
+        if ( iHandler )
+            {
+            response = ( iHandler->CanOpen() ||
+                         iHandler->CanSave() );
+            }
+        }
+    return response;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::CanOpenL
+// Check if there is a handler application for aDataType and
+// open is possible.
+//
+// Returns: ETrue:  The system is capable of handling aDataType
+//          EFalse: The system is not capable of handling aDataType
+// ---------------------------------------------------------
+//
+EXPORT_C TBool CDocumentHandler::CanOpenL( const TDataType& aDataType )
+    {
+    TUid appUid;
+    TInt error;
+    TBool response = EFalse;
+
+    #ifdef _DEBUG
+    TPtrC mimetype = aDataType.Des();
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::CanOpenL called with aDataType: %S "), &mimetype );
+    #endif
+
+    error = iApaLs->AppForDataType( aDataType, appUid );
+    if ( error == KErrNone )
+        {
+        FindHandlerL( aDataType, appUid ); // do not allow unsupported
+        if ( iHandler )
+            {
+            response = iHandler->CanOpen();
+            }
+        }
+    return response;
+    }
+
+
+// ---------------------------------------------------------
+// CDocumentHandler::CanSaveL
+// Check if there is a handler application for aDataType and
+// saving is possible.
+//
+// Returns: ETrue:  The system is capable of handling aDataType
+//          EFalse: The system is not capable of handling aDataType
+// ---------------------------------------------------------
+//
+EXPORT_C TBool CDocumentHandler::CanSaveL( const TDataType& aDataType )
+    {
+    TUid appUid;
+    TInt error;
+    TBool response = EFalse;
+
+    #ifdef _DEBUG
+    TPtrC mimetype = aDataType.Des();
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::CanSaveL called with aDataType: %S "), &mimetype );
+    #endif
+
+    error = iApaLs->AppForDataType( aDataType, appUid );
+    if ( error == KErrNone )
+        {
+        TRAP( error, FindHandlerL( aDataType, appUid ) ); // allow unsupported.
+        if ( error == KMimeNotSupported )
+            {
+            iHandler = CDocDefaultHandler::NewL( aDataType, appUid, this, EDocSaveOnly );
+            error = KErrNone;
+            }
+        else
+            {
+            User::LeaveIfError( error );
+            }
+
+        if ( iHandler )
+            {
+            response = iHandler->CanSave();
+            }
+        }
+    return response;
+    }
+
+
+// ---------------------------------------------------------
+// CDocumentHandler::CheckFileNameExtension
+// Add correct file extension to aFileName with aDatatype.
+// Calls CDocDefaultHandler::CheckFileNameExtensionL()
+// ---------------------------------------------------------
+//
+EXPORT_C void CDocumentHandler::CheckFileNameExtension( TDes& aFileName, const TDataType& aDatatype )
+    {
+    #ifdef _DEBUG
+    TPtrC mimetype = aDatatype.Des();
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::CheckFileNameExtension called with: aFileName: %S -- aDataType: %S "), &aFileName, &mimetype );
+    #endif
+
+    TUid appUid;
+    TInt error;
+
+    // Try to find uid
+    error = iApaLs->AppForDataType( aDatatype, appUid );
+    if ( error == KErrNone )
+        {
+        // Try to find handler.
+        TRAPD(err, FindHandlerL(aDatatype, appUid));
+
+        if (err == KErrNone && iHandler)
+            {
+            // Check finally extension
+            TRAP_IGNORE( iHandler->CheckFileNameExtensionL( aFileName, aDatatype ) );
+            }
+        }
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::CheckFileNameExtension finished : aFileName: %S"), &aFileName );
+    #endif
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::SetExitObserver(..)
+// Delegate exit signals to aObserver too.
+// ---------------------------------------------------------
+//
+EXPORT_C void CDocumentHandler::SetExitObserver(
+    MAknServerAppExitObserver* aObserver )
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::SetExitObserver called.") );
+    #endif
+
+    __ASSERT_DEBUG (
+        aObserver,
+        User::Panic ( _L ( "DocumentHandler" ), KErrUnknown ) );
+    iServerAppExitObserver = aObserver;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::FindHandlerByUidL(..)
+// Try to find a handler for aUid.
+// ---------------------------------------------------------
+//
+void CDocumentHandler::FindHandlerByUidL( const TUid& aUid, const TDataType& aDataType )
+    {
+    switch ( aUid.iUid )
+        {
+        case KTextHandler:        // Notepad viewer
+            iHandler = CDocDefaultHandler::NewL(
+                           aDataType, 
+                           aUid, this, EDocOpenAndSave );
+            break;
+        case KCertSaveAppHandler: // Cert save app
+            iHandler = CDocDefaultHandler::NewL(
+                           aDataType,
+                           aUid, this, EDocOpenOnly );
+            break;
+        case KLandmarkHandler: // Landmark UI app
+            iHandler = CDocDefaultHandler::NewL(
+                           aDataType,
+                           aUid, this, EDocOpenOnly );
+            break;
+        case KImageViewerHandler: // Image Viewer
+            iHandler = CDocImageHandler::NewL(
+                           aDataType, aUid, this);
+            break;
+        case KAppInstHandler:   // Application Installer
+            iHandler = CDocAppInstHandler::NewL(
+                           aDataType,
+                           aUid, this, EDocOpenAndSave );
+            break;
+        case KWmlcHandler: // Browser
+            iHandler = CDocDefaultHandler::NewL(
+                           aDataType,
+                           aUid, this, EDocOpenAndSave );
+            break;
+        default:
+/*          TODO: Do we need midlet handler anymore?
+            if (FeatureManager::FeatureSupported( KFeatureIdCdmaExtendedAms ) )
+                {
+                // Check if given UID belongs to a Java Midlet
+                if ( CDocMidletHandler::IsMidlet( aUid ) )
+                    {
+                    iHandler = CDocMidletHandler::NewL(
+                        aDataType,
+                        aUid, this);
+                    }
+                }
+*/
+            break; // We will use default handler
+        }
+    }
+
+// ---------------------------------------------------------
+// void CDocumentHandler::FindHandlerByMimeTypeL(..)
+// Try to find a handler for aDataType
+// ---------------------------------------------------------
+//
+void CDocumentHandler::FindHandlerByMimeTypeL( const TUid& aUid, const TDataType& aDataType )
+    {
+    // All games are handler by the game handler
+    if ( aDataType.Des8().FindF( KGameMimeType ) != KErrNotFound )
+        {
+        iHandler = CDocGameHandler::NewL(
+                           aDataType, aUid, this, EDocSaveOnly );
+        return;
+        }
+
+    if (( aDataType.Des8().FindF( KDocMimeCard ) != KErrNotFound) ||
+        ( aDataType.Des8().FindF( KDocMimeCalendar) != KErrNotFound) ||
+        ( aDataType.Des8().FindF( KDocMimeCalendar2) != KErrNotFound))
+        {
+        //
+        // vCal and vCard types are handled as 'read only' types
+        // (must be saved from application, not through doc handler).
+        //
+        iHandler = CDocDefaultHandler::NewL(
+                           aDataType,
+                           aUid, this, EDocOpenOnly );
+        return;
+        }
+    #ifdef ENABLE_DRM
+    #ifdef __DRM_OMA2
+    if ( aDataType.Des8().FindF( KOma1DcfContentType ) != KErrNotFound ||
+         aDataType.Des8().FindF( KOma2DcfContentType ) != KErrNotFound )
+    #else // __DRM_OMA2
+    if ( aDataType.Des8().FindF( KOma1DcfContentType ) != KErrNotFound )
+    #endif // __DRM_OMA2
+        {
+        iHandler = CDocDCFHandler::NewL( aDataType, iOperation, aUid, this );
+        return;
+        }
+    #endif // ENABLE_DRM
+
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::FindHandlerL
+// Based on app uid and mime type decide which handler
+// implementation to use.
+//
+//
+// Returns: KErrNone:           The handler was constructed ok
+// ---------------------------------------------------------
+//
+TInt CDocumentHandler::FindHandlerL(
+    const TDataType& aDataType,
+    const TUid& aUid)
+    {
+    delete iHandler;            // delete the old handler
+    iHandler = NULL;
+
+    // First check by the application uid
+    FindHandlerByUidL( aUid, aDataType );
+
+    // Then check by the mime type
+    if ( !iHandler )
+        {
+        FindHandlerByMimeTypeL( aUid, aDataType );
+        }
+
+    // Default handler if everything else has failed
+    if ( !iHandler )
+        {
+        TApaAppInfo info;
+        if ( iApaLs->GetAppInfo( info, aUid ) == KErrNone ) // Check the uid is real.
+            {
+            iHandler = CDocDefaultHandler::NewL( aDataType,
+                                             aUid, this, EDocOpenAndSave );
+            }
+        else
+            {
+            User::Leave( KMimeNotSupported );
+            }
+        }
+        
+    return KErrNone;
+    }
+
+
+// ---------------------------------------------------------
+// Get the whole path including filename where the content was saved.
+// If the content was not saved in a file, return the id
+// representing the object.
+// returns: KErrNone:           Ok
+//          KNotInitialized     Handler is no initialized
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::GetPath( TDes& aPath )
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::GetPath called.") );
+    #endif
+
+    __ASSERT_DEBUG (
+        iHandler,
+        User::Panic ( _L( "DocumentHandler" ), KNotInitialized ) );
+
+    if ( !iHandler )
+        {
+        aPath.Zero();
+        return KNotInitialized;
+        }
+    iHandler->GetPath( aPath );
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::GetPath returns aPath: %S "), &aPath);
+    #endif
+
+    return iHandler->Status();
+    }
+
+// ---------------------------------------------------------
+// Get the Uid of handler application.
+// returns: KErrNone:           Ok
+//          KNotInitialized     Handler is no initialized
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CDocumentHandler::HandlerAppUid( TUid& aUid )
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::HandlerAppUid called.") );
+    #endif
+
+    __ASSERT_DEBUG (
+        iHandler,
+        User::Panic ( _L( "DocumentHandler" ), KNotInitialized ) );
+
+    if ( !iHandler )
+        {
+        return KNotInitialized;
+        }
+    iHandler->HandlerAppUid( aUid );
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::HandlerAppUid returns uid: %x "), aUid.iUid);
+    #endif
+
+    return iHandler->Status();
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::ListSupportedMimeTypesL
+// Lists all supported MIME-types using RDebug::Print
+// ---------------------------------------------------------
+//
+void CDocumentHandler::ListSupportedMimeTypesL()
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L( "DocumentHandler: All supported mime types:" ) );
+    RDebug::Print( _L( "**********************" ) );
+    CDataTypeArray *dataTypes = new( ELeave ) CDataTypeArray( 20 );
+    CleanupStack::PushL( dataTypes );
+    iApaLs->GetSupportedDataTypesL( *dataTypes );
+    for ( TInt i = dataTypes->Count() - 1; i; i-- )
+        {
+        TBuf < KMaxDataTypeLength > buf;
+        buf.Copy( dataTypes->At( i ).Des8() );
+        RDebug::Print( buf );
+        TUid uid;
+        iApaLs->AppForDataType( dataTypes->At( i ), uid );
+        TApaAppInfo appInfo;
+        iApaLs->GetAppInfo( appInfo, uid );
+        RDebug::Print( _L(" -handler app uid - %x, caption - %S"), uid.iUid, &appInfo.iCaption);
+
+        }
+    RDebug::Print( _L( "**********************" ) );
+    CleanupStack::PopAndDestroy();
+    #endif
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::RecognizeAndCheckFile
+// Recognizes the file and makes other checks.
+// This filehandle version is called from OpenFile*L methods
+// ---------------------------------------------------------
+//
+TInt CDocumentHandler::RecognizeAndCheckFileL(
+    RFile& aFileHandle,
+    TDataType& aDataType,
+    TUid& aUid )
+    {
+    #ifdef ENABLE_DRM
+    if ( aDataType.Des8().FindF( KOma1DcfContentType ) != KErrNotFound ||
+         aDataType.Des8().FindF( KOma2DcfContentType ) != KErrNotFound )
+        {
+        return KErrNone;
+        }
+    #endif
+
+    #ifdef _DEBUG
+    ListSupportedMimeTypesL(); // Let's list all supported mime-types
+    #endif
+
+    TDataType recognizedData;
+    TDataType emptyType;
+
+    // TODO: Do we need some security checks for file?
+    TInt error = KErrNone;
+
+    // Caller gave data type, try it first.
+    if ( aDataType != emptyType )
+        {
+        error = iApaLs->AppForDataType( aDataType, aUid );
+        if ( error == KErrNone )
+            {
+            #ifdef _DEBUG
+            RDebug::Print( _L("DocumentHandler: CDocumentHandler::RecognizeAndCheckFileL: Use data type from caller:") );
+            RDebug::Print( aDataType.Des() );
+            #endif
+            return KErrNone;
+            }
+        }
+
+    // Let's ask from RApaLsSession what datatype file is
+    // This will give us both uid of an application and the data type.
+    error = iApaLs->AppForDocument( aFileHandle, aUid, recognizedData );
+    if ( error == KErrNone )
+        {
+#ifdef _DEBUG
+        RDebug::Print( _L( "DocumentHandler: CDocumentHandler::RecognizeAndCheckFileL: Recognized mime type:" ) );
+        RDebug::Print( recognizedData.Des() );
+#endif
+        if ( recognizedData != emptyType )
+            {
+            aDataType = recognizedData;
+            return KErrNone;
+            }
+        }
+
+    return KErrNotFound;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::RecognizeAndCheckFile
+// Recognizes the file and makes other checks.
+// This filename version is called from Copy/Move methods
+// ---------------------------------------------------------
+//
+TInt CDocumentHandler::RecognizeAndCheckFileL(
+    const TDesC& aFileName,
+    TDataType& aDataType,
+    TUid& aUid )
+    {
+    #ifdef ENABLE_DRM
+    if ( aDataType.Des8().FindF( KOma1DcfContentType ) != KErrNotFound ||
+         aDataType.Des8().FindF( KOma2DcfContentType ) != KErrNotFound )
+        {
+        return KErrNone;
+        }
+    #endif
+
+    TDataType recognizedData;
+    TDataType emptyType;
+
+    #ifdef _DEBUG
+    ListSupportedMimeTypesL(); // Let's list all supported mime-types
+    #endif
+
+    // If the file is an executable, we are not allowed to continue
+    // for security reasons.
+    TBool executable;
+    User::LeaveIfError( iApaLs->IsProgram( aFileName, executable ) );
+    if ( executable )               // Warn the caller about the content.
+        {
+        User::Leave( KExecNotAllowed );
+        }
+
+    TInt error = KErrNone;
+
+    // Caller gave data type, try it first.
+    if ( aDataType != emptyType )
+        {
+        error = iApaLs->AppForDataType( aDataType, aUid );
+        if ( error == KErrNone )
+            {
+            #ifdef _DEBUG
+            RDebug::Print( _L("DocumentHandler: CDocumentHandler::RecognizeAndCheckFileL: Use data type from caller:") );
+            RDebug::Print( aDataType.Des() );
+            #endif
+            // Success, we're done.
+            return KErrNone;
+            }
+        }
+
+    // Let's ask from RApaLsSession what datatype file is
+    // This will give us both uid of an application and the data type.
+    error = iApaLs->AppForDocument( aFileName, aUid, recognizedData );
+    if ( error == KErrNone )
+        {
+        #ifdef _DEBUG
+        RDebug::Print( _L( "DocumentHandler: CDocumentHandler::RecognizeAndCheckFileL: Recognized mime type:" ) );
+        RDebug::Print( recognizedData.Des() );
+        #endif
+        if ( recognizedData != emptyType )
+            {
+            aDataType = recognizedData;
+            return KErrNone;
+            }
+        }
+
+    return KErrNotFound;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::OpenTempFileL()
+// Opens a new sharable filehandle from existing file.
+// ---------------------------------------------------------
+//
+EXPORT_C void CDocumentHandler::OpenTempFileL(
+          const TDesC& aFileName,
+          RFile &aSharableFile)
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::OpenTempFileL() Called"));
+    RDebug::Print( _L("DocumentHandler: Parameters are: aFileName: %S  "), &aFileName);
+    #endif
+
+    TInt error = KErrNone;
+
+    // Cannot do anything if filename is not valid.
+    if (aFileName.Length() == 0)
+        {
+        error=KNotInitialized;
+        }
+
+    // Close if existing sharable RFs and create new for sharing purposes.
+    if ( error == KErrNone )
+        {
+        CloseSharableFS();
+        User::LeaveIfError(iSharableFS.Connect());
+        User::LeaveIfError(iSharableFS.ShareProtected());
+        TInt err = aSharableFile.Open(iSharableFS,aFileName,EFileShareReadersOnly);
+        if (err == KErrInUse)
+            {
+            User::LeaveIfError(aSharableFile.Open(iSharableFS,aFileName,EFileShareReadersOrWriters));
+            }
+        else if ( err != KErrNone )
+            {
+            error = err; // Otherwise possible KErrNotReady caused by hotswap leads to crash later
+            }
+        }
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::OpenTempFileL: finished with error=%d."), error);
+    #endif
+
+    LEAVEONERROR( error );
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::SaveTempFileL()
+// Saves content (aContent) to file and opens that sharable file
+// ---------------------------------------------------------
+//
+EXPORT_C void CDocumentHandler::SaveTempFileL(
+          const TDesC8& aContent,
+          TDataType& aDataType,
+          const TDesC& aFileName,
+          RFile &aSharableFile)
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::SaveTempFileL() Called"));
+    TPtrC mimetype = aDataType.Des();
+    RDebug::Print( _L("DocumentHandler: Parameters are: aDataType: %S -- aFileName: %S  "), &mimetype, &aFileName);
+    #endif
+
+    TUid uid = { 0 };
+    TInt error;
+    TFileName createdFileName;
+
+    iOperation = EDocSaveTemp;
+
+    // Use Default Handler for saving whatever mimetype actually is
+    delete iHandler;            // delete the old handler
+    iHandler = NULL;
+    iHandler = CDocDefaultHandler::NewL( aDataType,
+                                             uid, this, EDocSaveOnly );
+
+    error = iHandler->SetDestName( aFileName );     // Save with this file name
+
+    // Close if existing sharable RFs and create new for sharing purposes.
+    if ( error == KErrNone )
+        {
+        CloseSharableFS();
+        User::LeaveIfError(iSharableFS.Connect());
+        iSharableFS.ShareProtected();
+        }
+
+    if ( error == KErrNone )
+        {
+        error = iHandler->SaveTempFileL( aContent, KEntryAttNormal, createdFileName ); // Do save the content
+        }
+
+    if ( error == KErrNone )
+        {
+        OpenTempFileL(createdFileName, aSharableFile);
+        }
+
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::SaveTempFileL: finished with error=%d."), error);
+    #endif
+
+    LEAVEONERROR( error );
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::InParamListL()
+// Returns empty instance of CAiwGenericParamList
+// ---------------------------------------------------------
+//
+EXPORT_C CAiwGenericParamList& CDocumentHandler::InParamListL()
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::InParamListL() Called"));
+    #endif
+
+    if (!iInParams)
+        {
+        iInParams = CAiwGenericParamList::NewL();
+        }
+    iInParams->Reset();
+    return *iInParams;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::OutParamList()
+// Returns list of possible output parameters
+// ---------------------------------------------------------
+//
+EXPORT_C const CAiwGenericParamList* CDocumentHandler::OutParamList()
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::OutParamListL() Called"));
+    #endif
+
+    const CAiwGenericParamList* result = NULL;
+
+    if (!iHandler)
+        {
+        return NULL;
+        }
+
+    TRAPD(err, result = iHandler->OutputParamsL());
+    if (err != KErrNone)
+        {
+        return NULL;
+        }
+
+    return result;
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::CloseSharableFS
+// Close iSharableFs
+// ---------------------------------------------------------
+//
+void CDocumentHandler::CloseSharableFS()
+    {
+    if (iSharableFS.Handle() != NULL)
+        {
+        iSharableFS.Close();
+        }
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::SetTempFile
+// Set temp file, which will be deleted in destructor.
+// ---------------------------------------------------------
+//
+void CDocumentHandler::SetTempFile(const TDesC& aTempFile)
+    {
+    #ifdef _DEBUG
+    RDebug::Print( _L("DocumentHandler: CDocumentHandler::SetTempFile called with %S  "), &aTempFile);
+    #endif
+
+    // If there allready is stored tempfile, delete it first
+    if ( iTempFileName.Length() > 0 && iHandler )
+        {
+        iHandler->DeleteFile(iTempFileName);
+        }
+
+    // Set new tempfile to member variable
+    if ( aTempFile.Length() > 0 )
+        {
+        iTempFileName = aTempFile;
+        }
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::CanHandleProgressivelyL()
+// Returns ETrue if progressive downloading is supported by
+// some application for the requested data type. The Uid of
+// the application for the given data type is also returned.
+//
+// ---------------------------------------------------------
+//
+EXPORT_C TBool CDocumentHandler::CanHandleProgressivelyL(
+    const TDataType& aDataType,
+    TUid& aUid )
+    {
+    aUid.iUid = 0; // By default
+
+    HBufC* buffer16 = HBufC::NewLC( KDocMaxCenRepBufLen );
+
+    // Get Uid list.
+    //
+    TInt err = KErrNone;
+    RArray<TInt32> uidList;
+    TRAP( err, GetProgressiveDownloadAppUidsL( uidList ) )
+    CleanupClosePushL( uidList );
+    User::LeaveIfError( err ); // KErrNotFound.
+
+    // Check mimetypes.
+    //
+    CRepository* variation = CRepository::NewL( KCRUidCommonUi );
+    CleanupStack::PushL( variation );
+
+    TPtr allMimePtr( buffer16->Des() );
+    allMimePtr.Zero();
+
+    HBufC8* oneMime = HBufC8::NewLC( KDocPDMaxMimeLen );
+    TPtr8 oneMimePtr( oneMime->Des() );
+    TUint uidCount = uidList.Count();
+
+    for ( TInt i = 0; i < Min( uidCount, KDocPDMaxUids ); i++ )
+        {
+        err = variation->Get( KCuiMimeTypeSet1 + i, allMimePtr );
+        TInt start = 0; // leftmost pos.
+        TInt len = 0;
+        do
+            {
+            len = allMimePtr.Mid( start ).Locate( ';' );
+            if ( len == KErrNotFound )
+                {
+                len = allMimePtr.Mid( start ).Length();
+                }
+            if ( len > KDocPDMaxMimeLen ) // resize buffer length
+                {
+                CleanupStack::PopAndDestroy( oneMime );
+                oneMime = HBufC8::NewLC( len );
+                oneMimePtr.Set( oneMime->Des() );
+                }
+            oneMimePtr.Copy( allMimePtr.Mid( start, len ) );
+            oneMimePtr.Trim();
+
+            if ( !aDataType.Des8().CompareF( oneMimePtr ) ||
+                aDataType.Des8().MatchF( oneMimePtr ) != KErrNotFound )
+                {
+                aUid.iUid = uidList[ i ];
+                CleanupStack::PopAndDestroy( 4 ); // buffer16, uidList, variation
+                                                  // oneMime
+                return ETrue;
+                }
+
+            oneMimePtr.Zero();
+            if ( len > KDocPDMaxMimeLen ) // return normal length
+                {
+                CleanupStack::PopAndDestroy( oneMime );
+                oneMime = HBufC8::NewLC( KDocPDMaxMimeLen );
+                oneMimePtr = oneMime->Des();
+                }
+            start += len + 1;
+            }
+        while ( start < allMimePtr.Length() );
+        }
+
+    CleanupStack::PopAndDestroy( 4 ); // buffer16, uidList, variation, oneMime
+
+    return EFalse; // not found.
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::GetProgressiveDownloadAppUidsL
+// Returns
+//
+// ---------------------------------------------------------
+//
+EXPORT_C void CDocumentHandler::GetProgressiveDownloadAppUidsL(
+    RArray<TInt32>& aUidList )
+    {
+    // 16-bit buffer for CenRep.
+    HBufC* buffer16 = HBufC::NewLC( KDocMaxCenRepBufLen );
+
+    // Read data to the buffer.
+    TInt err = KErrNone;
+    CRepository* variation = CRepository::NewL( KCRUidCommonUi );
+    CleanupStack::PushL( variation );
+    TPtr allUidPtr( buffer16->Des() );
+
+    err = variation->Get( KCuiProgDownloadUids, allUidPtr );
+    if( err != KErrNone )
+        {
+        User::LeaveIfError( KErrNotFound ); // Error: CenRep access failed.
+        }
+    CleanupStack::PopAndDestroy( 1 ); // variation
+
+    HBufC* oneUid = HBufC::NewLC( KDocPDMaxUidLen );
+    TPtr oneUidPtr( oneUid->Des() );
+
+    TInt start = 0;
+    TInt len = 0;
+    do
+        {
+        len = allUidPtr.Mid( start ).Locate( ';' );
+        if ( len == KErrNotFound )
+            {
+            len = allUidPtr.Mid( start ).Length();
+            }
+        if ( len > KDocPDMaxUidLen ) // resize buffer length
+            {
+            CleanupStack::PopAndDestroy( oneUid );
+            oneUid = HBufC::NewLC( len );
+            oneUidPtr.Set( oneUid->Des() );
+            }
+        oneUidPtr.Copy( allUidPtr.Mid( start, len ) );
+        oneUidPtr.Trim();
+
+        TInt32 uid = 0;
+        if ( ConvertHexStringToInt32( oneUidPtr, uid ) != KErrNone )
+            {
+            User::LeaveIfError( KErrNotFound ); // Error: conversion failed.
+            }
+        aUidList.AppendL( uid );
+
+        oneUidPtr.Zero();
+        if ( len > KDocPDMaxUidLen ) // return normal length
+            {
+            CleanupStack::PopAndDestroy( oneUid );
+            oneUid = HBufC::NewLC( KDocPDMaxUidLen );
+            oneUidPtr = oneUid->Des();
+            }
+        start += len + 1;
+        }
+    while ( start < allUidPtr.Length() );
+
+    CleanupStack::PopAndDestroy( 2 ); // buffer16, oneUid
+    }
+
+// ---------------------------------------------------------
+// CDocumentHandler::ConvertHexStringToInt32
+// Returns TInt32 for a valid hex string, otherwise KErrArgument.
+//
+// ---------------------------------------------------------
+//
+TInt CDocumentHandler::ConvertHexStringToInt32(
+    const TDesC& aHexString,
+    TInt32& aInt32 )
+    {
+    aInt32 = 0;
+
+    TInt pos = aHexString.LocateF( 'x' );
+    if ( pos == KErrNotFound )
+        {
+        pos = 0;
+        }
+    else
+        {
+        pos++;
+        }
+
+    if( ( aHexString.Length() - pos ) > KDocMaxDigitsInHexString )
+        {
+        return KErrArgument; // Error: value too big.
+        }
+    TPtrC aHexStringPtr( aHexString.Mid( pos ) );
+
+    TInt64 value64;
+    if ( TLex( aHexStringPtr ).Val( value64, EHex ) != KErrNone )
+        {
+        return KErrArgument; // Error: conversion failed.
+        }
+    aInt32 = value64;
+
+    return KErrNone;
+    }
+
+// End of File