--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/photosgallery/collectionframework/datasource/plugins/glxdatasourcemde2.5/src/glxdatasourcemds.cpp Thu Dec 17 08:45:44 2009 +0200
@@ -0,0 +1,1250 @@
+/*
+* 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: Data Source MDS Class
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "glxdatasourcemds.h"
+
+#include <e32base.h>
+#include <fbs.h>
+#include <glxbackgroundtnmessagedefs.h>
+#include <glxcollectionmessagedefs.h>
+#include <glxcommandrequest.h>
+#include <glxgetrequest.h>
+#include <glxidlistrequest.h>
+#include <glxrequest.h>
+#include <glxthumbnailrequest.h>
+
+#ifndef USE_S60_TNM
+#include <glxtndatabase.h>
+#include <glxtnthumbnailcreator.h>
+#endif
+
+#include <glxtracer.h>
+#include <glxlog.h>
+#include <mdeobjectcondition.h>
+#include <mderelationcondition.h>
+#include <mderelationdef.h>
+#include <mpxmediageneraldefs.h>
+#include <mpxmessagegeneraldefs.h>
+
+#include "glxdatasourcetaskmds.h"
+#include "glxdatasourcetaskmdsattribute.h"
+#include "glxdatasourcetaskmdscommand.h"
+#include "glxdatasourcetaskmdsidlist.h"
+#include "glxdatasourcetaskmdsthumbnail.h"
+
+#ifdef USE_S60_TNM
+const TInt KMaxGridThumbnailWidth = 200;
+#else
+const TInt KGlxThumbnailCleanupAfterDeletions = 200;
+
+_LIT(KGlxMdeDataSourceThumbnailDatabase, "glxmdstn");
+#endif
+
+_LIT(KObjectDefLocation, "Location");
+_LIT(KObjectDefNameAlbum, "Album");
+_LIT(KObjectDefNameImage, "Image");
+_LIT(KObjectDefNameMedia, "MediaObject");
+_LIT(KObjectDefNameObject, "Object");
+_LIT(KObjectDefNameTag, "Tag");
+_LIT(KObjectDefNameVideo, "Video");
+_LIT(KPropertyDefNameCreationDate, "CreationDate");
+_LIT(KPropertyDefNameLastModifiedDate, "LastModifiedDate");
+_LIT(KPropertyDefNameSize, "Size");
+_LIT(KPropertyDefNameTitle, "Title");
+_LIT(KRelationDefNameContains, "Contains");
+_LIT(KRelationDefNameContainsLocation, "ContainsLocation");
+
+_LIT(KObjectDefNameMonth, "MediaObject");/// @todo nasty hack remove and use base object
+
+_LIT(KGlxMdeCameraAlbumUri, "defaultalbum_captured");
+_LIT(KGlxMdeFavoritesUri, "defaultalbum_favourites");
+
+#undef __USING_INTELLIGENT_UPDATE_FILTERING
+
+const TInt KHarvestUpdateChunkSize = 1000;
+
+// ---------------------------------------------------------------------------
+// MPXChangeEventType
+// Helper method
+// ---------------------------------------------------------------------------
+//
+TMPXChangeEventType MPXChangeEventType(const TObserverNotificationType& aType)
+ {
+ TMPXChangeEventType type = EMPXItemInserted;
+
+ switch (aType)
+ {
+ case ENotifyAdd:
+ type = EMPXItemInserted;
+ break;
+ case ENotifyModify:
+ type = EMPXItemModified;
+ break;
+ case ENotifyRemove:
+ type = EMPXItemDeleted;
+ break;
+ }
+ return type;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CGlxMDSShutdownObserver::NewL()
+// ---------------------------------------------------------------------------
+//
+CGlxMDSShutdownObserver* CGlxMDSShutdownObserver::NewL( MGlxMDSShutdownObserver& aObserver,
+ const TUid& aKeyCategory,
+ const TInt aPropertyKey,
+ TBool aDefineKey)
+ {
+ TRACER("CGlxMDSShutdownObserver* CGlxMDSShutdownObserver::NewL");
+ CGlxMDSShutdownObserver* self = new( ELeave )CGlxMDSShutdownObserver( aObserver,
+ aKeyCategory,
+ aPropertyKey,
+ aDefineKey);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxMDSShutdownObserver::CGlxMDSShutdownObserver()
+// ---------------------------------------------------------------------------
+//
+CGlxMDSShutdownObserver::CGlxMDSShutdownObserver( MGlxMDSShutdownObserver& aObserver,
+ const TUid& aKeyCategory,
+ const TInt aPropertyKey,
+ TBool aDefineKey)
+ : CActive( CActive::EPriorityStandard ), iObserver( aObserver ),
+ iKeyCategory( aKeyCategory ), iPropertyKey(aPropertyKey), iDefineKey( aDefineKey )
+ {
+ TRACER("CGlxMDSShutdownObserver::CGlxMDSShutdownObserver()");
+ CActiveScheduler::Add( this );
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxMDSShutdownObserver::ConstructL()
+// ---------------------------------------------------------------------------
+//
+void CGlxMDSShutdownObserver::ConstructL()
+ {
+ TRACER("void CGlxMDSShutdownObserver::ConstructL()");
+ // define P&S property types
+ if (iDefineKey)
+ {
+ RProperty::Define(iKeyCategory,iPropertyKey,
+ RProperty::EInt,KAllowAllPolicy,KPowerMgmtPolicy);
+ }
+
+ // attach to the property
+ TInt err = iProperty.Attach(iKeyCategory,iPropertyKey,EOwnerThread);
+ User::LeaveIfError(err);
+
+ // wait for the previously attached property to be updated
+ iProperty.Subscribe(iStatus);
+ SetActive();
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxMDSShutdownObserver::~CGlxMDSShutdownObserver()
+// ---------------------------------------------------------------------------
+//
+CGlxMDSShutdownObserver::~CGlxMDSShutdownObserver()
+ {
+ TRACER("CGlxMDSShutdownObserver::~CGlxMDSShutdownObserver()");
+ Cancel();
+ iProperty.Close();
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxMDSShutdownObserver::RunL()
+// ---------------------------------------------------------------------------
+//
+void CGlxMDSShutdownObserver::RunL()
+ {
+ TRACER("void CGlxMDSShutdownObserver::RunL()");
+
+ // resubscribe before processing new value to prevent missing updates
+ iProperty.Subscribe(iStatus);
+ SetActive();
+
+ // retrieve the value
+ TInt value = 0;
+ TInt Err = iProperty.Get(value);
+ GLX_DEBUG2("CGlxMDSShutdownObserver::RunL(): iProperty.Get(value); returns %d", Err);
+
+ User::LeaveIfError(Err);
+
+ iObserver.ShutdownNotification(value);
+
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxMDSShutdownObserver::DoCancel()
+// ---------------------------------------------------------------------------
+//
+void CGlxMDSShutdownObserver::DoCancel()
+ {
+ TRACER("void CGlxMDSShutdownObserver::DoCancel()");
+ iProperty.Cancel();
+ }
+
+
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+// ---------------------------------------------------------------------------
+// NewL()
+// ---------------------------------------------------------------------------
+//
+CGlxDataSourceMde* CGlxDataSourceMde::NewL()
+ {
+ TRACER("CGlxDataSourceMde* CGlxDataSourceMde::NewL()");
+ CGlxDataSourceMde* ds = new (ELeave) CGlxDataSourceMde();
+ CleanupStack::PushL(ds);
+ ds->ConstructL();
+ CleanupStack::Pop(ds);
+ return ds;
+ }
+
+// ---------------------------------------------------------------------------
+// ~CGlxDataSourceMde()
+// ---------------------------------------------------------------------------
+//
+
+CGlxDataSourceMde::~CGlxDataSourceMde()
+ {
+ TRACER("CGlxDataSourceMde::~CGlxDataSourceMde()");
+ delete iSession;
+
+#ifdef USE_S60_TNM
+ delete iTnThumbnail;
+ iTnThumbnail = NULL;
+
+ delete iThumbnail;
+ iThumbnail = NULL;
+
+ delete iTnEngine;
+ iTnEngine = NULL;
+#else
+ if (iThumbnailCreator)
+ {
+ iThumbnailCreator->Close(iThumbnailDatabase);
+ }
+ delete iThumbnailDatabase;
+#endif
+ iFs.Close();
+ iHC.Close();
+ RFbsSession::Disconnect();
+ iMonthArray.Close();
+ iMonthList.Close();
+ iUpdateData.Close();
+ iAddedItems.Reset();
+ iAddedItems.Close();
+ delete iUpdateCallback;
+ delete iCreateSessionCallback;
+ delete iMDSShutdownObserver ;
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxDataSourceMde()
+// ---------------------------------------------------------------------------
+//
+CGlxDataSourceMde::CGlxDataSourceMde()
+ {
+ TRACER("CGlxDataSourceMde::CGlxDataSourceMde()");
+ //No Implementation
+ }
+
+// ---------------------------------------------------------------------------
+// ConstructL()
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::ConstructL()
+ {
+ TRACER("CGlxDataSourceMde::ConstructL()");
+
+ iDataSourceReady = EFalse;
+ User::LeaveIfError(iFs.Connect());
+ iSession = CMdESession::NewL( *this );
+
+ User::LeaveIfError(RFbsSession::Connect());
+
+#ifdef USE_S60_TNM
+ iTnEngine = CThumbnailManager::NewL( *this);
+ iTnEngine->SetDisplayModeL( EColor64K );
+
+ iTnRequestInProgress = EFalse;
+#else
+ iThumbnailCreator = CGlxtnThumbnailCreator::InstanceL();
+ iThumbnailDatabase = CGlxtnThumbnailDatabase::NewL(
+ KGlxMdeDataSourceThumbnailDatabase, this);
+#endif
+
+ iCreateSessionCallback = new ( ELeave )
+ CAsyncCallBack( TCallBack( CreateSession, this ), CActive::EPriorityHigh );
+
+ iMDSShutdownObserver = CGlxMDSShutdownObserver::NewL( *this, KHarvesterPSShutdown, KMdSShutdown, EFalse );
+
+ iUpdateCallback = new ( ELeave )
+ CAsyncCallBack( TCallBack( ProcessItemUpdate, this ), CActive::EPriorityLow );
+ iUpdateData.Reserve(100); // ignore if it fails
+
+ User::LeaveIfError(iHC.Connect());
+ iHC.AddHarvesterEventObserver(*this, EHEObserverTypePlaceholder, KHarvestUpdateChunkSize);
+
+ iHarvestingOngoing = EFalse;
+ }
+
+// ----------------------------------------------------------------------------
+// from MMdESessionObserver
+// CMPXCollectionMdEPlugin::HandleSessionOpened
+// ----------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::HandleSessionOpened( CMdESession& aSession, TInt aError )
+ {
+ TRACER("CGlxDataSourceMde::HandleSessionOpened(CMdESession& aSession, TInt aError)");
+ if( KErrNone != aError )
+ {
+ HandleSessionError(aSession, aError);
+ }
+ TRAPD(err, DoSessionInitL());
+ if( KErrNone != err )
+ {
+ HandleSessionError(aSession, err);
+ }
+
+ iSessionOpen = ETrue;
+ iDataSourceReady = ETrue;
+ TryStartTask(ETrue);
+ }
+
+// ----------------------------------------------------------------------------
+// from MMdESessionObserver
+// CMPXCollectionMdEPlugin::HandleSessionError
+// ----------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::HandleSessionError(CMdESession& /*aSession*/, TInt aError )
+ {
+ TRACER("CGlxDataSourceMde::HandleSessionError(CMdESession& /*aSession*/, TInt aError)")
+ iSession = NULL;
+
+ GLX_DEBUG2("void CGlxDataSourceMde::HandleSessionError() Session Error = %d", aError);
+
+ iDataSourceReady = EFalse;
+ iSessionOpen = EFalse;
+
+ // We wait till MDS restarts before starting the session if the current session is locked.
+ // that is handled separately by the MDS Shutdown PUB SUB Framework.
+ // for everything else we use the generic method and continue.
+ if ( (KErrLocked != aError) && ( KErrServerTerminated != aError) )
+ {
+ iCreateSessionCallback->CallBack();
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CreateTaskL
+// ---------------------------------------------------------------------------
+//
+CGlxDataSourceTask* CGlxDataSourceMde::CreateTaskL(CGlxRequest* aRequest,
+ MGlxDataSourceRequestObserver& aObserver)
+ {
+ TRACER("CGlxDataSourceTask* CGlxDataSourceMde::CreateTaskL(CGlxRequest* aRequest,MGlxDataSourceRequestObserver& aObserver)") ;
+ if(dynamic_cast<CGlxCommandRequest*>(aRequest))
+ {
+ CleanupStack::PushL(aRequest);
+ CGlxDataSourceTaskMdeCommand* task = new (ELeave)
+ CGlxDataSourceTaskMdeCommand(static_cast<CGlxCommandRequest*>(aRequest),
+ aObserver, this);
+ CleanupStack::Pop(aRequest); // now owned by task
+ CleanupStack::PushL(task);
+ task->ConstructL();
+ CleanupStack::Pop(task);
+ return task;
+ }
+ else if (dynamic_cast< CGlxGetRequest *>(aRequest))
+ {
+ CleanupStack::PushL(aRequest);
+ CGlxDataSourceTaskMdeAttributeMde* task = new (ELeave)
+ CGlxDataSourceTaskMdeAttributeMde(static_cast<CGlxGetRequest*>(aRequest),
+ aObserver, this);
+ CleanupStack::Pop(aRequest); // now owned by task
+ CleanupStack::PushL(task);
+ task->ConstructL();
+ CleanupStack::Pop(task);
+ return task;
+ }
+ else if (dynamic_cast< CGlxIdListRequest *>(aRequest))
+ {
+ CleanupStack::PushL(aRequest);
+ CGlxDataSourceTaskMdeIdList* task = new (ELeave)
+ CGlxDataSourceTaskMdeIdList(static_cast<CGlxIdListRequest*>(aRequest),
+ aObserver, this);
+ CleanupStack::Pop(aRequest); // now owned by task
+ CleanupStack::PushL(task);
+ task->ConstructL();
+ CleanupStack::Pop(task);
+ return task;
+ }
+ else if (dynamic_cast< CGlxThumbnailRequest *>(aRequest))
+ {
+ CleanupStack::PushL(aRequest);
+ CGlxDataSourceTaskMdeThumbnail* task = new (ELeave)
+ CGlxDataSourceTaskMdeThumbnail(static_cast<CGlxThumbnailRequest*>(aRequest),
+ aObserver, this);
+ CleanupStack::Pop(aRequest); // now owned by task
+ CleanupStack::PushL(task);
+ task->ConstructL();
+ CleanupStack::Pop(task);
+ return task;
+ }
+ else
+ {
+ User::Leave(KErrNotSupported);
+ return NULL; // stops compiler warning
+ }
+ }
+
+#ifndef USE_S60_TNM
+// ---------------------------------------------------------------------------
+// ThumbnailAvailable
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::ThumbnailAvailable(const TGlxMediaId&
+ /*aId*/, const TSize& /*aSize*/)
+ {
+ TRACER("CGlxDataSourceMde::ThumbnailAvailable(const TGlxMediaId& /*aId*/, const TSize& /*aSize*/)");
+ //No implementation
+ }
+
+// ---------------------------------------------------------------------------
+// BackgroundThumbnailError
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::BackgroundThumbnailError(const TGlxMediaId& aId, TInt aError)
+ {
+ TRACER("CGlxDataSourceMde::BackgroundThumbnailError(const TGlxMediaId& aId, TInt aError)");
+ TSize size(0, 0);
+ TRAP_IGNORE(BackgroundThumbnailMessageL(aId, size, aError));
+ }
+#endif
+
+// ---------------------------------------------------------------------------
+// BackgroundThumbnailMessageL
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::BackgroundThumbnailMessageL(const TGlxMediaId& aId,
+ const TSize& aSize, TInt aError)
+ {
+ TRACER("CGlxDataSourceMde::BackgroundThumbnailMessageL(const TGlxMediaId& aId, const TSize& aSize, TInt aError)");
+ CMPXMessage* message = CMPXMessage::NewL();
+ CleanupStack::PushL(message);
+ message->SetTObjectValueL(KMPXMessageGeneralId, KGlxMessageIdBackgroundThumbnail);
+ message->SetTObjectValueL<TMPXItemId>(KGlxBackgroundThumbnailMediaId, aId.Value());
+ message->SetTObjectValueL(KGlxBackgroundThumbnailSize, aSize);
+ message->SetTObjectValueL(KGlxBackgroundThumbnailError, aError);
+ BroadcastMessage(*message);
+ CleanupStack::PopAndDestroy(message);
+ }
+
+// ---------------------------------------------------------------------------
+// DoSessionInitL
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::DoSessionInitL()
+ {
+ TRACER("CGlxDataSourceMde::DoSessionInitL()");
+ /// @todo check schema version number
+ iNameSpaceDef = &iSession->GetDefaultNamespaceDefL();
+
+ CMdEObject* cameraAlbum = iSession->GetObjectL(KGlxMdeCameraAlbumUri);
+ if ( !cameraAlbum )
+ {
+ User::Leave(KErrCorrupt);
+ }
+ iCameraAlbumId = (TGlxMediaId)cameraAlbum->Id();
+ delete cameraAlbum;
+
+ CMdEObject* favorites = iSession->GetObjectL(KGlxMdeFavoritesUri);
+ if ( !favorites )
+ {
+ User::Leave(KErrCorrupt);
+ }
+ iFavoritesId = (TGlxMediaId)favorites->Id();
+ delete favorites;
+
+
+ iContainsDef = &iNameSpaceDef->GetRelationDefL(KRelationDefNameContains);
+ iContainsLocationDef = &iNameSpaceDef->GetRelationDefL(KRelationDefNameContainsLocation);
+
+ iObjectDef = &iNameSpaceDef->GetObjectDefL(KObjectDefNameObject);
+ iImageDef = &iNameSpaceDef->GetObjectDefL(KObjectDefNameImage);
+ iVideoDef = &iNameSpaceDef->GetObjectDefL(KObjectDefNameVideo);
+ iMediaDef = &iNameSpaceDef->GetObjectDefL(KObjectDefNameMedia);
+ iAlbumDef = &iNameSpaceDef->GetObjectDefL(KObjectDefNameAlbum);
+ iTagDef = &iNameSpaceDef->GetObjectDefL(KObjectDefNameTag);
+ iMonthDef = &iNameSpaceDef->GetObjectDefL(KObjectDefNameMonth);
+ iLocationDef = &iNameSpaceDef->GetObjectDefL(KObjectDefLocation);
+
+ AddMdEObserversL();
+
+ PrepareMonthsL();
+ }
+
+// ---------------------------------------------------------------------------
+// AddMdEObserversL
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::AddMdEObserversL()
+ {
+ TRACER("CGlxDataSourceMde::AddMdEObserversL()");
+ iSession->AddRelationObserverL(*this);
+ iSession->AddRelationPresentObserverL(*this);
+
+ iSession->AddObjectObserverL(*this);
+ iSession->AddObjectPresentObserverL(*this);
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxDataSourceMde::HandleObjectNotification
+// ---------------------------------------------------------------------------
+//
+///@todo AB test this
+void CGlxDataSourceMde::HandleObjectNotification(CMdESession& /*aSession*/,
+ TObserverNotificationType aType,
+ const RArray<TItemId>& aObjectIdArray)
+ {
+ TRACER("CGlxDataSourceMde::HandleObjectNotification()");
+ GLX_LOG_INFO3("CGlxDataSourceMde::HandleObjectNotification() aType=%d, aObjectIdArray.Count()=%d, iHarvestingOngoing=%d",
+ aType, aObjectIdArray.Count(),
+ iHarvestingOngoing);
+ if (ENotifyAdd == aType)
+ {
+ for ( TInt i = 0; i < aObjectIdArray.Count(); i++ )
+ {
+ iAddedItems.Append(aObjectIdArray[i]);
+ }
+ GLX_LOG_INFO1("ENotifyAdd - iAddedItems.Count()=%d", iAddedItems.Count());
+ }
+
+ if (ENotifyModify == aType)
+ {
+ for ( TInt i = 0; i < aObjectIdArray.Count(); i++ )
+ {
+ if (iAddedItems.Find(aObjectIdArray[i]) != KErrNotFound)
+ {
+ if (!iHarvestingOngoing)
+ {
+ GLX_LOG_INFO("ENotifyModify - Harvesting Completed - "
+ "Reset iAddedItems array");
+ iAddedItems.Reset();
+ break;
+ }
+ GLX_LOG_INFO("ENotifyModify - Id found in iAddedItems array, DO NOT PROCESS");
+ return;
+ }
+ }
+ }
+
+ GLX_LOG_INFO("ProcessUpdateArray");
+ ProcessUpdateArray(aObjectIdArray, MPXChangeEventType(aType), ETrue);
+#ifndef USE_S60_TNM
+ if(MPXChangeEventType(aType) == EMPXItemDeleted )
+ {
+ TInt count = aObjectIdArray.Count();
+ iDeletedCount += count;
+ GLX_LOG_INFO2("EMPXItemDeleted - aObjectIdArray.Count()=%d, iDeletedCount=%d",
+ count, iDeletedCount);
+ if(iDeletedCount > KGlxThumbnailCleanupAfterDeletions)
+ {
+ TRAPD(err, ThumbnailCreator().CleanupThumbnailsL(iThumbnailDatabase));
+ if(!err)
+ {
+ iDeletedCount = 0;
+ }
+ }
+ }
+
+ if(MPXChangeEventType(aType) == EMPXItemModified )
+ {
+ GLX_LOG_INFO("EMPXItemModified");
+ TRAP_IGNORE(ThumbnailCreator().CleanupThumbnailsL(iThumbnailDatabase));
+ }
+#endif
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxDataSourceMde::HandleObjectPresentNotification
+// ---------------------------------------------------------------------------
+//
+///@todo AB test this
+void CGlxDataSourceMde::HandleObjectPresentNotification(CMdESession& /*aSession*/,
+ TBool aPresent, const RArray<TItemId>& aObjectIdArray)
+ {
+ TRACER("CGlxDataSourceMde::HandleObjectPresentNotification()");
+ if (aPresent)
+ {
+ ProcessUpdateArray(aObjectIdArray, EMPXItemInserted, ETrue);
+ }
+ else
+ {
+ ProcessUpdateArray(aObjectIdArray, EMPXItemDeleted, ETrue);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxDataSourceMde::HandleRelationNotification
+// ---------------------------------------------------------------------------
+//
+///@todo AB test this
+void CGlxDataSourceMde::HandleRelationNotification(CMdESession& /*aSession*/,
+ TObserverNotificationType aType,
+ const RArray<TItemId>& aRelationIdArray)
+ {
+ TRACER("CGlxDataSourceMde::HandleRelationNotification()");
+ ProcessUpdateArray(aRelationIdArray, MPXChangeEventType(aType), EFalse);
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxDataSourceMde::HandleRelationPresentNotification
+// ---------------------------------------------------------------------------
+//
+///@todo AB test this
+void CGlxDataSourceMde::HandleRelationPresentNotification(CMdESession& /*aSession*/,
+ TBool aPresent, const RArray<TItemId>& aRelationIdArray)
+ {
+ TRACER("CGlxDataSourceMde::HandleRelationPresentNotification()");
+ if (aPresent)
+ {
+ ProcessUpdateArray(aRelationIdArray, EMPXItemInserted, EFalse);
+ }
+ else
+ {
+ ProcessUpdateArray(aRelationIdArray, EMPXItemDeleted, EFalse);
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ProcessUpdateArray
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::ProcessUpdateArray(const RArray<TItemId>& aArray,
+ TMPXChangeEventType aType, TBool aIsObject)
+ {
+ TRACER("CGlxDataSourceMde::ProcessUpdateArray(const RArray<TItemId>& aArray,TMPXChangeEventType aType, TBool aIsObject)");
+ // only need one message so process first item
+ TUpdateData update;
+ update.iId = aArray[0];
+ update.iType = aType;
+ update.iIsObject = aIsObject;
+ if( iUpdateData.Count() )
+ {
+ if( ( iUpdateData[0].iType == aType ) && ( iUpdateData[0].iIsObject ) )
+ {
+ return;
+ }
+ }
+ if( iUpdateData.Append(update) == KErrNone ) // if we can't allocate space for the update, ignore it
+ {
+ iUpdateCallback->CallBack();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CreateSession
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::CreateSession()
+ {
+ TRACER("CGlxDataSourceMde::CreateSession()")
+ TRAP_IGNORE(CreateSessionL());
+ }
+
+// ---------------------------------------------------------------------------
+// CreateSession
+// ---------------------------------------------------------------------------
+//
+TInt CGlxDataSourceMde::CreateSession(TAny* aPtr)
+ {
+ TRACER("CGlxDataSourceMde::CreateSession(TAny* aPtr)");
+ CGlxDataSourceMde* self
+ = reinterpret_cast<CGlxDataSourceMde*>( aPtr );
+ TRAP_IGNORE(self->CreateSessionL());
+ return 0;
+ }
+
+// ---------------------------------------------------------------------------
+// CreateSessionL
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::CreateSessionL()
+ {
+ TRACER("CGlxDataSourceMde::CreateSessionL()");
+ iSession = CMdESession::NewL( *this );
+ }
+
+
+// ---------------------------------------------------------------------------
+// ProcessItemUpdate
+// ---------------------------------------------------------------------------
+//
+TInt CGlxDataSourceMde::ProcessItemUpdate(TAny* aPtr)
+ {
+ TRACER("CGlxDataSourceMde::ProcessItemUpdate(TAny* aPtr)");
+ CGlxDataSourceMde* self
+ = reinterpret_cast<CGlxDataSourceMde*>( aPtr );
+ TRAP_IGNORE(self->ProcessItemUpdateL());
+ return 0;
+ }
+
+// ---------------------------------------------------------------------------
+// ProcessItemUpdateL
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::ProcessItemUpdateL()
+ {
+ TRACER("CGlxDataSourceMde::ProcessItemUpdateL()");
+ //__ASSERT_DEBUG(iUpdateData.Count(), Panic(EGlxPanicIllegalState));
+ if ( !iUpdateData.Count() || iPauseUpdate )
+ {
+ return;
+ }
+ CMPXMessage* message = CMPXMessage::NewL();
+ CleanupStack::PushL(message);
+ message->SetTObjectValueL<TInt>(KMPXMessageGeneralId, KMPXMessageIdItemChanged);
+ message->SetTObjectValueL<TMPXChangeEventType>(KMPXMessageChangeEventType,
+ iUpdateData[0].iType);
+ TMPXGeneralCategory category = EMPXNoCategory;
+ TMPXItemId id = iUpdateData[0].iId;
+
+#ifdef __USING_INTELLIGENT_UPDATE_FILTERING
+ if ( !iUpdateData[0].iIsObject )
+ {
+ TMPXGeneralCategory containerCategory = EMPXNoCategory;
+ TMPXItemId containerId;
+
+ CMdERelation* relation = iSession->GetRelationL(id);
+ if( relation )
+ {
+ TItemId rightId = relation->RightObjectId();
+ TItemId leftId = relation->LeftObjectId();
+ delete relation;
+
+ CMdEObject* contObject = iSession->GetObjectL(leftId);
+ __ASSERT_DEBUG(contObject, Panic(EGlxPanicIllegalState));
+ TContainerType container = ContainerType(contObject);
+ delete contObject;
+ __ASSERT_DEBUG(( EContainerTypeTag != container), Panic(EGlxPanicIllegalState));
+ if( EContainerTypeNotAContainer == container )
+ {
+ CMdEObject* rightObject = iSession->GetObjectL(rightId);
+ __ASSERT_DEBUG(rightObject, Panic(EGlxPanicIllegalState));
+ TContainerType rightContainer = ContainerType(rightObject);
+ delete rightObject;
+ __ASSERT_DEBUG(( EContainerTypeAlbum != rightContainer),
+ Panic(EGlxPanicIllegalState));
+ if( EContainerTypeTag == rightContainer )
+ {
+ id = leftId;
+ containerId = rightId;
+ containerCategory = EMPXTag;
+ }
+ else if( EContainerTypeNotAContainer == rightContainer )
+ {
+ User::Leave(KErrNotSupported); // Not a gallery relation.
+ }
+ }
+ else if( EContainerTypeAlbum == container)
+ {
+ id = rightId;
+ containerId = leftId;
+ containerCategory = EMPXAlbum;
+ }
+ message->SetTObjectValueL<TMPXGeneralCategory>(KGlxCollectionMessageContainerCategory,
+ containerCategory);
+ message->SetTObjectValueL<TMPXItemId>(KGlxCollectionMessageContainerId,
+ containerId);
+ }
+ else
+ {
+ // use id 0 to identify to ML that we don't know what was deleted
+ id = 0;
+ }
+ }
+
+ if ( id != 0 )
+ {
+ CMdEObject* object = iSession->GetObjectL(id);
+ if( object )
+ {
+ TContainerType container = ContainerType(object);
+ if( EContainerTypeAlbum == container)
+ {
+ category = EMPXAlbum;
+ }
+ else if( EContainerTypeTag == container)
+ {
+ category = EMPXTag;
+ }
+ else
+ {
+ TItemType item = ItemType(object);
+ if( EItemTypeImage == item)
+ {
+ category = EMPXImage;
+ }
+ else if( EItemTypeVideo == item)
+ {
+ category = EMPXVideo;
+ }
+ }
+ delete object;
+ }
+ }
+#endif // __USING_INTELLIGENT_UPDATE_FILTERING
+ message->SetTObjectValueL<TMPXGeneralCategory>(KMPXMessageMediaGeneralCategory,
+ category);
+ message->SetTObjectValueL<TMPXItemId>(KMPXMessageMediaGeneralId, id);
+ BroadcastMessage(*message);
+ CleanupStack::PopAndDestroy(message);
+ iUpdateData.Remove(0);
+ }
+
+// ---------------------------------------------------------------------------
+// ContainerType
+// ---------------------------------------------------------------------------
+//
+CGlxDataSource::TContainerType CGlxDataSourceMde::ContainerType(CMdEObject* aObject)
+ {
+ TRACER("CGlxDataSourceMde::ContainerType(CMdEObject* aObject)");
+ TContainerType containerType = EContainerTypeNotAContainer;
+
+ if( 0 == aObject->Def().Compare(*iAlbumDef) )
+ {
+ containerType = EContainerTypeAlbum;
+ }
+ else if( 0 == aObject->Def().Compare(*iTagDef) )
+ {
+ containerType = EContainerTypeTag;
+ }
+ else if( 0 == aObject->Def().Compare(*iMonthDef) )
+ {
+ containerType = EContainerTypeMonth;
+ }
+
+ return containerType;
+ }
+
+
+// ---------------------------------------------------------------------------
+// ContainerType
+// ---------------------------------------------------------------------------
+//
+CGlxDataSource::TContainerType CGlxDataSourceMde::ContainerType(CMdEObjectDef*
+ aObjectDef)
+ {
+ TRACER("CGlxDataSourceMde::ContainerType()");
+ TContainerType containerType = EContainerTypeNotAContainer;
+
+ if( 0 == aObjectDef->Compare(*iAlbumDef) )
+ {
+ containerType = EContainerTypeAlbum;
+ }
+ else if( 0 == aObjectDef->Compare(*iTagDef) )
+ {
+ containerType = EContainerTypeTag;
+ }
+ else if( 0 == aObjectDef->Compare(*iMonthDef) )
+ {
+ containerType = EContainerTypeMonth;
+ }
+
+ return containerType;
+ }
+
+// ---------------------------------------------------------------------------
+// ItemType()
+// ---------------------------------------------------------------------------
+//
+CGlxDataSource::TItemType CGlxDataSourceMde::ItemType(CMdEObject* aObject)
+ {
+ TRACER("CGlxDataSourceMde::ItemType(CMdEObject* aObject)");
+ TItemType itemType = EItemTypeNotAnItem;
+
+ if( 0 == aObject->Def().Compare(*iImageDef) )
+ {
+ itemType = EItemTypeImage;
+ }
+ else if(0 == aObject->Def().Compare(*iVideoDef) )
+ {
+ itemType = EItemTypeVideo;
+ }
+
+ return itemType;
+ }
+
+// ---------------------------------------------------------------------------
+// PrepareMonthsL()
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::PrepareMonthsL()
+ {
+ TRACER("CGlxDataSourceMde::PrepareMonthsL()");
+ TTime month(0);
+ iFirstMonth = month;
+ }
+
+// ---------------------------------------------------------------------------
+// GetMonthIdL()
+// ---------------------------------------------------------------------------
+//
+const TGlxMediaId CGlxDataSourceMde::GetMonthIdL(const TTime& aMonth)
+ {
+ TRACER("CGlxDataSourceMde::GetMonthIdL()");
+ TTime monthStart = iFirstMonth + aMonth.MonthsFrom(iFirstMonth);
+ const TTimeIntervalMonths KGlxOneMonth = 1;
+ const TTimeIntervalMicroSeconds KGlxOneMicrosecond = 1;
+
+ TGlxMediaId monthId;
+ TInt monthIndex = iMonthArray.Find(monthStart);
+ if( monthIndex != KErrNotFound )
+ {
+ monthId = iMonthList[monthIndex];
+ }
+ else
+ {
+ _LIT(KGlxMonthTitleFormat, "%F%Y%M%D:");
+ const TInt KGlxMonthTitleLength = 12;
+ TBuf<KGlxMonthTitleLength> title;
+ monthStart.FormatL(title, KGlxMonthTitleFormat);
+
+ CMdEObject* month = iSession->GetObjectL(title);
+ if( month )
+ {
+ monthId = (TGlxMediaId)month->Id();
+ iMonthArray.AppendL(monthStart);
+ iMonthList.AppendL(monthId);
+ delete month;
+ }
+ else
+ {
+ TTime monthEnd = monthStart + KGlxOneMonth - KGlxOneMicrosecond;
+ month = iSession->NewObjectLC(*iMonthDef, title);
+
+ // A title property def of type text is required.
+ CMdEPropertyDef& titlePropertyDef = iObjectDef->GetPropertyDefL(
+ KPropertyDefNameTitle);
+ if (titlePropertyDef.PropertyType() != EPropertyText)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ // Set the object title.
+ month->AddTextPropertyL (titlePropertyDef, title);
+
+ // A size property is required.
+ CMdEPropertyDef& sizePropertyDef = iObjectDef->GetPropertyDefL(
+ KPropertyDefNameSize);
+ if (sizePropertyDef.PropertyType() != EPropertyUint32)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ month->AddUint32PropertyL(sizePropertyDef,0);
+
+
+ // A creation date property is required.
+ CMdEPropertyDef& creationDateDef = iObjectDef->GetPropertyDefL(
+ KPropertyDefNameCreationDate);
+ if (creationDateDef.PropertyType() != EPropertyTime)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ month->AddTimePropertyL(creationDateDef, monthStart);
+
+ // A last modified date property is required.
+ CMdEPropertyDef& lmDateDef = iObjectDef->GetPropertyDefL(
+ KPropertyDefNameLastModifiedDate);
+ if (lmDateDef.PropertyType() != EPropertyTime)
+ {
+ User::Leave(KErrCorrupt);
+ }
+
+ month->AddTimePropertyL(lmDateDef, monthEnd);
+
+ monthId = (TGlxMediaId)iSession->AddObjectL(*month);
+ CleanupStack::PopAndDestroy(month);
+ iMonthArray.AppendL(monthStart);
+ iMonthList.AppendL(monthId);
+ }
+ }
+ return monthId;
+ }
+
+// ---------------------------------------------------------------------------
+// SameMonth
+// ---------------------------------------------------------------------------
+//
+TBool CGlxDataSourceMde::SameMonth(const TTime& aOldDate, const TTime& aNewDate)
+ {
+ TRACER("CGlxDataSourceMde::SameMonth(const TTime& aOldDate, const TTime& aNewDate)")
+ return ( aOldDate.MonthsFrom(iFirstMonth) == aNewDate.MonthsFrom(iFirstMonth) );
+ }
+
+// ---------------------------------------------------------------------------
+// ContainerIsLeft
+// ---------------------------------------------------------------------------
+//
+TBool CGlxDataSourceMde::ContainerIsLeft(CMdEObjectDef& aObjectDef)
+ {
+ TRACER("CGlxDataSourceMde::ContainerIsLeft(CMdEObjectDef& aObjectDef)")
+ TBool containerLeft = EFalse;
+ if ( 0 == aObjectDef.Compare(AlbumDef()) )
+ {
+ containerLeft = ETrue;
+ }
+ return containerLeft;
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxDataSource
+// TaskCompletedL
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::TaskCompletedL()
+ {
+ iPauseUpdate = EFalse;
+ iUpdateCallback->CallBack();
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxDataSource
+// TaskStartedL
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::TaskStartedL()
+ {
+ iPauseUpdate = ETrue;
+ }
+
+#ifdef USE_S60_TNM
+void CGlxDataSourceMde::FetchThumbnailL(CGlxRequest* aRequest,
+ MThumbnailFetchRequestObserver& aObserver)
+ {
+ TRACER("CGlxDataSourceMde::FetchThumbnailL()");
+#ifdef _DEBUG
+ iStartTime.HomeTime(); // Get home time
+#endif
+
+ iTnFetchObserver = &aObserver;
+
+ CGlxThumbnailRequest* request = static_cast<CGlxThumbnailRequest*>(aRequest);
+
+ TGlxThumbnailRequest tnReq;
+ request->ThumbnailRequest(tnReq);
+ User::LeaveIfNull(request->ThumbnailInfo());
+
+ iTnHandle = tnReq.iBitmapHandle;
+ iMediaId = tnReq.iId;
+ if (tnReq.iSizeClass.iWidth < KMaxGridThumbnailWidth)
+ {
+ iTnEngine->SetFlagsL(CThumbnailManager::ECropToAspectRatio);
+ iTnEngine->SetThumbnailSizeL(EGridThumbnailSize);
+ GLX_LOG_INFO("CGlxDataSourceMde::FetchThumbnailL() - Fetch TN attrib -"
+ " EGridThumbnailSize");
+ }
+ else
+ {
+ iTnEngine->SetFlagsL(CThumbnailManager::EDefaultFlags);
+ iTnEngine->SetThumbnailSizeL(EFullScreenThumbnailSize);
+ GLX_LOG_INFO("CGlxDataSourceMde::FetchThumbnailL() - Fetch TN attrib - "
+ "EFullScreenThumbnailSize");
+ }
+
+ if (tnReq.iPriorityMode == TGlxThumbnailRequest::EPrioritizeQuality)
+ {
+ iTnEngine->SetQualityPreferenceL(CThumbnailManager::EOptimizeForQuality);
+ GLX_LOG_INFO("CGlxDataSourceMde::FetchThumbnailL() - Fetch TN attrib -"
+ " EOptimizeForQuality");
+ }
+ else
+ {
+ iTnEngine->SetQualityPreferenceL(CThumbnailManager::EOptimizeForQualityWithPreview);
+ GLX_LOG_INFO("CGlxDataSourceMde::FetchThumbnailL() - Fetch TN attrib -"
+ " EOptimizeForQualityWithPreview");
+ }
+
+ CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC(
+ request->ThumbnailInfo()->FilePath(), 0);
+ iTnThumbnailCbId = iTnEngine->GetThumbnailL(*source);
+ CleanupStack::PopAndDestroy();
+
+ iTnRequestInProgress = ETrue;
+ }
+
+TInt CGlxDataSourceMde::CancelFetchThumbnail()
+ {
+ TRACER("CGlxDataSourceMde::CancelFetchThumbnail");
+ TInt ret = KErrNone;
+ if (iTnRequestInProgress)
+ {
+ ret = iTnEngine->CancelRequest(iTnThumbnailCbId);
+ iTnRequestInProgress = EFalse;
+ iTnFetchObserver->ThumbnailFetchComplete(KErrCancel,EFalse);
+ }
+ return ret;
+ }
+
+// Called when preview thumbnail is created
+void CGlxDataSourceMde::ThumbnailPreviewReady(MThumbnailData& aThumbnail,
+ TThumbnailRequestId aId)
+ {
+ TRACER("CGlxDataSourceMde::ThumbnailPreviewReady()");
+
+ TInt error = KErrNotSupported;
+ if (aThumbnail.Bitmap() != NULL)
+ {
+ GLX_DEBUG1("CGlxDataSourceMde::ThumbnailPreviewReady preview aval");
+ error = KErrNone;
+ }
+ //This function is called number of times as a callback ,
+ //hence not trapping the leaving function which costs time and memory.
+ //Ignoring this for code scanner warnings - Leaving functions called in non-leaving functions.
+ ThumbnailReadyL(error, aThumbnail, aId, EFalse);
+ }
+
+// Called when real thumbnail is created
+void CGlxDataSourceMde::ThumbnailReady(TInt aError,
+ MThumbnailData& aThumbnail, TThumbnailRequestId aId)
+ {
+ TRACER("CGlxDataSourceMde::ThumbnailReady");
+ GLX_DEBUG2("GlxDataSourceMde::ThumbnailReady aError=%d", aError);
+ //This function is called number of times as a callback ,
+ //hence not trapping the leaving function which costs time and memory.
+ //Ignoring this for code scanner warnings - Leaving functions called in non-leaving functions.
+ ThumbnailReadyL(aError,aThumbnail, aId, ETrue);
+ }
+
+// ---------------------------------------------------------------------------
+// ThumbnailReadyL
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::ThumbnailReadyL(TInt aError,
+ MThumbnailData& aThumbnail, TThumbnailRequestId aId, TBool aQuality)
+ {
+ TRACER("CGlxDataSourceMde::ThumbnailReadyL()");
+ GLX_DEBUG3("CGlxDataSourceMde::ThumbnailReadyL aError=%d, aQuality=%d",
+ aError, aQuality);
+#ifdef _DEBUG
+ iStopTime.HomeTime(); // Get home time
+ GLX_DEBUG2("=>CGlxDataSourceMde::ThumbnailReadyL - TN Fetch took <%d> us",
+ (TInt)iStopTime.MicroSecondsFrom(iStartTime).Int64());
+#endif
+
+ if (iTnThumbnailCbId == aId)
+ {
+ if (aError == KErrNone && iTnHandle)
+ {
+ if (iTnHandle == KGlxMessageIdBackgroundThumbnail)
+ {
+ BackgroundThumbnailMessageL(iMediaId, TSize(), aError);
+ }
+ else
+ {
+ delete iTnThumbnail;
+ iTnThumbnail = NULL;
+ iTnThumbnail = aThumbnail.DetachBitmap();
+
+ delete iThumbnail;
+ iThumbnail = NULL;
+ iThumbnail = new (ELeave) CFbsBitmap();
+ User::LeaveIfError( iThumbnail->Duplicate(iTnHandle));
+ User::LeaveIfError(iThumbnail->Resize(iTnThumbnail->SizeInPixels()));
+ CFbsBitmapDevice* device = CFbsBitmapDevice::NewL(iThumbnail);
+ CleanupStack::PushL(device );
+ CFbsBitGc* context = NULL;
+ User::LeaveIfError(device->CreateContext(context));
+ CleanupStack::PushL(context);
+ context->BitBlt( TPoint(), iTnThumbnail);
+ CleanupStack::PopAndDestroy(context);
+ CleanupStack::PopAndDestroy(device);
+ }
+ }
+ }
+
+ if (iTnFetchObserver && iTnRequestInProgress)
+ {
+ iTnFetchObserver->ThumbnailFetchComplete(aError, aQuality);
+ iTnHandle = KErrNone;
+ iTnRequestInProgress = EFalse;
+ }
+ }
+#endif
+
+// ---------------------------------------------------------------------------
+// CGlxDataSourceMde
+// HarvestingUpdated
+// ---------------------------------------------------------------------------
+//
+void CGlxDataSourceMde::HarvestingUpdated(
+ HarvesterEventObserverType /*aHEObserverType*/,
+ HarvesterEventState aHarvesterEventState,
+ TInt /*aItemsLeft*/)
+ {
+ TRACER("void CGlxDataSourceMde::HarvestingUpdated()");
+ GLX_LOG_INFO1("CGlxDataSourceMde::HarvestingUpdated() aHarvesterEventState=%d",
+ aHarvesterEventState);
+
+ switch(aHarvesterEventState)
+ {
+ case EHEStateStarted:
+ GLX_LOG_INFO("CGlxDataSourceMde::HarvestingUpdated() - EHEStateStarted");
+ case EHEStateResumed:
+ case EHEStateHarvesting:
+ {
+ iHarvestingOngoing = ETrue;
+ }
+ break;
+ case EHEStatePaused:
+ case EHEStateFinished:
+ {
+ iHarvestingOngoing = EFalse;
+ GLX_LOG_INFO("CGlxDataSourceMde::HarvestingUpdated() - EHEStateFinished");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+void CGlxDataSourceMde::ShutdownNotification(TInt aShutdownState)
+ {
+ TRACER("void CGlxDataSourceMde::ShutdownNotification(TInt aShutdownState)")
+ GLX_DEBUG2("CGlxDataSourceMde::ShutdownNotification(TInt aShutdownState) aShutdownState = %d", aShutdownState);
+
+ // iDataSourceReady is set to false if we have lost an MDS session.
+ // a ShutdownNotification with aaShutdownState == 0 means that MDS has restarted. So this is the time to recreate a session with MDS.
+ if ( (!iDataSourceReady) && (0 == aShutdownState) )
+ {
+ CreateSession();
+ }
+ }