photosgallery/collectionframework/thumbnailcreator/src/glxtnbackgroundgenerationtask.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:45:44 +0200
changeset 0 4e91876724a2
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2008-2009 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:    Thumbnail background generation task implementation
*
*/




/**
 * @internal reviewed 31/07/2007 by Simon Brooks
 */

// INCLUDE FILES

#include "glxtnbackgroundgenerationtask.h"

#include <fbs.h>
#include <glxassert.h>
#include <glxtracer.h>
#include <glxthumbnail.h>
#include <featmgr.h>
#include <bldvariant.hrh>   // For feature constants

#include "glxtnfileinfo.h"
#include "glxtnfileutility.h"
#include "glxtnimageutility.h"
#include "glxtnvideoutility.h"
#include "mglxtnstorage.h"
#include "mglxtnthumbnailcreatorclient.h"



// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// CGlxtnBackgroundGenerationTask::CGlxtnBackgroundGenerationTask
// C++ default constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
CGlxtnBackgroundGenerationTask::CGlxtnBackgroundGenerationTask(
                    const TGlxMediaId& iItemId, CGlxtnFileUtility& aFileUtility,
                    MGlxtnThumbnailCreatorClient& aClient, 
                    CGlxSettingsModel::TSupportedOrientations aSupportedOrientations) :
    CGlxtnSaveThumbnailTask(KGlxtnTaskIdBackgroundThumbnailGeneration,
                            iItemId, aClient.ThumbnailStorage()),
    iClient(&aClient), iFileUtility(aFileUtility),
    iSupportedOrientations(aSupportedOrientations)
    {
    TRACER("CGlxtnBackgroundGenerationTask::CGlxtnBackgroundGenerationTask()");
    // Background task is always low priority
    SetPriority(EPriorityLow);
    }

// -----------------------------------------------------------------------------
// CGlxtnBackgroundGenerationTask::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CGlxtnBackgroundGenerationTask::ConstructL()
    {
    TRACER("void CGlxtnBackgroundGenerationTask::ConstructL()");
    iImageUtility = new (ELeave) CGlxtnImageUtility(iFileUtility.FsSession());
    LayoutSpecificDataL();
    
	}

// -----------------------------------------------------------------------------
// CGlxtnBackgroundGenerationTask::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CGlxtnBackgroundGenerationTask* CGlxtnBackgroundGenerationTask::NewL(
                    const TGlxMediaId& iItemId, CGlxtnFileUtility& aFileUtility,
                    MGlxtnThumbnailCreatorClient& aClient, 
                    CGlxSettingsModel::TSupportedOrientations aSupportedOrientations)
    {
    TRACER("CGlxtnBackgroundGenerationTask* CGlxtnBackgroundGenerationTask::NewL()");
    CGlxtnBackgroundGenerationTask* self
            = new (ELeave) CGlxtnBackgroundGenerationTask(
                                                iItemId, aFileUtility, aClient,
                                                aSupportedOrientations);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop( self );

    return self;
    }

// Destructor
CGlxtnBackgroundGenerationTask::~CGlxtnBackgroundGenerationTask()
    {
    TRACER("Destructor CGlxtnBackgroundGenerationTask::~CGlxtnBackgroundGenerationTask()");
    delete iImageUtility;
    delete iVideoUtility;
    delete iImage;
    delete iFilteredImage;
    iSizes.Close();
    }

// -----------------------------------------------------------------------------
// DoStartL
// -----------------------------------------------------------------------------
//
TBool CGlxtnBackgroundGenerationTask::DoStartL(TRequestStatus& aStatus)
    {
    TRACER("CGlxtnBackgroundGenerationTask::DoStartL()");
    // Sizes to generate, largest first
	
    
    iSizes.AppendL(iGridIconSize);
    if( CGlxSettingsModel::ELandscapeAndPortrait == iSupportedOrientations )
        {
        iSizes.AppendL(iCoverflowIconSize); 
        iSizes.AppendL(TSize(iCoverflowIconSize.iHeight, iCoverflowIconSize.iWidth));
		}
    else if(CGlxSettingsModel::ELandscape == iSupportedOrientations)
        {
        iSizes.AppendL(iCoverflowIconSize);
        }
    else
        {
        iSizes.AppendL(TSize(iCoverflowIconSize.iHeight, iCoverflowIconSize.iWidth));
        }

    iFileInfo = new (ELeave) CGlxtnFileInfo;
    iClient->FetchFileInfoL(iFileInfo, ItemId(), &aStatus);
    iState = EStateFetchingUri;

    return ETrue; // Request has been issued
    }

// -----------------------------------------------------------------------------
// DoCancel
// -----------------------------------------------------------------------------
//
void CGlxtnBackgroundGenerationTask::DoCancel()
    {
    TRACER("void CGlxtnBackgroundGenerationTask::DoCancel()");
    CGlxtnSaveThumbnailTask::DoCancel();
    
    Storage()->NotifyBackgroundError(ItemId(), KErrCancel);

    if ( iClient && EStateFetchingUri == iState )
        {
        iClient->CancelFetchUri(ItemId());
        }

	iImageUtility->Cancel();

	if ( iVideoUtility ) 
		{
		iVideoUtility->Cancel();
		}

    iFileUtility.ClearBadFileMarker();
    }

// -----------------------------------------------------------------------------
// DoRunL
// -----------------------------------------------------------------------------
//
TBool CGlxtnBackgroundGenerationTask::DoRunL(TRequestStatus& aStatus)
    {
    TRACER("TBool CGlxtnBackgroundGenerationTask::DoRunL()");
    User::LeaveIfError(aStatus.Int());

    TBool active = EFalse;

    switch ( iState )
        {
        case EStateFetchingUri:
            {
            iImageDecoded = EFalse;
            iBadFileMarkerNotNeededFlag = ETrue;
            // Client is no longer needed
            iClient->ThumbnailFetchComplete(ItemId(),
                                        EGlxThumbnailQualityHigh, KErrNone);
            iClient = NULL;

            User::LeaveIfNull(iFileInfo);
 
            TBool isVideo, isProtected;
            iFileInfo->IdentifyFileL(isVideo, isProtected);
            // if DRM protected leave
            // assume DRM capablity not present
            if(isProtected)
                {
                User::Leave(KErrAccessDenied);
                }
            
            active = CheckNextL(aStatus);
            }
            break;

        case EStateDecoding:
            iImageUtility->FreeDecoder();
            iImageDecoded = ETrue;
            FilterThumbnailL(aStatus);
            active = ETrue;
            break;

        case EStateFiltering:
            ScaleThumbnailL(aStatus);
            active = ETrue;
            break;

        case EStateSaving:
            active = ProcessNextL(aStatus);
            break;

        case EStateChecking:
            if ( KGlxThumbnailNotAvailable == aStatus.Int() )
                {
                iTodoSizes.AppendL(iSize);
                }
            active = CheckNextL(aStatus);
            break;

        case EStateScaling:
            EncodeThumbnailL(aStatus);
            active = ETrue;
            break;

        case EStateEncoding:
            SaveThumbnailL(aStatus);
            active = ETrue;
            break;

        default:
            GLX_ASSERT_ALWAYS( EFalse, Panic( EGlxPanicIllegalState ),
                            "CGlxtnBackgroundGenerationTask: Illegal state" );
            break;
        }

    if ( !active )
        {
        if( !iBadFileMarkerNotNeededFlag )
            {
            iFileUtility.ClearBadFileMarker();
            }
        // Send notification that we've finished
        Storage()->NotifyBackgroundError( ItemId(), KErrNone );
        }

    return active;  // Task is complete
    }

// -----------------------------------------------------------------------------
// DoRunError
// -----------------------------------------------------------------------------
//
TBool CGlxtnBackgroundGenerationTask::DoRunError(TInt aError)
    {
    TRACER("CGlxtnBackgroundGenerationTask::DoRunError()");
    if( !iBadFileMarkerNotNeededFlag )
        {
        iFileUtility.ClearBadFileMarker();
        }
    if ( iClient )
        {
        iClient->ThumbnailFetchComplete(
                                ItemId(), EGlxThumbnailQualityHigh, aError);
        }
    else
        {
        Storage()->NotifyBackgroundError(ItemId(), aError);
        }

    return EFalse;  // Task is complete
    }

// -----------------------------------------------------------------------------
// CheckNextL
// -----------------------------------------------------------------------------
//
TBool CGlxtnBackgroundGenerationTask::CheckNextL(TRequestStatus& aStatus)
    {
    TRACER("CGlxtnBackgroundGenerationTask::CheckNextL()");
    if ( iSizes.Count() == 0 )
        {
        return ProcessNextL(aStatus);
        }

    iSize = iSizes[0];
    iSizes.Remove(0);

    Storage()->IsThumbnailAvailableL(ItemId(), *iFileInfo, iSize, &aStatus);
    iState = EStateChecking;
    return ETrue;
    }

// -----------------------------------------------------------------------------
// ProcessNextL
// -----------------------------------------------------------------------------
//
TBool CGlxtnBackgroundGenerationTask::ProcessNextL(TRequestStatus& aStatus)
    {
    TRACER("TBool CGlxtnBackgroundGenerationTask::ProcessNextL()");
    if ( iTodoSizes.Count() == 0 )
        {
        return EFalse;
        }

    iSize = iTodoSizes[0];
    if( iImageDecoded )
        {
        FilterThumbnailL(aStatus);
        }
    else
        {
        DecodeImageL(aStatus);
        }
    return ETrue;
    }

// -----------------------------------------------------------------------------
// FilterThumbnailL
// -----------------------------------------------------------------------------
//
void CGlxtnBackgroundGenerationTask::FilterThumbnailL(TRequestStatus& aStatus)
    {
    TRACER("void CGlxtnBackgroundGenerationTask::FilterThumbnailL()");
    // Create thumbnail bitmap of required size
    TSize targetSize(iTodoSizes[0]);
    iTodoSizes.Remove(0);
    iImageUtility->AdjustSize(targetSize, iImage->SizeInPixels());

    delete iThumbnail;
    iThumbnail = NULL;
    iThumbnail = new (ELeave) CFbsBitmap;
    User::LeaveIfError(iThumbnail->Create(targetSize, KGlxThumbnailDisplayMode));

    iImageUtility->FilterImageL(&aStatus, iImage, iFilteredImage, iThumbnail);
    iState = EStateFiltering;
    }

// -----------------------------------------------------------------------------
// ScaleThumbnailL
// -----------------------------------------------------------------------------
//
void CGlxtnBackgroundGenerationTask::ScaleThumbnailL(TRequestStatus& aStatus)
    {
    TRACER("void CGlxtnBackgroundGenerationTask::ScaleThumbnailL()");
    TSize targetSize(iSize);
    const TSize srcSize = iImage->SizeInPixels();
    iImageUtility->AdjustSize(targetSize, iImage->SizeInPixels());
    iImageUtility->ScaleImageL(aStatus, *iImage, srcSize, *iThumbnail, targetSize);
    iState = EStateScaling;
    }

// -----------------------------------------------------------------------------
// DecodeImageL
// -----------------------------------------------------------------------------
//
void CGlxtnBackgroundGenerationTask::DecodeImageL(TRequestStatus& aStatus)
    {
    TRACER("void CGlxtnBackgroundGenerationTask::DecodeImageL()");
    iBadFileMarkerNotNeededFlag = EFalse;
    iFileUtility.CheckBadFileListL( iFileInfo->FilePath() );
    TBool isVideo, isProtected;
    iFileInfo->IdentifyFileL(isVideo, isProtected);
    if ( isVideo )
        {
        iVideoUtility = new (ELeave) CGlxtnVideoUtility;
        iVideoUtility->GetVideoFrameL(&aStatus, iImage,
                                        iFileInfo->FilePath(), iTodoSizes, KGlxThumbnailDisplayMode);
        }
    else
        {
        iImage = iImageUtility->DecodeImageL(aStatus,
                    iFileInfo->FilePath(), iTodoSizes, KGlxThumbnailDisplayMode);
        }
    delete iFilteredImage;
    iFilteredImage = NULL;
    iState = EStateDecoding;
    }
// -----------------------------------------------------------------------------
// LayoutSpecificDataL
// -----------------------------------------------------------------------------
//	
void CGlxtnBackgroundGenerationTask::LayoutSpecificDataL()
	{
	TRACER("void CGlxtnBackgroundGenerationTask::LayoutSpecificDataL()");
	// Sets up TLS, must be done before FeatureManager is used.
	        FeatureManager::InitializeLibL();
	        
	      if(FeatureManager::FeatureSupported( KFeatureIdLayout640_360_Touch ) || FeatureManager::FeatureSupported( KFeatureIdLayout360_640_Touch ))
	          {
	          iGridIconSize = TSize(111,83);
	          iCoverflowIconSize = TSize(640,360);
	          }
	      else if(FeatureManager::FeatureSupported(KFeatureIdLayout640_480_Touch) || FeatureManager::FeatureSupported(KFeatureIdLayout480_640_Touch) || 
	              FeatureManager::FeatureSupported(KFeatureIdLayout640_480) || FeatureManager::FeatureSupported(KFeatureIdLayout480_640))
	          {
	          iGridIconSize = TSize(146,110);
	          iCoverflowIconSize = TSize(640,480);
	          }
	      else
	          {
	          iGridIconSize = TSize(146,110);
	          iCoverflowIconSize = TSize(640,480);
	          }
	    // Frees the TLS. Must be done after FeatureManager is used.
	        FeatureManager::UnInitializeLib(); 
	
	
  }

//  End of File