diff -r 000000000000 -r 2f259fa3e83a commonuis/CommonUi/src/DocumentHandler.cpp --- /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 +#endif // ENABLE_DRM + +#include + +#include + +#include +#include + +#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(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 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 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& 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