diff -r 16e4b9007960 -r f5508c13dfe0 bluetoothappprofiles/avrcp/mediabrowseapi/src/remconmediabrowsetargetbase.cpp --- a/bluetoothappprofiles/avrcp/mediabrowseapi/src/remconmediabrowsetargetbase.cpp Wed Oct 13 13:15:31 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1295 +0,0 @@ -// Copyright (c) 2008-2010 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: -// - - - -/** - @file - @internalComponent - @released -*/ - -#include -#include -#include -#include -#include -#include "mediabrowse.h" -#include "remconmediabrowsefault.h" -#include "remconqueuemessage.h" - -const TInt KDatabaseUnawareUidCounter = 0; -#ifdef __FLOG_ACTIVE -_LIT8(KLogComponent, LOG_COMPONENT_REMCONMEDIABROWSEAPI); -_LIT8(KLogFormat, "Operation Id = 0x%x, Data Lengh = %d"); -#endif -//========================================================================================= -// Construction/Destruction -//========================================================================================= -CRemConMediaBrowseTargetBase::CRemConMediaBrowseTargetBase(CRemConInterfaceSelector& aInterfaceSelector, - MRemConDatabaseAwareMediaLibraryBrowseObserver& aMlObserver, - MRemConDatabaseAwareNowPlayingBrowseObserver& aNpObserver, - TUint16 aMediaLibraryStateCookie) - : CRemConInterfaceBase(TUid::Uid(KRemConMediaBrowseApiUid), - KMaxLengthMediaBrowseMsg, - aInterfaceSelector, - ERemConClientTypeTarget), - iInterfaceSelector(aInterfaceSelector), - iRcdamlbo(&aMlObserver), - iRcdanpbo(&aNpObserver), - iMediaLibraryStateCookie(aMediaLibraryStateCookie), - iAttributeIterator(iMediaAttributeIds), - iNullIterator(iNullArray), - iSearchInProgress(EFalse), - iLastMlscUpdate(aMediaLibraryStateCookie) - { - } - -CRemConMediaBrowseTargetBase::CRemConMediaBrowseTargetBase(CRemConInterfaceSelector& aInterfaceSelector, - MRemConDatabaseUnawareMediaLibraryBrowseObserver& aMlObserver, - MRemConDatabaseUnawareNowPlayingBrowseObserver& aNpObserver) - : CRemConInterfaceBase(TUid::Uid(KRemConMediaBrowseApiUid), - KMaxLengthMediaBrowseMsg, - aInterfaceSelector, - ERemConClientTypeTarget), - iInterfaceSelector(aInterfaceSelector), - iRcdumlbo(&aMlObserver), - iRcdunpbo(&aNpObserver), - iAttributeIterator(iMediaAttributeIds), - iNullIterator(iNullArray), - iSearchInProgress(EFalse) - { - } - -CRemConMediaBrowseTargetBase::~CRemConMediaBrowseTargetBase() // codescanner::destructor - { - iMediaAttributeIds.Close(); - iNullArray.Close(); - iOutBuf.Close(); - iSearchString.Close(); - - // iGetPathResponse, iGiaResponse and iGflResponse are instantiated in CRemConMediaBrowseTargetBase::BaseConstructL() and - // so should have the same lifetime as this CRemConMediaBrowseTargetBase instance - __ASSERT_DEBUG(iGetPathResponse && iGiaResponse && iGflResponse, MediaBrowsePanic::Panic(EUnexpectedNullMemberField)); - iGetPathResponse->Close(); - iGiaResponse->Close(); - iGflResponse->Close(); - delete iGetPathResponse; - delete iGiaResponse; - delete iGflResponse; - - if (iNextMessageCallBack) - { - iNextMessageCallBack->Cancel(); - delete iNextMessageCallBack; - } - if (iNextItemCallBack) - { - iNextItemCallBack->Cancel(); - delete iNextItemCallBack; - } - - iMsgQueue->Reset(); - delete iMsgQueue; - } - -void CRemConMediaBrowseTargetBase::BaseConstructL(TBool aSearchSupported) - { - iMsgQueue = new(ELeave)TRemConMessageQueue(); - - iGetPathResponse = new(ELeave)RRemConGetPathResponse(); - iGiaResponse = new(ELeave)RRemConGetItemAttributesResponse(); - iGflResponse = new(ELeave)RRemConGetFolderItemsResponse(); - - TCallBack cb(&NextMessageCb, this); - iNextMessageCallBack = new(ELeave)CAsyncCallBack(cb, CActive::EPriorityStandard); - - TCallBack itemCallBack(&NextItemCallBack, this); - iNextItemCallBack = new(ELeave)CAsyncCallBack(itemCallBack, CActive::EPriorityStandard); - - RRemConInterfaceFeatures features; - User::LeaveIfError(features.Open()); - CleanupClosePushL(features); - - if(aSearchSupported) - { - features.AddOperationL(ESearchOperationId); - iSearchSupported = ETrue; - } - - if(DatabaseAware()) - { - features.AddOperationL(EUIDPersistency); - } - - //Mandate the following operationIds to be supported in the client - features.AddOperationL(EGetFolderItemsOperationId); - features.AddOperationL(EChangePathOperationId); - features.AddOperationL(EGetItemAttributesOperationId); - features.AddOperationL(ESetBrowsedPlayerOperationId); - - iOutBuf.CreateL(KMediaBrowseOutBufMaxLength); - - CRemConInterfaceBase::BaseConstructL(features, ETrue); // it's true, this interface is a bulk interface - CleanupStack::PopAndDestroy(&features); - } - -//========================================================================================= -// RemCon interface stuff, called from interface selector -//========================================================================================= - -/** -@internalComponent -@released - -Gets a pointer to a specific interface version. - -@return A pointer to the interface, NULL if not supported. -*/ -TAny* CRemConMediaBrowseTargetBase::GetInterfaceIf(TUid aUid) - { - TAny* ret = NULL; - if ( aUid == TUid::Uid(KRemConInterfaceIf1) ) - { - ret = reinterpret_cast( - static_cast(this) - ); - } - - return ret; - } - -void CRemConMediaBrowseTargetBase::MrcibNewMessage(TUint aOperationId, - const TDesC8& aData) - { - LOG_FUNC - LOG2(KLogFormat, aOperationId, aData.Length()); - - TMetadataTransferPDU currentOp = RAvrcpIPC::GetPDUIdFromIPCOperationId(aOperationId); - switch(currentOp) - { - case EGetFolderItemsOperationId: - AddToOperationQueue(EMbGetFolderItems, - EGetFolderItemsOperationId, aData); - if (!iMsgQueue->IsEmpty() && !iInProgress && !iMsgQueue->Find( - TUid::Uid(KRemConMediaBrowseApiUid) - ,EGetFolderItemsOperationId)) - { - iNextMessageCallBack->CallBack(); - } - break; - case EChangePathOperationId: - ProcessChangePath(aData); - break; - case EGetItemAttributesOperationId: - { - AddToOperationQueue(EMbGetItemAttributes, - EGetItemAttributesOperationId, aData); - if (!iMsgQueue->IsEmpty() && !iInProgress && !iMsgQueue->Find( - TUid::Uid(KRemConMediaBrowseApiUid) - ,EGetItemAttributesOperationId)) - { - iNextMessageCallBack->CallBack(); - } - break; - } - case ESearchOperationId: - ProcessSearch(aData); - break; - case ESetBrowsedPlayerOperationId: - ProcessGetPath(aData); - break; - case EMediaLibraryStateCookieUpdateOperationId: - ProcessMediaLibraryStateCookieUpdate(aData); - break; - default: - __ASSERT_DEBUG(EFalse, MediaBrowseFault::Fault(EUnexpectedOperationId)); - break; - }; - } - -//========================================================================================= -// Browse Interface functions, called from derived classes -//========================================================================================= -void CRemConMediaBrowseTargetBase::DoFolderListing(const TArray& aFolderListing, - TUint16 aMediaLibraryStateCookie, - TInt aResult) - { - if (aResult != KErrNone) - { - SendGetFolderItemsResponse(aResult, KNullDesC8); - return; - } - - // If asserted here, means the client calls the interface FolderListing() - // more than once corresponding to the only once call - // MrcmbtoGetFolderListing() - __ASSERT_DEBUG(iGflResponse->iItems.Count() == 0, MediaBrowsePanic::Panic(EFolderListingProvidedTwice)); - - // Store clients state cookie to pass it back when requesting each item. - // This will ensure that we don't miss state change during the course of - // the non-atomic GetFolderListing operation - iGflResponse->iUidCounter = aMediaLibraryStateCookie; - - // Store these UIDs, then ask for info about them - if (iGflResponse->CopyItems(aFolderListing) != KErrNone) - { - SendGetFolderItemsResponse(KErrAvrcpAirInternalError, KNullDesC8); - return; - } - - iGflResponse->iCurrentListingSize = KGetFolderItemsResponseBaseSize; - iGflResponse->iCurrentItem = -1; - RequestNextItem(); - } - -void CRemConMediaBrowseTargetBase::DoFolderUpResult(TUint aItemCount, TInt aResult) - { - SendChangePathResponse(aItemCount, aResult); - } - -void CRemConMediaBrowseTargetBase::DoFolderDownResult(TUint aItemCount, TInt aResult) - { - SendChangePathResponse(aItemCount, aResult); - } - -void CRemConMediaBrowseTargetBase::DoGetPathResult(TUint aItemCount, - TUint16 aMediaLibraryStateCookie, - TInt aResult) - { - if (aResult != KErrNone) - { - iGetPathResponse->Close(); - return SendError(EMbSetBrowsedPlayer, - ESetBrowsedPlayerOperationId, aResult); - } - - // Store the current UIDs counter. - iMediaLibraryStateCookie = aMediaLibraryStateCookie; - - TInt status = KErrAvrcpAirBase - KErrAvrcpAirSuccess; - iGetPathResponse->iStatus = status; - iGetPathResponse->iUidCounter = aMediaLibraryStateCookie; - iGetPathResponse->iNumberItems = aItemCount; - - RBuf8 responseBuf; - TInt error = responseBuf.Create(iGetPathResponse->Size()); - if (error != KErrNone) - { - iGetPathResponse->Close(); - return SendError(EMbSetBrowsedPlayer, - ESetBrowsedPlayerOperationId, KErrAvrcpAirInternalError); - } - - iGetPathResponse->iPduId = AvrcpBrowsing::ESetBrowsedPlayer; - TRAP(error, iGetPathResponse->WriteL(responseBuf)); - if (error == KErrNone) - { - // Send the response back to the CT - error = InterfaceSelector().SendBulkUnreliable( - TUid::Uid(KRemConMediaBrowseApiUid), - ESetBrowsedPlayerOperationId, responseBuf ); - } - - iGetPathResponse->Close(); - responseBuf.Close(); - } - -void CRemConMediaBrowseTargetBase::DoSearchResult(TUint aNumberItemsFound, - TUint16 aMediaLibraryStateCookie, - TInt aResult) - { - // GetFoldItems should in progress When this interface is called. - __ASSERT_DEBUG(iSearchInProgress, MediaBrowsePanic::Panic(ESearchResultWithoutRequest)); - - SendSearchResponse(aResult, aNumberItemsFound, aMediaLibraryStateCookie); - } - -void CRemConMediaBrowseTargetBase::DoMediaLibraryStateChange(TUint16 aMediaLibraryStateCookie) - { - if(DatabaseAware()) - { - __ASSERT_DEBUG(aMediaLibraryStateCookie != KDatabaseUnawareUidCounter, MediaBrowsePanic::Panic(EZeroMediaLibraryStateCookie)); - - // For database aware players we need to update if we have a pending update and - // the new value is different to what we last - if(iMlscUpdatePending && (aMediaLibraryStateCookie != iLastMlscUpdate)) - { - // Send update with new value - SendMediaLibraryStateCookieUpdateResponse(aMediaLibraryStateCookie); - } - - // Always store the last value here. When we are asked for an update - // we will be provided with the value the update should be relative - // to, so we will compare to this. - iLastMlscUpdate = aMediaLibraryStateCookie; - } - else - { - __ASSERT_DEBUG(aMediaLibraryStateCookie == KDatabaseUnawareUidCounter, MediaBrowseFault::Fault(ENonZeroMediaLibraryStateCookie)); - - if(iMlscUpdatePending) - { - SendMediaLibraryStateCookieUpdateResponse(aMediaLibraryStateCookie); - } - else - { - // For database aware clients the value can never change. Indicate that - // the client has informed us of the state change by incrementing our - // update value so that we know there's been a change. The value doesn't - // matter, we just have to make it something other than zero. - iLastMlscUpdate = 1; - } - } - } - -void CRemConMediaBrowseTargetBase::DoFolderItemResult(const TRemConItemUid& aFolderID, - const TDesC8& aFolderName, - TFolderItemType aFolderType, - TFolderItemPlayable aPlayable, - const TArray& aAttributes, - TInt aResult) - { - // GetFolderItems should in progress When this interface is called. - __ASSERT_DEBUG(iGetFolderListing || iGetItemAttributes, MediaBrowsePanic::Panic(EFolderItemResultWithoutRequest)); - - if(iGetFolderListing) - { - ProcessFolderItemResult(aFolderID, aFolderName, aFolderType, aPlayable, aResult); - } - - if (iGetItemAttributes) - { - ProcessGetItemAttributesResult(aAttributes, aResult); - } - } - -void CRemConMediaBrowseTargetBase::DoMediaElementItemResult(const TRemConItemUid& aMediaID, - const TDesC8& aMediaName, - TMediaItemType aMediaType, - const TArray& aAttributes, - TInt aResult) - { - __ASSERT_DEBUG((iGetFolderListing || iGetItemAttributes), MediaBrowsePanic::Panic(EMediaElementItemResultWithoutRequest)); - - if (iGetFolderListing) - { - ProcessMediaElementItemResult(aMediaID, aMediaName, aMediaType, aAttributes, aResult); - } - - if (iGetItemAttributes) - { - ProcessGetItemAttributesResult(aAttributes, aResult); - } - } - -//========================================================================================= -// Utility functions, called internally -//========================================================================================= - -void CRemConMediaBrowseTargetBase::ProcessMediaLibraryStateCookieUpdate(const TDesC8& aData) - { - // Try to read the incoming request - RRemConUidsChangedRequest request; - TRAPD(error, request.ReadL(aData)); - __ASSERT_DEBUG(error == KErrNone, MediaBrowseFault::Fault(EBadlyFormattedMediaLibraryStateCookieUpdate)); - static_cast(error == error); // stops compiler warnings (assert above indicates design contract). - - if(request.iInitialUidCounter != iLastMlscUpdate) - { - // The client has updated the uid counter since the bearer - // last asked. Tell it the new value. The Send..Response - // function deals with all the state management necessary, - // including whether we are database aware or unaware - SendMediaLibraryStateCookieUpdateResponse(iLastMlscUpdate); - } - else - { - // Bearer still up to date. Remember that it's waiting for - // an update. - iMlscUpdatePending = ETrue; - } - } - -void CRemConMediaBrowseTargetBase::ProcessGetItemAttributes(const TDesC8& aData) - { - TRemConFolderScope scope; - TRemConItemUid item; - TUint16 uidCounter; - TInt err = ParseGetItemAttributesRequest(aData, scope, item, uidCounter); - if (err != KErrNone) - { - SendGetItemAttributesResponse(err, KNullDesC8); - return; - } - - iAttributeIterator.Start(); - iInProgress = ETrue; - iGetItemAttributes = ETrue; - TInt result = KErrNone; - if(scope == ENowPlayingFolder) - { - if (!DatabaseAware() && (0 == uidCounter))//Database UnAware - { - result = iRcdunpbo->MrcdunpboGetItem(item, iAttributeIterator); - } - else if (DatabaseAware() && (uidCounter > 0)) - { - result = iRcdanpbo->MrcdanpboGetItem(item, iAttributeIterator, uidCounter); - } - else - { - result = KErrAvrcpAirInvalidParameter; - } - } - else - { - if (!DatabaseAware() && (0 == uidCounter))//Database UnAware - { - result = iRcdumlbo->MrcdumlboGetItem(scope, item, iAttributeIterator); - } - else if (DatabaseAware() && (uidCounter > 0)) - { - result = iRcdamlbo->MrcdamlboGetItem(scope, item, iAttributeIterator, - uidCounter); - } - else - { - result = KErrAvrcpAirInvalidParameter; - } - } - - // The call back function returns error. - if (result != KErrNone) - { - SendGetItemAttributesResponse(result, KNullDesC8); - } - } - -void CRemConMediaBrowseTargetBase::SendGetItemAttributesResponse(TInt aResult, const TDesC8& aData) - { - if(aResult != KErrNone) - { - SendError(EMbGetItemAttributes, EGetItemAttributesOperationId, aResult); - } - else - { - InterfaceSelector().SendBulkUnreliable( - TUid::Uid(KRemConMediaBrowseApiUid), - EGetItemAttributesOperationId, aData); - } - - iInProgress = EFalse; - iGetItemAttributes = EFalse; - iMediaAttributeIds.Reset(); - iGiaResponse->Close(); - - if (!iMsgQueue->IsEmpty()) - { - iNextMessageCallBack->CallBack(); - } - } - -void CRemConMediaBrowseTargetBase::ProcessChangePath(const TDesC8& aData) - { - // Try to read the incoming request - TInt error = KErrNone; - RRemConChangePathRequest request; - TRAP(error, request.ReadL(aData)); - - // Couldn't parse the request; tell them it was invalid - if (error != KErrNone) - { - SendError(EMbChangePath, EChangePathOperationId, KErrAvrcpAirInvalidParameter); - return; - } - - if(request.iDirection == AvrcpBrowsing::KUp) - { - if (DatabaseAware() && (request.iUidCounter > 0)) - { - iRcdamlbo->MrcdamlboFolderUp(request.iUidCounter); - } - else if (!DatabaseAware() && (0 == request.iUidCounter)) - { - iRcdumlbo->MrcdumlboFolderUp(); - } - else - { - SendError(EMbChangePath, EChangePathOperationId, KErrAvrcpAirInvalidParameter); - } - } - else if(request.iDirection == AvrcpBrowsing::KDown) - { - if (DatabaseAware() && (request.iUidCounter > 0)) - { - iRcdamlbo->MrcdamlboFolderDown(request.iElement, request.iUidCounter); - } - else if (!DatabaseAware() && (0 == request.iUidCounter)) - { - iRcdumlbo->MrcdumlboFolderDown(request.iElement); - } - else - { - SendError(EMbChangePath, EChangePathOperationId, KErrAvrcpAirInvalidParameter); - } - } - else - { - SendError(EMbChangePath, EChangePathOperationId, KErrAvrcpAirInvalidDirection); - } - } - -void CRemConMediaBrowseTargetBase::SendSearchResponse(TInt aResult, TUint aNumberItemsFound, TUint16 aMediaLibraryStateCookie) - { - iSearchString.Close(); - - // format the response in a RRemConSearchResponse - RRemConMediaErrorResponse errResponse; - RRemConSearchResponse response; - TInt symbianError = errResponse.SymbianErrorCheck(aResult); - - response.iStatus = errResponse.SymbianErrToStatus(symbianError); - response.iPduId = AvrcpBrowsing::ESearch;//0x80 - response.iUidCounter = aMediaLibraryStateCookie; - response.iNumberItems = aNumberItemsFound; - TRAPD(error, response.WriteL(iOutBuf)); - if (error == KErrNone) - { - // send the response back to the CT - error = InterfaceSelector().SendBulkUnreliable( - TUid::Uid(KRemConMediaBrowseApiUid), - ESearchOperationId, iOutBuf ); - } - - //Search operatin complete. - iSearchInProgress = EFalse; - } - -void CRemConMediaBrowseTargetBase::ProcessSearch(const TDesC8& aData) - { - // Don't trouble the client with this if they've informed us they don't - // support it - if (!iSearchSupported) - { - return SendSearchResponse(KErrAvrcpAirSearchNotSupported, 0, 0); - } - - // We know a search operation is in progress - if (iSearchInProgress) - { - return SendSearchResponse(KErrAvrcpAirSearchInProgress, 0, 0); - } - - // Try to read the incoming request - TInt error = KErrNone; - RRemConSearchRequest request; - TRAP(error, request.ReadL(aData)); - - // Couldn't parse the request; tell them it was invalid - if (error != KErrNone) - { - error = (error == KErrNoMemory) ? - KErrAvrcpAirInternalError : KErrAvrcpAirInvalidParameter; - - return SendSearchResponse(error, 0, 0); - } - - // Check the character set - if (request.iCharset != KUtf8MibEnum) - { - iSearchInProgress = EFalse; - return SendSearchResponse(KErrAvrcpAirInvalidParameter, 0, 0); - } - - iSearchString.Close(); - iSearchString.Assign(request.iSearchString); - //iSearchString has taken ownership of request's search string. - request.iSearchString.Assign(NULL); - - iSearchInProgress = ETrue; - - if(DatabaseAware()) - { - iRcdamlbo->MrcdamlboSearch(iSearchString); - } - else - { - iRcdumlbo->MrcdumlboSearch(iSearchString); - } - - request.Close(); - } - -void CRemConMediaBrowseTargetBase::ProcessGetPath(const TDesC8& aData) - { - iGflResponse->iMaxResponse = *(reinterpret_cast(aData.Ptr())); - - if(DatabaseAware()) - { - iRcdamlbo->MrcdamlboGetPath(iGetPathResponse->iPath); - } - else - { - iRcdumlbo->MrcdumlboGetPath(iGetPathResponse->iPath); - } - } - -void CRemConMediaBrowseTargetBase::ProcessGetFolderItems(const TDesC8& aData) - { - // The bearer is responsible for ensuring we have been supplied with response - // max size before sending us any requests - __ASSERT_DEBUG(iGflResponse->iMaxResponse != 0, MediaBrowseFault::Fault(ERequestWithoutMaxResponseBeingSet)); - - iInProgress = ETrue; - iGetFolderListing = ETrue; - - RRemConGetFolderItemsRequest request; - TRAPD(err, request.ReadL(aData)); - if(err != KErrNone) - { - request.Close(); - SendGetFolderItemsResponse(KErrAvrcpAirInvalidParameter, KNullDesC8); - return; - } - - if(request.iScope == AvrcpBrowsing::KSearchScope && !iSearchSupported) - { - request.Close(); - SendGetFolderItemsResponse(KErrAvrcpAirSearchNotSupported, KNullDesC8); - return; - } - - if (request.CopyAttributes(iMediaAttributeIds) != KErrNone) - { - request.Close(); - SendGetFolderItemsResponse(KErrAvrcpAirInternalError, KNullDesC8); - return; - } - iAttributeIterator.Start(); - - if(request.iScope == AvrcpBrowsing::KVirtualFilesystemScope) - { - iScope = EBrowseFolder; - } - else if(request.iScope == AvrcpBrowsing::KNowPlayingScope) - { - iScope = ENowPlayingFolder; - } - else if(request.iScope == AvrcpBrowsing::KSearchScope) - { - iScope = ESearchResultFolder; - } - else - { - request.Close(); - SendGetFolderItemsResponse(KErrAvrcpAirInvalidScope, KNullDesC8); - return; - } - - if (request.iStartItem > request.iEndItem) - { - request.Close(); - SendGetFolderItemsResponse(KErrAvrcpAirRangeOutOfBounds, KNullDesC8); - return; - } - - if(iScope == ENowPlayingFolder) - { - if(DatabaseAware()) - { - iRcdanpbo->MrcdanpboGetFolderListing(request.iStartItem, request.iEndItem); - } - else - { - iRcdunpbo->MrcdunpboGetFolderListing(request.iStartItem, request.iEndItem); - } - } - else - { - if(DatabaseAware()) - { - iRcdamlbo->MrcdamlboGetFolderListing(iScope,request.iStartItem, request.iEndItem); - } - else - { - iRcdumlbo->MrcdumlboGetFolderListing(iScope,request.iStartItem, request.iEndItem); - } - } - - request.Close(); - } - -void CRemConMediaBrowseTargetBase::SendGetFolderItemsResponse(TInt aResult, const TDesC8& aData) - { - if(aResult != KErrNone) - { - SendError(EMbGetFolderItems, EGetFolderItemsOperationId, aResult); - } - else - { - InterfaceSelector().SendBulkUnreliable( - TUid::Uid(KRemConMediaBrowseApiUid), - EGetFolderItemsOperationId, aData); - } - - iInProgress = EFalse; - iGetFolderListing = EFalse; - iMediaAttributeIds.Reset(); - iGflResponse->Close(); - - iNextItemCallBack->Cancel(); - - if (!iMsgQueue->IsEmpty()) - { - iNextMessageCallBack->CallBack(); - } - } - -TInt CRemConMediaBrowseTargetBase::NextMessageCb(TAny* aThis) - { - static_cast(aThis)->DoNextMessage(); - return KErrNone; - } - -void CRemConMediaBrowseTargetBase::DoNextMessage() - { - __ASSERT_DEBUG(!iMsgQueue->IsEmpty(), MediaBrowseFault::Fault(EUnexpectedNextMessageCallback)); - CRemConQueuedMessage* msg = iMsgQueue->First(); - iMsgQueue->Remove(*msg); - - switch (msg->iOperationId) - { - case EGetFolderItemsOperationId: - ProcessGetFolderItems(msg->Data()); - break; - case EGetItemAttributesOperationId: - ProcessGetItemAttributes(msg->Data()); - break; - default: - __ASSERT_DEBUG(EFalse, MediaBrowseFault::Fault(EUnexpectedNextMessageCallback)); - break; - } - delete msg; - } - -void CRemConMediaBrowseTargetBase::SendMediaLibraryStateCookieUpdateResponse(TUint16 aMediaLibraryStateCookie) - { - LOG_FUNC - - TUint16 newValue = DatabaseAware() ? aMediaLibraryStateCookie : KDatabaseUnawareUidCounter; - - TInt error = KErrNone; - RRemConUidsChangedResponse response; - response.iUidCounter = newValue; - TRAP(error, response.WriteL(iOutBuf)); - - if (error == KErrNone) - { - // send the response back to the CT - error = InterfaceSelector().SendBulkUnreliable( - TUid::Uid(KRemConMediaBrowseApiUid), - EMediaLibraryStateCookieUpdateOperationId, iOutBuf); - - iLastMlscUpdate = newValue; - iMlscUpdatePending = EFalse; - } - // otherwise we couldn't update the client. Leave our state with the update - // pending then we'll try again next time the client tells us state has - // changed. - } - -void CRemConMediaBrowseTargetBase::SendChangePathResponse(TUint aItemCount, - TInt aResult) - { - if (aResult != KErrNone) - { - return SendError(EMbChangePath, EChangePathOperationId, aResult); - } - - TInt error = KErrNone; - - // Format the response in a RRemConChangePathResponse - RRemConChangePathResponse response; - response.iStatus = KErrAvrcpAirBase - KErrAvrcpAirSuccess;//0x4 - response.iNumberItems = aItemCount; - - RBuf8 responseBuf; - error = responseBuf.Create(KMediaBrowseOutBufMaxLength); - if (error != KErrNone) - { - responseBuf.Close(); - SendError(EMbChangePath, EChangePathOperationId, KErrAvrcpAirInternalError); - return; - } - - response.iPduId = AvrcpBrowsing::EChangePath; - TRAP(error, response.WriteL(responseBuf)); - if (error == KErrNone) - { - // send the response back to the CT - error = InterfaceSelector().SendBulkUnreliable( - TUid::Uid(KRemConMediaBrowseApiUid), - EChangePathOperationId, responseBuf ); - } - - responseBuf.Close(); - } - -TInt CRemConMediaBrowseTargetBase::NextItemCallBack(TAny* aThis) - { - static_cast(aThis)->RequestNextItem(); - return KErrNone; - } - -void CRemConMediaBrowseTargetBase::RequestNextItem() - { - TInt err = KErrNone; - TInt result = KErrNone; - RBuf8 responseBuf; - - // If true, indicate that we have not got all the items requested, - // so going on. - // There are some array elements accessed by [] as follows without - // checking range for it is done in RequestNextItem function. - if ( iGflResponse->RequestNextItem(err, responseBuf, - iGflResponse->iUidCounter) ) - { - TBool folderItem = EFalse; - if (AvrcpBrowsing::EFolderItem == iGflResponse->iItems[iGflResponse->iCurrentItem].iType) - { - folderItem = ETrue; - } - iAttributeIterator.Start(); - if(iScope == ENowPlayingFolder) - { - if(DatabaseAware()) - { - result = iRcdanpbo->MrcdanpboGetItem( - iGflResponse->iItems[iGflResponse->iCurrentItem].iUid, - folderItem ? iNullIterator : iAttributeIterator, - iGflResponse->iUidCounter); - } - else - { - result = iRcdunpbo->MrcdunpboGetItem( - iGflResponse->iItems[iGflResponse->iCurrentItem].iUid, - folderItem ? iNullIterator : iAttributeIterator); - } - } - else - { - if(DatabaseAware()) - { - result = iRcdamlbo->MrcdamlboGetItem(iScope, - iGflResponse->iItems[iGflResponse->iCurrentItem].iUid, - folderItem ? iNullIterator : iAttributeIterator, - iGflResponse->iUidCounter); - } - else - { - result = iRcdumlbo->MrcdumlboGetItem(iScope, - iGflResponse->iItems[iGflResponse->iCurrentItem].iUid, - folderItem ? iNullIterator : iAttributeIterator); - } - } - - // The call back function reutrns error. - if (result != KErrNone) - { - SendGetFolderItemsResponse(result, KNullDesC8); - } - } - // If comes here, indicate that we stop requesting the next item - // which means two possibilities: - // 1. Success: Have got all the items we want. - // 2. Error: Error occured internally. - else if ( err == KErrNone ) //Possibility 1. - { - SendGetFolderItemsResponse(KErrNone, responseBuf); - } - else // Possibility 2. - { - SendGetFolderItemsResponse(KErrAvrcpAirInternalError, KNullDesC8); - } - responseBuf.Close(); - } - -void CRemConMediaBrowseTargetBase::DoItemComplete(TInt aResult) - { - if (aResult != KErrNone) - { - SendGetFolderItemsResponse(aResult, KNullDesC8); - } - else - { - // We have to put an async break in here - otherwise if large - // numbers of items are requested we could overflow the stack - iNextItemCallBack->CallBack(); - } - } - -void CRemConMediaBrowseTargetBase::SendError(TUint8 aPduId, - TUint aOperationId, - TInt aError) - { - TInt error = KErrNone; - RRemConMediaErrorResponse response; - response.iPduId = aPduId; - response.iStatus = RAvrcpIPC::SymbianErrToStatus(aError); - TRAP(error, response.WriteL(iOutBuf)); - if (error == KErrNone) - { - InterfaceSelector().SendBulkUnreliable( - TUid::Uid(KRemConMediaBrowseApiUid), - aOperationId, iOutBuf); - } - } - -/** -Sets an attribute value for the requested item. -*/ -TInt CRemConMediaBrowseTargetBase::DoAttributeValue( - TMediaAttributeId aAttributeId, - const TDesC8& aAttributeData ) - { - iSetAttributeValue = ETrue; - - REAResponse resp; - resp.iAttributeId = aAttributeId; - resp.iCharset = KUtf8MibEnum; - resp.iStringLen = aAttributeData.Length(); - resp.iString = aAttributeData.Alloc(); - if (!resp.iString) - { - iSetAttributeValue = EFalse; - return KErrNoMemory; - } - TInt status = KErrNone; - if(iGiaResponse->Size() + resp.iStringLen < iGflResponse->iMaxResponse) - { - status = iGiaResponse->iAttributes.Append(resp); - if (status != KErrNone) - { - iSetAttributeValue = EFalse; - resp.Close(); // make sure heap string is de-allocated - } - } - - return status; - } - -/** -Signals that all attributes requested has been supplied. -*/ - void CRemConMediaBrowseTargetBase::DoAllAttributesCompleted(TInt aResult) - { - TInt error = KErrNone; - __ASSERT_DEBUG(((aResult != KErrNone) || ((aResult == KErrNone) && iSetAttributeValue)), - MediaBrowseFault::Fault(EResultErrorCodeMismatch)); - - if (aResult == KErrNone) - { - // Finalise response; update number of attributes returned - iGiaResponse->iNumberAttributes = iGiaResponse->iAttributes.Count(); - } - - // Allocate a buffer for the formatted message - RBuf8 messageBuffer; - TInt bufferSize = - (aResult == KErrNone) ? iGiaResponse->Size() : KBrowseResponseBaseLength; - - if ( messageBuffer.Create(bufferSize) != KErrNone ) - { - SendGetItemAttributesResponse(KErrAvrcpAirInternalError, KNullDesC8); - } - else - { - // Send the result back to the CT - iGiaResponse->iPduId = AvrcpBrowsing::EGetItemAttributes; // 0x73 - iGiaResponse->iStatus = RAvrcpIPC::SymbianErrToStatus(aResult); - - TRAP(error, iGiaResponse->WriteL(messageBuffer)); - if (error == KErrNone) - { - SendGetItemAttributesResponse(KErrNone, messageBuffer); - } - else - { - SendGetItemAttributesResponse(KErrAvrcpAirInternalError, KNullDesC8); - } - } - messageBuffer.Close(); - } - -TInt CRemConMediaBrowseTargetBase::ItemAttributesResult( - const TArray& aAttributes) - { - TInt error = KErrNone; - TMediaAttributeId attributeId; - for (TInt i = 0; i < aAttributes.Count(); i++) - { - // check that the values supplied were requested - attributeId = aAttributes[i].iAttributeId; - if ( KErrNotFound == iMediaAttributeIds.Find(attributeId) ) - { - //Omit the invalid ones - continue; - } - - error = DoAttributeValue(attributeId, *aAttributes[i].iString); - if (error != KErrNone) - { - break; - } - } - - return error; - } - -void CRemConMediaBrowseTargetBase::AddToOperationQueue(TUint8 aPduId, - TInt aOperationId, - const TDesC8& aData) - { - CRemConQueuedMessage* msg = NULL; - TRAPD(err, msg = CRemConQueuedMessage::NewL( - TUid::Uid(KRemConMediaBrowseApiUid), aData, aOperationId)); - if (err == KErrNone) - { - iMsgQueue->AddLast(*msg); - } - else - { - SendError(aPduId, aOperationId, KErrAvrcpAirInternalError); - } - } - -TInt CRemConMediaBrowseTargetBase::ParseGetItemAttributesRequest( - const TDesC8& aData, - TRemConFolderScope& aScope, - TRemConItemUid& aItemUid, - TUint16& aMediaLibraryStateCookie) - { - // Try to read the incoming request - TInt error = KErrNone; - RRemConGetItemAttributesRequest request; - TRAP(error, request.ReadL(aData)); - - // Couldn't parse the request;tell them it was invalid - // Specification says unique id must not be 0x0 - if (error != KErrNone || request.iElement == 0) - { - request.Close(); - return KErrAvrcpAirInvalidParameter; - } - - if (request.iNumberAttributes == 0) - { - // spec says this is a request for all attribs - // current spec has 7 specified (0x01 to 0x07) - for (TInt i = 1; i <= KMediaAttributeNum; i++) - { - if (iMediaAttributeIds.Append(static_cast(i)) - != KErrNone) - { - request.Close(); - return KErrAvrcpAirInternalError; - } - } - } - else - { - // No need to check - // request.iNumberAttributes == request.iAttributes.Count() - // as this must be correct or request.ReadL(aData) leaves - TUint8 value; - TMediaAttributeId attributeid; - for (TInt i = 0; i < request.iNumberAttributes; i++) - { - value = request.iAttributes[i]; - if (value > 0 && value <= KMaxMediaAttributeValue ) - { - attributeid = static_cast(value); - if (iMediaAttributeIds.Append(attributeid) != KErrNone) - { - request.Close(); - return KErrAvrcpAirInternalError; - } - } - } - } - // Check that some valid attribute ids have been found - if (iMediaAttributeIds.Count() == 0) - { - request.Close(); - return KErrAvrcpAirInvalidParameter; - } - - if(request.iScope == AvrcpBrowsing::KSearchScope) - { - aScope = ESearchResultFolder; - } - else if(request.iScope == AvrcpBrowsing::KVirtualFilesystemScope) - { - aScope = EBrowseFolder; - } - else if (request.iScope == AvrcpBrowsing::KNowPlayingScope) - { - aScope = ENowPlayingFolder; - } - else - { - request.Close(); - return KErrAvrcpAirInvalidScope; - } - - aItemUid = request.iElement; - aMediaLibraryStateCookie = request.iUidCounter; - - request.Close(); - return KErrNone; - } - -void CRemConMediaBrowseTargetBase::ProcessMediaElementItemResult( - const TRemConItemUid& aMediaID, - const TDesC8& aMediaName, - TMediaItemType aMediaType, - const TArray& aAttributes, - TInt aResult) - { - TInt internalError = KErrNone; - if (aResult == KErrNone) - { - __ASSERT_DEBUG(aMediaType < AvrcpBrowsing::KMediaTypeReserved, MediaBrowsePanic::Panic(EInvalidMediaType)); - - RItem& item = iGflResponse->iItems[iGflResponse->iCurrentItem]; - if (item.iUid == aMediaID) - { - item.iType = AvrcpBrowsing::EMediaElement; - item.iCharset = KUtf8MibEnum; - - item.iName = aMediaName.Alloc(); - internalError = (!item.iName) ? KErrNoMemory : internalError; - - if (internalError == KErrNone) - { - item.iNameLength = aMediaName.Length(); - item.iMediaType = static_cast(aMediaType); - item.iNumberAttributes = aAttributes.Count(); - item.iLength = KMediaElementItemBaseLength + item.iNameLength; - TInt attributeCount = aAttributes.Count(); - REAResponse attribute; - for (TInt i = 0; i < attributeCount; i++) - { - // Check that the values supplied were requested - if (KErrNotFound == iMediaAttributeIds.Find(aAttributes[i].iAttributeId)) - { - //Omit the invalid ones - continue; - } - - attribute.iAttributeId = aAttributes[i].iAttributeId; - attribute.iString = aAttributes[i].iString->Alloc(); - internalError = (!attribute.iString) ? KErrNoMemory : internalError; - if (internalError == KErrNone) - { - attribute.iCharset = KUtf8MibEnum; - attribute.iStringLen = attribute.iString->Length(); - item.iAttributes.Append(attribute); - - item.iLength += - KAttributeBaseLength + attribute.iString->Length(); - } - else - { - //it's useless to continue as there is an allocation issue - break; - } - } - } - } - else - { - internalError = KErrArgument; - } - } - - aResult = - (KErrNone == internalError)? aResult : KErrAvrcpAirInternalError; - - DoItemComplete(aResult); - } - -void CRemConMediaBrowseTargetBase::ProcessFolderItemResult( - const TRemConItemUid& aFolderID, - const TDesC8& aFolderName, - TFolderItemType aFolderType, - TFolderItemPlayable aPlayable, - TInt aResult) - { - TInt internalError = KErrNone; - if (aResult == KErrNone) - { - __ASSERT_DEBUG(aFolderType < AvrcpBrowsing::EFolderTypeReserved, MediaBrowsePanic::Panic(EInvalidFolderType)); - __ASSERT_DEBUG(aPlayable < AvrcpBrowsing::KPlayableReserved, MediaBrowsePanic::Panic(EInvalidPlayableValue)); - - RItem& item = iGflResponse->iItems[iGflResponse->iCurrentItem]; - if (item.iUid == aFolderID) - { - item.iType = AvrcpBrowsing::EFolderItem; - item.iCharset = KUtf8MibEnum; - - item.iName = aFolderName.Alloc(); - internalError = (!item.iName) ? KErrNoMemory : internalError; - - item.iNameLength = aFolderName.Length(); - - item.iFolderType = - static_cast(aFolderType); - - item.iPlayable = aPlayable; - item.iLength = KFolderItemBaseLength + item.iNameLength; - } - else - { - internalError = KErrArgument; - } - } - - aResult = (internalError == KErrNone) ? aResult : KErrAvrcpAirInternalError; - - DoItemComplete(aResult); - } - -void CRemConMediaBrowseTargetBase::ProcessGetItemAttributesResult( - const TArray& aAttributes, - TInt aResult) - { - TInt internalError = KErrNone; - if (aResult == KErrNone) - { - internalError = ItemAttributesResult(aAttributes); - } - - aResult = - (KErrNone == internalError)? aResult : KErrAvrcpAirInternalError; - - DoAllAttributesCompleted(aResult); - } - -inline TBool CRemConMediaBrowseTargetBase::DatabaseAware() const - { - return iRcdanpbo ? ETrue : EFalse; - }