photosgallery/collectionframework/thumbnailcreator/thumbnailcomposerplugin/glxthumbnailcomposerplugin.cpp
changeset 0 4e91876724a2
child 18 bcb43dc84c44
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photosgallery/collectionframework/thumbnailcreator/thumbnailcomposerplugin/glxthumbnailcomposerplugin.cpp	Thu Dec 17 08:45:44 2009 +0200
@@ -0,0 +1,684 @@
+/*
+* 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 Composer plugin
+*
+*/
+
+
+
+
+/**
+ * @internal reviewed 12/07/2007 by Simon Brooks
+ */
+
+#include <e32base.h>
+
+#include <MdELogicCondition.h>
+#include <mdeconstants.h>
+
+#include <mpxcollectionutility.h>
+#include <mpxcollectionpath.h>
+#include <mpxcollectionmessage.h>
+#include <mpxmessagegeneraldefs.h>
+#include <mpxcollectionframeworkdefs.h>
+
+#include <glxassert.h>
+#include <glxcollectionpluginall.hrh>
+#include <glxthumbnailattributeinfo.h>
+#include <glxbackgroundtnmessagedefs.h>
+#include <glxmediaid.h>
+#include <glxthumbnailinfo.h>
+#include <glxfilterfactory.h>
+#include <glxcommandfactory.h>
+#include <glxtracer.h>
+#include <hal.h>
+
+#include "glxthumbnailcomposerplugin.h"
+
+// This can be any number other than zero
+const TUint KGlxBackgroundThumbnailAttributeId = 1;
+const TInt KGlxThumbnailComposerInactivityTimeout = 30; // seconds
+const TInt KGlxThumbnailComposerDelay = 10000; // microseconds
+const TInt KGlxThumbnailComposerHarvestDelay = 5000000; // microseconds
+const TInt KGlxThumbnailComposerLargeDelay = 30000000; // microseconds
+const TInt KGlxDisplayStatusTimeOutDelay = 5000000; // 5 secs
+
+// ---------------------------------------------------------------------------
+// destructor
+// ---------------------------------------------------------------------------
+//
+CGlxThumbnailCompeserInactivityTimer::~CGlxThumbnailCompeserInactivityTimer()
+    {
+    // no implementation
+    }
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CGlxThumbnailCompeserInactivityTimer* CGlxThumbnailCompeserInactivityTimer::NewL(TInt aPriority, CGlxThumbnailComposerPlugin& aCallback)
+    {
+	TRACER("CGlxThumbnailCompeserInactivityTimer::NewL");
+	CGlxThumbnailCompeserInactivityTimer* self = 
+	                              new (ELeave) CGlxThumbnailCompeserInactivityTimer(aPriority, aCallback);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	CActiveScheduler::Add(self);
+	return self;
+    }
+
+// ---------------------------------------------------------------------------
+// After
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailCompeserInactivityTimer::After( TTimeIntervalMicroSeconds32 aInterval )
+    {
+    TRACER("CGlxThumbnailCompeserInactivityTimer::After");
+
+    // Fix for ELLZ-7DBBDZ and JPKN-7M2AYJ: to prevent a KERN EXEC 15 panic that occurs 
+    // if a timer request is made while one is already outstanding.
+    Cancel();
+    // Forward the call on to the base class.
+    CTimer::After( aInterval );
+    }
+
+// ---------------------------------------------------------------------------
+// constructor
+// ---------------------------------------------------------------------------
+//
+CGlxThumbnailCompeserInactivityTimer::CGlxThumbnailCompeserInactivityTimer(TInt aPriority, CGlxThumbnailComposerPlugin& aCallback)
+         : CTimer(aPriority), iCallback(aCallback)
+        {
+        // no implementation
+        }
+
+// ---------------------------------------------------------------------------
+// RunL
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailCompeserInactivityTimer::RunL()
+    {
+	TRACER("CGlxThumbnailCompeserInactivityTimer::RunL");
+	
+    TInt dispState = KErrNotFound;
+    TInt ret = HAL::Get(HALData::EDisplayState, dispState);
+    GLX_DEBUG4("CGlxThumbnailCompeserInactivityTimer::RunL iCallback.iState = %d, ret=%d, dispState= %d", 
+    																iCallback.iState, ret, dispState );
+	if (iCallback.iState && ret == KErrNone && dispState)
+		{
+		iCallback.DelayDisplayStateCheck();
+	    GLX_LOG_INFO("GlxThumbnailCompeser - DISPLAY ON - DO NOT PROCESS" );
+		return;
+		}
+
+	GLX_LOG_INFO("GlxThumbnailCompeser - DISPLAY OFF - ALLOW TO PROCESS" );
+		
+	switch (iCallback.iState)
+	    {
+    	case CGlxThumbnailComposerPlugin::EStateFirstOpening:
+    	case CGlxThumbnailComposerPlugin::EStateOpening:
+    	    {
+            iCallback.DoOpenCollectionL();
+            break;
+    	    }
+        case CGlxThumbnailComposerPlugin::EStateActiveSmall:
+        case CGlxThumbnailComposerPlugin::EStateActiveLarge:
+            {
+        	iCallback.DoRequestItemL();
+        	break;
+            }
+        case CGlxThumbnailComposerPlugin::EStateClosing:
+            {
+            iCallback.CloseCollection();
+            break;
+            }
+	    }
+    }
+
+// ---------------------------------------------------------------------------
+// DoCancel
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailCompeserInactivityTimer::DoCancel()
+    {
+    // no implementation
+    }
+
+// ---------------------------------------------------------------------------
+// RunError
+// ---------------------------------------------------------------------------
+//
+TInt CGlxThumbnailCompeserInactivityTimer::RunError(TInt /*aError*/)
+    {
+	TRACER("CGlxThumbnailCompeserInactivityTimer::RunError");
+    iCallback.ReturnToIdle();
+    return KErrNone;
+    }
+
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CGlxThumbnailComposerPlugin* CGlxThumbnailComposerPlugin::NewL()
+	{
+	TRACER("CGlxThumbnailComposerPlugin::NewL");
+	CGlxThumbnailComposerPlugin* self = 
+	                              new (ELeave) CGlxThumbnailComposerPlugin();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+// ---------------------------------------------------------------------------
+// ~CGlxThumbnailComposerPlugin
+// ---------------------------------------------------------------------------
+//
+CGlxThumbnailComposerPlugin::~CGlxThumbnailComposerPlugin()
+	{
+	delete iPath;
+    if (iCollectionUtility)
+        {
+        iCollectionUtility->Close();
+        }
+
+	if ( iInactivityTimer )
+	    {
+    	iInactivityTimer->Cancel();
+	    }
+	delete iInactivityTimer;
+	}
+
+// ---------------------------------------------------------------------------
+// CGlxThumbnailComposerPlugin
+// ---------------------------------------------------------------------------
+//
+CGlxThumbnailComposerPlugin::CGlxThumbnailComposerPlugin() : iLastError(KErrNone)
+	{
+	}
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::ConstructL()
+	{
+	TRACER("CGlxThumbnailComposerPlugin::ConstructL");
+	iInactivityTimer = CGlxThumbnailCompeserInactivityTimer::NewL(CActive::EPriorityIdle, *this);
+	}
+
+// ---------------------------------------------------------------------------
+// SetObservers
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::SetObservers()
+	{
+	TRAPD(err, SetObserversL());
+    GLX_ASSERT_ALWAYS( KErrNone == err, Panic( EGlxPanicEnvironment ),
+                        "CGlxThumbnailComposerPlugin cannot set observers, reset Harvester server" );
+	}
+
+// ---------------------------------------------------------------------------
+// SetObserversL
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::SetObserversL()
+	{
+	TRACER("CGlxThumbnailComposerPlugin::SetObserversL");
+	if ( iSession )
+		{
+		CMdELogicCondition* condition = 
+		            CMdELogicCondition::NewLC( ELogicConditionOperatorOr );
+
+#ifdef RD_MDS_2_0
+
+		CMdENamespaceDef* defaultNamespace = 
+		               iSession->GetDefaultNamespaceDefL();
+
+    	CMdEObjectDef* imageDef = defaultNamespace->GetObjectDefL(
+    	                                MdeConstants::Image::KImageObject );
+		condition->AddObjectConditionL( *imageDef );
+
+    	CMdEObjectDef* videoDef = defaultNamespace->GetObjectDefL(
+    	                                MdeConstants::Video::KVideoObject );
+		condition->AddObjectConditionL( *videoDef );
+
+#else
+
+		CMdENamespaceDef& defaultNamespace = 
+		               iSession->GetDefaultNamespaceDefL();
+
+    	CMdEObjectDef& imageDef = defaultNamespace.GetObjectDefL(
+    	                                MdeConstants::Image::KImageObject );
+		condition->AddObjectConditionL( imageDef );
+
+    	CMdEObjectDef& videoDef = defaultNamespace.GetObjectDefL(
+    	                                MdeConstants::Video::KVideoObject );
+		condition->AddObjectConditionL( videoDef );
+
+#endif
+
+		iSession->AddObjectObserverL( *this, condition );
+    	CleanupStack::Pop( condition );
+    	
+        if ( iState == EStateIdle )
+            {
+            iState = EStateFirstOpening;
+            iInactivityTimer->After(KGlxThumbnailComposerLargeDelay);
+            }
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// RemoveObservers
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::RemoveObservers()
+	{
+	if ( iSession )
+		{
+#ifdef RD_MDS_2_0
+		iSession->RemoveObjectObserver( *this );
+#else
+		TRAP_IGNORE(iSession->RemoveObjectObserverL( *this ));
+#endif
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// IsComposingComplete
+// ---------------------------------------------------------------------------
+//
+TBool CGlxThumbnailComposerPlugin::IsComposingComplete()
+	{
+	TRACER("CGlxThumbnailComposerPlugin::IsComposingComplete");
+	// Need to stop background thumbnail generation activity
+	// when harvester requests to pause. 
+	    
+	    if (iState != EStateIdle)
+	        {
+	        iState = EStateClosing;
+	        
+	        if ( iInactivityTimer )
+	            {
+	            iInactivityTimer->Cancel();
+	            }
+
+	        if (iCollectionUtility)
+	            {
+	            iCollectionUtility->Close();
+	            iCollectionUtility = NULL;
+	            }
+	            
+	        iState = EStateIdle;
+	        }
+	    
+	    return ETrue ; //( iState == EStateIdle );
+	}
+
+#ifdef RD_MDS_2_0
+
+// ---------------------------------------------------------------------------
+// HandleObjectAdded
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::HandleObjectAdded(
+        CMdESession& /*aSession*/, const RArray<TItemId>& /*aObjectIdArray*/ )
+	{
+	TRACER("CGlxThumbnailComposerPlugin::HandleObjectAdded");
+    if ( ( iState == EStateIdle ) || ( iState == EStateFirstOpening ) || ( iState == EStateClosing ) )
+        {
+        iInactivityTimer->Cancel();
+        iState = EStateOpening;
+        iInactivityTimer->After(20000000);
+        }
+    else
+        {
+        iLastError = 1;
+        iState = EStateActiveLarge;
+        }
+	}
+
+// ---------------------------------------------------------------------------
+// HandleObjectModified
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::HandleObjectModified(
+                                    CMdESession& /*aSession*/, 
+                                    const RArray<TItemId>& /*aObjectIdArray*/)
+	{
+	//no implemention needed
+	}
+
+// ---------------------------------------------------------------------------
+// HandleObjectRemoved
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::HandleObjectRemoved(
+                                    CMdESession& /*aSession*/, 
+                                    const RArray<TItemId>& /*aObjectIdArray*/)
+	{
+	//no implemention needed
+	}
+
+#else
+
+void CGlxThumbnailComposerPlugin::HandleObjectNotification(CMdESession& /*aSession*/, 
+					TObserverNotificationType aType,
+					const RArray<TItemId>& /*aObjectIdArray*/)
+	{
+	TRACER("CGlxThumbnailComposerPlugin::HandleObjectNotification");
+    if (aType == ENotifyAdd)
+    	{
+			if ( iState == EStateIdle )
+		        {
+		        iState = EStateOpening;
+		        iInactivityTimer->After(KGlxThumbnailComposerLargeDelay);
+		        }
+		    else
+		        {
+		        iLastError = 1;
+		        iState = EStateActiveLarge;
+		        iInactivityTimer->After(KGlxThumbnailComposerLargeDelay);
+		        }
+    	}
+	}
+
+#endif
+
+// ---------------------------------------------------------------------------
+// HandleCollectionMediaL
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::HandleCollectionMediaL(
+                                const CMPXMedia& /*aMedia*/, TInt aError )
+    {
+	TRACER("CGlxThumbnailComposerPlugin::HandleCollectionMediaL");
+    if ( iPath && KErrNone != aError )
+        {
+        GLX_LOG_WARNING1( "Error %d getting media", aError );
+
+        // Error generating thumbnails, try the next item
+        iLastError = aError;
+        iCurrentIndex++;
+        RequestItemL();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// HandleCollectionMessageL
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::HandleCollectionMessage(
+                                        CMPXMessage* aMsg, TInt /*aErr*/ )
+    {
+	TRACER("CGlxThumbnailComposerPlugin::HandleCollectionMessage");
+    if ( iState != EStateIdle && aMsg )
+        {
+        TRAPD( err, DoHandleCollectionMessageL( *aMsg ) );
+        if ( KErrNone != err )
+            {
+            GLX_LOG_WARNING1( "Error %d handling message", err );
+            ReturnToIdle();
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// HandleOpenL
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::HandleOpenL( const CMPXMedia& /*aEntries*/,
+                          TInt /*aIndex*/, TBool /*aComplete*/, TInt aError )
+    {
+	TRACER("CGlxThumbnailComposerPlugin::HandleOpenL");
+    if ( KErrNone != aError )
+        {
+        GLX_LOG_WARNING1( "Error %d opening collection", aError );
+        ReturnToIdle();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// HandleOpenL
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::HandleOpenL(
+            const CMPXCollectionPlaylist& /*aPlaylist*/, TInt /*aError*/ )
+    {
+	// No implemention needed
+    }
+
+// ---------------------------------------------------------------------------
+// HandleCommandComplete
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::HandleCommandComplete(
+                        CMPXCommand* /*aCommandResult*/, TInt /*aError*/ )
+    {
+	TRACER("CGlxThumbnailComposerPlugin::HandleCommandComplete");
+    if( EStateCleanup == iState )
+        {
+        ReturnToIdle();
+        }
+    else
+        {
+        iInactivityTimer->After(0);
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// DoOpenCollectionL
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::DoOpenCollectionL()
+    {
+	TRACER("CGlxThumbnailComposerPlugin::HandleCollectionMediaL");
+    if ( !iCollectionUtility )
+        {
+        // Open isolated collection utility
+        iCollectionUtility = MMPXCollectionUtility::NewL(
+                                                this, KMcModeIsolated );
+        }
+
+    CMPXFilter* filter = CMPXFilter::NewL();
+    CleanupStack::PushL(filter);
+    filter->SetTObjectValueL<TGlxFilterSortDirection>(KGlxFilterGeneralSortDirection, EGlxFilterSortDirectionDescending);        
+    iCollectionUtility->Collection().SetFilterL(filter);
+    CleanupStack::PopAndDestroy(filter);
+
+    CMPXCollectionPath* path = CMPXCollectionPath::NewL();
+    CleanupStack::PushL( path );
+    // argument  path  all collection id
+   	path->AppendL( KGlxCollectionPluginAllImplementationUid );
+
+	iCollectionUtility->Collection().OpenL( *path );
+ 	CleanupStack::PopAndDestroy( path );
+
+    iState = EStateActiveSmall;                    
+    }
+
+// ---------------------------------------------------------------------------
+// DoHandleCollectionMessageL
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::DoHandleCollectionMessageL(
+                                                 const CMPXMessage& aMsg )
+    {
+	TRACER("CGlxThumbnailComposerPlugin::DoHandleCollectionMessageL");
+    if ( aMsg.IsSupported( KMPXMessageGeneralId ) )
+        {
+        TInt messageId = aMsg.ValueTObjectL<TInt>( KMPXMessageGeneralId );
+
+	    // Is it a background thumbnail message        
+	    if ( KGlxMessageIdBackgroundThumbnail == messageId )
+	        {
+	        // Is it the item expected
+	        TGlxMediaId id( ( TUint32 )
+	             aMsg.ValueTObjectL<TMPXItemId>( KGlxBackgroundThumbnailMediaId ) );
+	        if ( iPath && id.Value()
+	                        == ( TUint32 )iPath->IdOfIndex( iCurrentIndex ) )
+	            {
+	            TInt error = aMsg.ValueTObjectL<TInt>( KGlxBackgroundThumbnailError );
+	            if ( error == KErrCancel )
+	                {
+	                iState = EStateActiveLarge;
+    	            iLastError = error;
+	                }
+	            else if( KErrNone != error )
+	                {
+                    GLX_LOG_WARNING1( "Error %d in command", error );
+                    error = KErrNone;
+	                }
+	            // Yes, then request the next item
+	            iCurrentIndex++;
+	            RequestItemL();
+	            }
+	        }
+        else if ( KMPXMessageGeneral == messageId
+                && aMsg.IsSupported( KMPXMessageGeneralEvent ) )
+            {
+            TInt messageEvent = aMsg.ValueTObjectL<TInt>( KMPXMessageGeneralEvent );
+
+            // Is it a path changed event
+            if ( TMPXCollectionMessage::EPathChanged == messageEvent
+                && aMsg.IsSupported( KMPXMessageGeneralType ) )
+                {
+    	        TInt messageType = aMsg.ValueTObjectL<TInt>( KMPXMessageGeneralType );
+
+             	if ( EMcPathChangedByOpen == messageType
+             	    && iCollectionUtility && !iPath )
+            	    {
+         		    iPath = iCollectionUtility->Collection().PathL();
+
+                   	iCurrentIndex = 0;
+                    RequestItemL();
+            	    }
+               }
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// RequestItemL
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::RequestItemL()
+    {
+	TRACER("CGlxThumbnailComposerPlugin::RequestItemL");
+    if ( iLastError == KErrCancel )
+        {
+        iInactivityTimer->Inactivity(KGlxThumbnailComposerInactivityTimeout);
+        }
+    else if ( iLastError == 1 )
+        {
+        iInactivityTimer->After(KGlxThumbnailComposerHarvestDelay);
+        }
+    else
+        {
+        iInactivityTimer->After(KGlxThumbnailComposerDelay);
+        }
+    iLastError = KErrNone;
+    }
+    
+// ---------------------------------------------------------------------------
+// DoRequestItemL
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::DoRequestItemL()
+    {
+	TRACER("CGlxThumbnailComposerPlugin::DoRequestItemL");
+
+    if ( iPath && iCurrentIndex < iPath->Count() )
+        {
+        GLX_ASSERT_ALWAYS( iCollectionUtility, Panic( EGlxPanicNullPointer ),
+                            "No collection utility" );
+        // request next item
+    	iPath->Set( iCurrentIndex );
+
+        RArray<TMPXAttribute> attrs;
+        CleanupClosePushL( attrs );
+        // Add thumbnail attribute
+        attrs.AppendL( TMPXAttribute(
+                KGlxMediaIdThumbnail, KGlxBackgroundThumbnailAttributeId ) );
+
+        // Don't add spec for bitmap handle, to request background thumbnail
+        CMPXAttributeSpecs* attrSpecs = NULL;
+        
+        // Start first task
+        iCollectionUtility->Collection().MediaL(
+                                    *iPath, attrs.Array(), attrSpecs );
+        CleanupStack::PopAndDestroy( &attrs );
+        }
+    else
+        {
+        delete iPath;
+        iPath = NULL;
+        
+        if ( iState == EStateActiveLarge )
+            {
+            // go on to do small thumbnails
+            DoOpenCollectionL();
+            }
+        else
+            {
+            CMPXCommand* command
+                            = TGlxCommandFactory::ThumbnailCleanupCommandLC();
+            iCollectionUtility->Collection().CommandL( *command );
+            CleanupStack::PopAndDestroy( command );
+
+            iState = EStateCleanup;
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ReturnToIdle
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::ReturnToIdle()
+    {
+	TRACER("CGlxThumbnailComposerPlugin::ReturnToIdle");
+    iState = EStateClosing;
+    iInactivityTimer->After(KGlxThumbnailComposerLargeDelay);
+    }
+
+// ---------------------------------------------------------------------------
+// DelayDisplayStateCheck
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::DelayDisplayStateCheck()
+    {
+	TRACER("CGlxThumbnailComposerPlugin::DelayDisplayStateCheck");
+    iInactivityTimer->After(KGlxDisplayStatusTimeOutDelay);	
+    }
+
+// ---------------------------------------------------------------------------
+// CloseCollection
+// ---------------------------------------------------------------------------
+//
+void CGlxThumbnailComposerPlugin::CloseCollection()
+    {
+	TRACER("CGlxThumbnailComposerPlugin::CloseCollection");
+    if ( ( EStateClosing == iState ) && iCollectionUtility )
+        {
+        iCollectionUtility->Close();
+        iCollectionUtility = NULL;
+        iState = EStateIdle;
+        }
+    }