diff -r 2bb96f4ecad8 -r 8e7494275d3a omads/omadsextensions/adapters/mediads/src/cmdemanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omads/omadsextensions/adapters/mediads/src/cmdemanager.cpp Tue Aug 31 15:05:37 2010 +0300 @@ -0,0 +1,741 @@ +/* +* Copyright (c) 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: CMdEManager implementation +* +*/ + + +#include "cmdemanager.h" +#include + +#include + +#include "logger.h" + +// Warning: #940-D: missing return statement at end of non-void function +#pragma diag_remark 940 + +CMdEManager::CMdEManager( MMdEManagerObserver& aObserver ) : + iObserver(aObserver) + { + } + + +CMdEManager* CMdEManager::NewL( MMdEManagerObserver& aObserver ) + { + CMdEManager* self = new (ELeave) CMdEManager( aObserver ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +void CMdEManager::ConstructL() + { + TRACE_FUNC; + iMde = CMdESession::NewL( *this ); + } + + +CMdEManager::~CMdEManager() + { + TRACE_FUNC; + Cancel(); // Cancel any request, if outstanding + delete iAlbumQuery; + delete iObjectQuery; + delete iContainmentQuery; + delete iMde; + + iAlbumsInProgress.ResetAndDestroy(); + iAlbums.ResetAndDestroy(); + } + +void CMdEManager::GetAlbumsL() + { + TRACE_FUNC_ENTRY; + iAlbumsInProgress.ResetAndDestroy(); + iAlbums.ResetAndDestroy(); + if ( !iMde ) + { + LOGGER_WRITE("Session was not ready!"); + iState = EUninitialized; + iMde = CMdESession::NewL( *this ); + } + + if ( iState == EUninitialized) + { + LOGGER_WRITE("Starting processing albums after session is ready"); + iState = EWaitingToEnumerateAlbums; + } + else if ( iState == EIdle ) + { + StartProcessingAlbumsL(); + } + else + { + LOGGER_WRITE_1("Wrong state: %d", iState); + User::Leave( KErrGeneral ); + } + + TRACE_FUNC_EXIT; + } + +const CPlaylistItem& CMdEManager::AlbumL( TInt aAlbumId ) const + { + for ( TInt i=0; iId() == aAlbumId ) + { + LOGGER_WRITE("Album found"); + return *iAlbums[i]; + } + } + LOGGER_WRITE_1("CMdEManager::AlbumL - aAlbumId %d does not exist - Leaving KErrNotFound", aAlbumId); + User::Leave( KErrNotFound ); + } + +void CMdEManager::CreateAlbumL( CPlaylistItem& aAlbum ) + { + TRACE_FUNC_ENTRY; + if ( !iMde || iState != EIdle ) + { + LOGGER_WRITE("Not ready!"); + User::Leave( KErrNotReady ); + } + CMdENamespaceDef& defaultNamespaceDef = iMde->GetDefaultNamespaceDefL(); + CMdEObjectDef& albumObjDef = defaultNamespaceDef.GetObjectDefL( MdeConstants::Album::KAlbumObject ); + + CMdEPropertyDef& titlePropDef = albumObjDef.GetPropertyDefL( MdeConstants::Object::KTitleProperty ); + + // Validate album name + TInt albumLength = aAlbum.Title().Length(); + if ( albumLength < titlePropDef.MinTextLengthL() || + albumLength > titlePropDef.MaxTextLengthL() ) + { + LOGGER_WRITE("Album length is not on valid range!"); + User::Leave( KErrBadName ); + } + + CMdEObject* albumObject = iMde->NewObjectLC( albumObjDef, KNullDesC ); + + CMdEPropertyDef& sizePropDef = albumObjDef.GetPropertyDefL( MdeConstants::Object::KSizeProperty ); + albumObject->AddUint32PropertyL(sizePropDef, 0); + CMdEPropertyDef& creationDatePropDef = albumObjDef.GetPropertyDefL( MdeConstants::Object::KCreationDateProperty ); + CMdEPropertyDef& lastModifiedDatePropDef = albumObjDef.GetPropertyDefL( MdeConstants::Object::KLastModifiedDateProperty ); + + TTime timeDate; + timeDate.UniversalTime(); + + albumObject->AddTimePropertyL( creationDatePropDef, timeDate ); + albumObject->AddTimePropertyL( lastModifiedDatePropDef, timeDate ); + + CMdEPropertyDef& typePropDef = albumObjDef.GetPropertyDefL( MdeConstants::Object::KItemTypeProperty ); + albumObject->AddTextPropertyL( typePropDef,MdeConstants::Album::KAlbumItemType ); + + albumObject->AddTextPropertyL( titlePropDef, aAlbum.Title() ); + TItemId newAlbumId = iMde->AddObjectL( *albumObject ); + + CleanupStack::PopAndDestroy( albumObject ); + + if ( newAlbumId == KNoId ) + { + LOGGER_WRITE("Adding album failed!"); + User::Leave( KErrGeneral ); + } + LOGGER_WRITE_1("New almbum created, id: %d", newAlbumId); + + CMdERelationDef& relationDef = defaultNamespaceDef.GetRelationDefL( MdeConstants::Relations::KContains ); + TMdEObject mediaObject; + RPointerArray relations; + CleanupResetAndDestroyPushL( relations); + for ( TInt i=0; iCheckObjectL( mediaObject, aAlbum.ItemAt(i) )); + LOGGER_WRITE_1("url: %S", &aAlbum.ItemAt(i)); + LOGGER_WRITE_1("CheckObjectL err: %d", err); + if ( !err ) + { + LOGGER_WRITE_1("object def: %S", &mediaObject.DefL().Name()); + if ( mediaObject.DefL().Name().Compare( MdeConstants::Image::KImageObject ) == 0 + || mediaObject.DefL().Name().Compare( MdeConstants::Video::KVideoObject ) == 0 ) + { + CMdERelation* relation = iMde->NewRelationL( relationDef, newAlbumId, mediaObject.Id() ); + relations.AppendL( relation ); + } + else + { + LOGGER_WRITE("type not supported"); + } + } + } + + if ( relations.Count() > 0 ) + { + TInt err = iMde->AddItemsL( relations ); + LOGGER_WRITE_1("AddItemsL first err: %d", err); + } + + CleanupStack::PopAndDestroy( &relations ); + + aAlbum.SetId( newAlbumId ); + + TRACE_FUNC_EXIT; + } + +void CMdEManager::ReplaceAlbumL( TInt aAlbumId, CPlaylistItem& aAlbum ) + { + TRACE_FUNC_ENTRY; + if ( !iMde || iState != EIdle ) + { + LOGGER_WRITE("Not ready!"); + User::Leave( KErrNotReady ); + } + // get old album from local cache and check do we need to change album title + const CPlaylistItem& oldAlbum = AlbumL( aAlbumId ); + CMdENamespaceDef& defaultNamespaceDef = iMde->GetDefaultNamespaceDefL(); + if ( oldAlbum.Title().Compare( aAlbum.Title() ) != 0 ) + { + // Title changed, open item from MdE and update it + + CMdEObjectDef& albumObjDef = defaultNamespaceDef.GetObjectDefL( MdeConstants::Album::KAlbumObject ); + + CMdEPropertyDef& titlePropDef = albumObjDef.GetPropertyDefL( + MdeConstants::Object::KTitleProperty ); + + // Validate album name + TInt albumLength = aAlbum.Title().Length(); + if ( albumLength < titlePropDef.MinTextLengthL() || + albumLength > titlePropDef.MaxTextLengthL() ) + { + LOGGER_WRITE("Album length is not on valid range!"); + User::Leave( KErrBadName ); + } + + CMdEObject* albumObject = iMde->OpenObjectL( aAlbumId, albumObjDef ); + + CMdEProperty* titleProp = NULL; + TInt index = albumObject->Property( titlePropDef, titleProp ); + if ( index == KErrNotFound ) + { + LOGGER_WRITE("Cannot find title property"); + User::Leave( KErrCorrupt ); + } + + LOGGER_WRITE("Change title property"); + titleProp->SetTextValueL( aAlbum.Title() ); + + CMdEPropertyDef& lastModDatePropDef = albumObjDef.GetPropertyDefL( + MdeConstants::Object::KLastModifiedDateProperty ); + CMdEProperty* lastModDateProp = NULL; + index = albumObject->Property( lastModDatePropDef, lastModDateProp ); + + if ( index == KErrNotFound ) + { + LOGGER_WRITE("Cannot find lastModDateProp property"); + User::Leave( KErrCorrupt ); + } + + TTime now; + now.UniversalTime(); + lastModDateProp->SetTimeValueL( now ); + + iMde->CommitObjectL( *albumObject ); + } + + // Update album and content relations + // Search added relations + CMdERelationDef& containsRelationDef = defaultNamespaceDef.GetRelationDefL( MdeConstants::Relations::KContains ); + TMdEObject mediaObject; + RPointerArray addedRelations; + CleanupResetAndDestroyPushL( addedRelations); + for ( TInt i=0; i< aAlbum.ItemCount(); i++) + { + TInt index(KErrNotFound); + TInt foundRes = oldAlbum.FindItem( aAlbum.ItemAt(i) ,index ); + if ( foundRes != 0 ) + { + // Item not found for old album -> Added relation + // Find object by uri + TRAPD( err, iMde->CheckObjectL( mediaObject, aAlbum.ItemAt(i) )); + LOGGER_WRITE_1("url: %S", &aAlbum.ItemAt(i)); + LOGGER_WRITE_1("CheckObjectL err: %d", err); + if ( !err ) + { + LOGGER_WRITE_1("object def: %S", &mediaObject.DefL().Name()); + if ( mediaObject.DefL().Name().Compare( MdeConstants::Image::KImageObject ) == 0 + || mediaObject.DefL().Name().Compare( MdeConstants::Video::KVideoObject ) == 0 ) + { + CMdERelation* relation = iMde->NewRelationL( containsRelationDef, aAlbumId, mediaObject.Id() ); + addedRelations.AppendL( relation ); + } + else + { + LOGGER_WRITE("type not supported"); + } + } + + } + } + if ( addedRelations.Count() > 0 ) + { + TInt err = iMde->AddItemsL( addedRelations ); + LOGGER_WRITE_1("AddItemsL first err: %d", err); + } + + CleanupStack::PopAndDestroy( &addedRelations ); + + // search removed relations + if ( iContainmentQuery ) + { + delete iContainmentQuery; + iContainmentQuery = NULL; + } + iContainmentQuery = iMde->NewRelationQueryL( defaultNamespaceDef, this ); + + CMdELogicCondition& rootCondition = iContainmentQuery->Conditions(); + CMdERelationCondition& relationCondition = + rootCondition.AddRelationConditionL(containsRelationDef, + ERelationConditionSideLeft); // "AND" + + CMdELogicCondition& leftCondition = relationCondition.LeftL(); + CMdELogicCondition& rightCondition = relationCondition.RightL(); + + leftCondition.AddObjectConditionL( aAlbumId ); + + CMdELogicCondition& objectDefLogicCond = + rightCondition.AddLogicConditionL( ELogicConditionOperatorOr); + + TBool removingRelationsNeeded( EFalse ); + for ( TInt i=0; i< oldAlbum.ItemCount(); i++) + { + TInt index(KErrNotFound); + TInt foundRes = aAlbum.FindItem( oldAlbum.ItemAt(i) ,index ); + if ( foundRes != 0 ) + { + removingRelationsNeeded = ETrue; + // Item not found from new album -> Removed relation (add uri to search condition) + LOGGER_WRITE_1("relation to be removed, uri: %S", &oldAlbum.ItemAt(i) ); + objectDefLogicCond.AddObjectConditionL( EObjectConditionCompareUri, oldAlbum.ItemAt(i) ); + } + } + + if ( removingRelationsNeeded ) + { + // find all removed relation ID:s. HandleRelationQueryCompleted will be called when ready. + iContainmentQuery->SetResultMode( EQueryResultModeId ); + iContainmentQuery->FindL(); + iState = EReplacingAlbum; + } + else + { + // All done + iState = EIdle; + iObserver.AlbumReplaced( KErrNone ); + } + + TRACE_FUNC_EXIT; + } + +void CMdEManager::DeleteAlbumL( TInt aAlbumId ) + { + TRACE_FUNC_ENTRY; + if ( !iMde || iState != EIdle ) + { + LOGGER_WRITE("Not ready!"); + User::Leave( KErrNotReady ); + } + + CMdENamespaceDef& defaultNamespaceDef = iMde->GetDefaultNamespaceDefL(); + CMdEObjectDef& albumObjDef = defaultNamespaceDef.GetObjectDefL( MdeConstants::Album::KAlbumObject ); + + CMdEObject* albumObject = iMde->GetObjectL( aAlbumId, albumObjDef ); + + CMdEPropertyDef& typePropDef = albumObjDef.GetPropertyDefL( + MdeConstants::Album::KTypeProperty ); + + CMdEProperty* typeProp = NULL; + TInt index = albumObject->Property( typePropDef, typeProp ); + if ( index != KErrNotFound ) + { + TUint16 typeVal = typeProp->Uint16ValueL(); + if ( typeVal == MdeConstants::Album::EAlbumSystemFavourite ) + { + LOGGER_WRITE("Item type is EAlbumSystemFavourite, deletion not allowed!"); + User::Leave( KErrPermissionDenied ); + } + } + + TItemId removedId(KNoId); + removedId = iMde->RemoveObjectL( aAlbumId ); + if ( removedId == KNoId ) + { + LOGGER_WRITE("Deletion failed!"); + User::Leave( KErrNotFound ); + } + + TRACE_FUNC_EXIT; + } + +void CMdEManager::StartProcessingAlbumsL() + { + TRACE_FUNC_ENTRY; + CMdENamespaceDef& defaultNamespaceDef = iMde->GetDefaultNamespaceDefL(); + CMdEObjectDef& albumObjDef = defaultNamespaceDef.GetObjectDefL( MdeConstants::Album::KAlbumObject ); + if ( iAlbumQuery ) + { + delete iAlbumQuery; + iAlbumQuery = NULL; + } + // query objects with object definition "Album" + iAlbumQuery = iMde->NewObjectQueryL( defaultNamespaceDef, albumObjDef, this ); + + // Add order + CMdEObjectDef& objdef = defaultNamespaceDef.GetObjectDefL( MdeConstants::Object::KBaseObject ); + CMdEPropertyDef& propDef = objdef.GetPropertyDefL( MdeConstants::Object::KTitleProperty ); + TMdEOrderRule rule( propDef, ETrue ); + iAlbumQuery->AppendOrderRuleL( rule ); + + iAlbumQuery->FindL(); + + iState = EEnumeratingAlbums; + + TRACE_FUNC_EXIT; + } + + +void CMdEManager::FindItemsOnAlbumL( TItemId aAlbumObjectId ) + { + TRACE_FUNC_ENTRY; + if ( !iMde ) + { + LOGGER_WRITE("Session was not ready!"); + User::Leave( KErrNotReady ); + } + CMdENamespaceDef& defaultNamespaceDef = iMde->GetDefaultNamespaceDefL(); + CMdEObjectDef& objDef = defaultNamespaceDef.GetObjectDefL( MdeConstants::Object::KBaseObject ); + + CMdEPropertyDef& titlePropDef = objDef.GetPropertyDefL( MdeConstants::Object::KTitleProperty ); + + if ( iObjectQuery ) + { + delete iObjectQuery; + iObjectQuery = NULL; + } + iObjectQuery = iMde->NewObjectQueryL( defaultNamespaceDef, objDef, this ); + + // get only "Title" property + iObjectQuery->AddPropertyFilterL( &titlePropDef ); + + CMdEObjectDef& objdef = defaultNamespaceDef.GetObjectDefL( MdeConstants::Object::KBaseObject ); + CMdEPropertyDef& propDef = objdef.GetPropertyDefL( MdeConstants::Object::KTitleProperty ); + + CMdELogicCondition& rootCond = iObjectQuery->Conditions(); + + CMdERelationDef& containsRelDef = defaultNamespaceDef.GetRelationDefL( + MdeConstants::Relations::KContains ); + + // query right side objects from relations + CMdERelationCondition& relCond = rootCond.AddRelationConditionL( + containsRelDef, ERelationConditionSideRight ); + + // left side object of relation must be defined album object + CMdELogicCondition& leftRelCond = relCond.LeftL(); + leftRelCond.AddObjectConditionL( aAlbumObjectId ); + + iObjectQuery->FindL(); + + TRACE_FUNC_EXIT; + } + +/** + * Called to notify the observer that opening the session has been + * completed and, if the opening succeeded, the session is ready for use. + * + * @param aSession session + * @param aError KErrNone, if opening the session succeeded; + * or one of the system-wide error codes, if opening the + * session failed + */ +void CMdEManager::HandleSessionOpened(CMdESession& /*aSession*/, TInt aError) + { + TRACE_FUNC_ENTRY; + if ( !aError ) + { + LOGGER_WRITE("Session opened"); + if ( iState == EWaitingToEnumerateAlbums ) + { + iState = EIdle; + TRAPD(err, StartProcessingAlbumsL()); + if ( err ) + { + iObserver.AlbumsReaded( err ); + } + } + else + { + iState = EIdle; + } + } + else + { + LOGGER_WRITE_1("Error happened on opening session, aError: %d", aError); + if ( iState == EWaitingToEnumerateAlbums ) + { + iObserver.AlbumsReaded( aError ); + } + iState = EUninitialized; + delete iMde; + iMde = NULL; + } + TRACE_FUNC_EXIT; + } + +/** + * Called to notify the observer about errors, which are not a direct + * consequence of the operations initiated by the client but caused by + * some external source (e.g., other clients). The error cannot be + * recovered and all on-going operations initiated by the client have been + * aborted. Any attempts to continue using the session will cause a panic. + * The client should close the session immediately and try to open a new + * session, if it needs to continue using the metadata engine. + * + * @param aSession session + * @param aError one of the system-wide error codes + */ +void CMdEManager::HandleSessionError(CMdESession& /*aSession*/, TInt aError) + { + // Something went wrong. Handle the error and delete the old session. + LOGGER_WRITE_1("CMdEManager::HandleSessionError - aError: %d", aError) + iState = EUninitialized; + delete iMde; + iMde = NULL; + } + +/** + * Called to notify the observer that new results have been received + * in the query. + * + * @param aQuery Query instance that received new results. + * @param aFirstNewItemIndex Index of the first new item that was added + * to the result item array. + * @param aNewItemCount Number of items added to the result item + * array. + */ +void CMdEManager::HandleQueryNewResults(CMdEQuery& /*aQuery*/, + TInt /*aFirstNewItemIndex*/, + TInt /*aNewItemCount*/) + { + } + +void CMdEManager::ProcessNextAlbumL() + { + TRACE_FUNC_ENTRY; + if ( iAlbumsInProgress.Count() == 0 ) + { + LOGGER_WRITE("All ready"); + // all ready + return; + } + + FindItemsOnAlbumL( iAlbumsInProgress[0]->Id() ); + + TRACE_FUNC_EXIT; + } + + +/** + * Called to notify the observer that the query has been completed, + * or that an error has occured. + * + * @param aQuery Query instance. + * @param aError KErrNone, if the query was completed + * successfully. Otherwise one of the system-wide error + * codes. + */ +void CMdEManager::HandleQueryCompleted(CMdEQuery& aQuery, TInt aError) + { + TRACE_FUNC_ENTRY; + TInt err( aError ); + + if ( iState == EEnumeratingAlbums ) + { + CMdEObjectQuery& query = (CMdEObjectQuery&)aQuery; + if ( !err && &aQuery == iAlbumQuery ) + { + LOGGER_WRITE("Album query"); + TRAP( err, HandleAlbumQueryCompletedL( query )); + } + else if ( !err && &aQuery == iObjectQuery ) + { + LOGGER_WRITE("Object query"); + TRAP( err, HandleObjectQueryCompletedL( query )); + } + else + { + LOGGER_WRITE("unknown query or error happened"); + } + + if ( err ) + { + LOGGER_WRITE_1("Error happened: %d", err); + iState = EIdle; + iAlbumsInProgress.ResetAndDestroy(); + iAlbums.ResetAndDestroy(); + iObserver.AlbumsReaded( err ); + } + } + else if ( iState == EReplacingAlbum ) + { + if ( !err && &aQuery == iContainmentQuery ) + { + LOGGER_WRITE("relation query"); + CMdERelationQuery& query = (CMdERelationQuery&)aQuery; + TRAP( err, HandleRelationQueryCompletedL( query )); + } + + iState = EIdle; + iObserver.AlbumReplaced( err ); + + } + TRACE_FUNC_EXIT; + } + + +// ----------------------------------------------------------------------------- +// CMdEManager::HandleAlbumQueryCompletedL +// Callback function for find all albums. Save albums to iAlbumsInProgress array +// and start collecting objects on each album. +// ----------------------------------------------------------------------------- +void CMdEManager::HandleAlbumQueryCompletedL( CMdEObjectQuery& aQuery ) + { + TRACE_FUNC_ENTRY; + // clear old items + iAlbumsInProgress.ResetAndDestroy(); + iAlbums.ResetAndDestroy(); + + for ( TInt i = 0; i < aQuery.Count(); i++ ) + { + CPlaylistItem* albumItem = CPlaylistItem::NewLC(); + CMdEObject& object = aQuery.Result(i); + LOGGER_WRITE_1("Id: %d", object.Id()); + albumItem->SetId( object.Id() ); + + CMdEPropertyDef& titlePropDef = object.Def().GetPropertyDefL( MdeConstants::Object::KTitleProperty ); + + CMdEProperty* titleProp = NULL; + TInt index = object.Property( titlePropDef, titleProp ); + if ( index != KErrNotFound ) + { + const TDesC& title = titleProp->TextValueL(); + LOGGER_WRITE_1("Title: %S", &title); + albumItem->SetTitleL( title ); + } + else + { + // not found, might be default album + albumItem->SetTitleL( object.Uri() ); + } + + LOGGER_WRITE(""); + iAlbumsInProgress.AppendL( albumItem ); + CleanupStack::Pop( albumItem ); + } + + if ( aQuery.Count() > 0 ) + { + // Start processing albums + ProcessNextAlbumL(); + } + else + { + // no albums + iObserver.AlbumsReaded( KErrNone ); + } + TRACE_FUNC_EXIT; + } + +void CMdEManager::HandleObjectQueryCompletedL( CMdEObjectQuery& aQuery ) + { + if ( !iAlbumsInProgress.Count() ) + { + LOGGER_WRITE("Error! No items on iAlbumsInProgress"); + User::Leave( KErrGeneral ); + } + for ( TInt i = 0; i < aQuery.Count(); i++ ) + { + CMdEObject& object = aQuery.Result(i); + iAlbumsInProgress[0]->AddItemL( object.Uri() ); + } + iAlbums.AppendL( iAlbumsInProgress[0] ); + iAlbumsInProgress.Remove( 0 ); + if ( iAlbumsInProgress.Count() > 0) + { + ProcessNextAlbumL(); + } + else + { + // all albums processed + iState = EIdle; + iObserver.AlbumsReaded( KErrNone ); + } + } + +void CMdEManager::HandleRelationQueryCompletedL( CMdERelationQuery& aQuery ) + { + TRACE_FUNC_ENTRY; + const RArray& res = aQuery.ResultIds(); + LOGGER_WRITE_1("founded relations count: %d", res.Count()) + for (TInt i=0; i removed; + CMdENamespaceDef& defaultNameSpace = iMde->GetDefaultNamespaceDefL(); + iMde->RemoveRelationsL( aQuery.ResultIds(),removed, &defaultNameSpace); + LOGGER_WRITE_1("Removed relations count: %d", removed.Count()) + for (TInt i=0; iCancel()"); + iAlbumQuery->Cancel(); + } + if ( iObjectQuery ) + { + LOGGER_WRITE("iObjectQuery->Cancel()"); + iObjectQuery->Cancel(); + } + if ( iContainmentQuery ) + { + LOGGER_WRITE("iContainmentQuery->Cancel()"); + iContainmentQuery->Cancel(); + } + TRACE_FUNC_EXIT; + }