photosgallery/viewframework/medialists/src/glxerrormanager.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 19 Feb 2010 22:51:01 +0200
branchRCL_3
changeset 9 6b87b143d312
parent 0 4e91876724a2
permissions -rw-r--r--
Revision: 201003 Kit: 201007

/*
* 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:    Utility class to manage attribute retrieval errors
*
*/




#include "glxerrormanager.h"

//#include <glxerrors.h>

#include "glxfetcherrorarray.h"
#include "glxcachemanager.h"
#include "glxmedialist.h"
#include <glxtracer.h>                         // For Logs
#include <glxlog.h>                         // For Logs

/** Error attribute content ID */
const TInt KGlxErrorContentId = 0x200071AC;
const TMPXAttributeData KGlxMediaErrorArray = { KGlxErrorContentId, 0x01 }; // CGlxFetchErrorArray

const TInt KGlxErrorTimeOut = -10033;

// -----------------------------------------------------------------------------
// Return errors
// -----------------------------------------------------------------------------
//
inline CGlxFetchErrorArray* Errors( const CGlxMedia& aMedia ) 
    {
    TRACER("GlxErrorManager::Errors");
    
    return const_cast<CGlxFetchErrorArray*>(
        static_cast<const CGlxFetchErrorArray*>( aMedia.ValueCObject( 
            KGlxMediaErrorArray ) ) );
    }

// -----------------------------------------------------------------------------
// SetAttributeErrorL
// -----------------------------------------------------------------------------
//
void GlxErrorManager::SetAttributeErrorL(CGlxMedia* aItem, const RArray<TMPXAttribute>& aAttributes, TInt aError)
    {
    TRACER("GlxErrorManager::SetAttributeErrorL");
    
    if ( aItem )
        {
        CGlxFetchErrorArray* errorArray = NULL;
            
        if ( aItem->IsSupported(KGlxMediaErrorArray) )
            {
    		const CGlxFetchErrorArray* existingArray = static_cast<const CGlxFetchErrorArray*>(aItem->ValueCObject(KGlxMediaErrorArray));
    		
    		if ( existingArray )
    		    {
                errorArray = CGlxFetchErrorArray::NewLC(existingArray);
                }
            }
            
        if ( !errorArray )            
            {
            errorArray = new(ELeave) CGlxFetchErrorArray();
            CleanupStack::PushL(errorArray);
            }

        TInt attrCount = aAttributes.Count();
        
        for ( TInt attrIndex = 0; attrIndex < attrCount; attrIndex++ )
            {
            errorArray->AddErrorL(TGlxFetchError(aAttributes[attrIndex], aError));
            }
        
        aItem->SetCObjectValueL(KGlxMediaErrorArray, errorArray);

        CleanupStack::Pop(errorArray);
        }            
    }
    
// -----------------------------------------------------------------------------
// HasAttributeErrorL
// -----------------------------------------------------------------------------
//
EXPORT_C TInt GlxErrorManager::HasAttributeErrorL(const CGlxMedia* aMedia, 
        const TMPXAttribute& aAttribute)
    {
    TRACER("GlxErrorManager::HasAttributeErrorL");
    
    TInt retVal = KErrNone;
    
    if ( aMedia )
        {
        const CGlxFetchErrorArray* errors = Errors( *aMedia );
		
		if ( errors )
		    {
		    TInt index = errors->FindError(aAttribute);
		    if ( KErrNotFound != index )
		        {
    		    TGlxFetchError error = errors->Error(index);
		        retVal = error.iError;
		        
	            if ( IsExpired( error ) )
	                {
	                retVal = KErrNone;
	                }
	                
	            if ( KErrNone != retVal )
	                {
	                if ( IsTemporaryError(retVal) )
	                    {
    		            // Inform cache manager that at least one temporary error still exists
    		            CGlxCacheManager* cacheManager = CGlxCacheManager::InstanceL();
    		            cacheManager->SetTemporaryErrorFlag();
    		            cacheManager->Close();
	                    }
	                }
		        }
		    }
        }
        
    return retVal;
    }
    
// -----------------------------------------------------------------------------
// HasAttributeErrorL
// -----------------------------------------------------------------------------
//
EXPORT_C TInt GlxErrorManager::HasAttributeErrorL(const CGlxMedia* aMedia, 
        TInt aContentId)
    {
    TRACER("GlxErrorManager::HasAttributeErrorL");
    
    TInt retVal = KErrNone;
    if ( aMedia )
        {
        const CGlxFetchErrorArray* errors = Errors( *aMedia );
		
		if ( errors )
		    {
		    TInt index = errors->FindError(aContentId);
		    if ( KErrNotFound != index )
		        {
    		    TGlxFetchError error = errors->Error(index);
		        retVal = error.iError;
		        
	            if ( IsExpired( error ) )
	                {
	                retVal = KGlxErrorTimeOut;
	                }
	                
	            if ( KErrNone != retVal && KGlxErrorTimeOut != retVal)
	                {
	                if ( IsTemporaryError(retVal) )
	                    {
    		            // Inform cache manager that at least one temporary error still exists
    		            CGlxCacheManager* cacheManager = CGlxCacheManager::InstanceL();
    		            cacheManager->SetTemporaryErrorFlag();
    		            cacheManager->Close();
	                    }
	                }
		        }
		        
		    }
        }
        
    return retVal;
    }

// -----------------------------------------------------------------------------
// IsTemporaryError
// -----------------------------------------------------------------------------
//
TBool GlxErrorManager::IsTemporaryError(TInt aErrorCode)
    {
    TRACER("GlxErrorManager::IsTemporaryError");
 	GLX_DEBUG2("GlxErrorManager::IsTemporaryError() aErrorCode=%d", aErrorCode);
	               	 	    
    /// @todo Implement this when list of temporary and permanent errors are known. Currently assume
    ///       all errors are temporary
    switch ( aErrorCode )
        {
        case KErrArgument:      // fallthrough
        case KErrNotSupported:  // fallthrough
        case KErrNoMemory:      // fallthrough
        case KErrCorrupt:       // fallthrough
        case KErrDiskFull:      
        // add other permanent error codes here
            return EFalse;
            
        default:
            return ETrue;
        };
    }
    
// -----------------------------------------------------------------------------
// IsErrorStillVal
// -----------------------------------------------------------------------------
//
TBool GlxErrorManager::IsExpired( const TGlxFetchError& aError )
    {
    TRACER("GlxErrorManager::IsExpired");
    
    if ( IsTemporaryError(aError.iError) )
        {
        TTime now;
        now.UniversalTime();

        TTime errorTime(aError.iTimestamp);

        if ( now - TTimeIntervalSeconds(KGlxTemporaryErrorValidityPeriodInSeconds) > errorTime )
            {
            return ETrue;
            }
        }
        
    return EFalse;
    }
    
// -----------------------------------------------------------------------------
// HasError
// -----------------------------------------------------------------------------
//
TBool GlxErrorManager::HasError(const CGlxMedia* aMedia)
    {
    TRACER("GlxErrorManager::HasError");
    
    if ( aMedia )
        {
        return ( Errors( *aMedia ) != NULL );
        }
    
    return EFalse;
    }
    
// -----------------------------------------------------------------------------
// ClearExpiredAndUnusedErrorsL
// -----------------------------------------------------------------------------
//
void GlxErrorManager::ClearExpiredAndUnusedErrorsL( CGlxMedia& aMedia, 
        const RArray<TMPXAttribute>& aAttributesInUse )
    {
    TRACER("GlxErrorManager::ClearExpiredAndUnusedErrorsL");
    
    CGlxFetchErrorArray* errors = Errors( aMedia );
    
    if ( errors )
        {
        // Iterate through the list of errors backwards, so that removal is more
        // efficient, and loop control easier
        for ( TInt i = errors->ErrorCount() - 1; i >= 0; i-- )
            {
            TGlxFetchError error = errors->Error( i );
            // remove the error if it has expired, or if the attribute 
            // that the error is for is no longer in use
            if ( IsExpired( error ) || 
                 KErrNotFound == aAttributesInUse.Find( error.iAttr, TMPXAttribute::Match ) )
                {
                errors->Remove( i );
                }
            }
            
        // no further errors are remaining, so can remove the error array 
        // attribute from the media object
        if ( errors->ErrorCount() == 0 )
            {
            aMedia.DeleteAttribute( KGlxMediaErrorArray );
            }
        }
    }

// -----------------------------------------------------------------------------
// Return error attribute's id
// -----------------------------------------------------------------------------
//
TMPXAttribute GlxErrorManager::ErrorAttribute()
    {
    TRACER("GlxErrorManager::ErrorAttribute");
    
    return KGlxMediaErrorArray;
    }