bluetoothappprofiles/avrcp/remconbeareravrcp/src/playerstatewatcher.cpp
changeset 0 f63038272f30
child 6 6a29d5ad0713
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothappprofiles/avrcp/remconbeareravrcp/src/playerstatewatcher.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,305 @@
+// 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:
+//
+
+#include "mediabrowse.h"
+#include "avrcputils.h"
+#include "commandhandlerinterface.h"
+#include "internalcommand.h"
+#include "mediabrowse.h"
+#include "playerstatewatcher.h"
+#include "remconcommandinterface.h"
+#include "avrcplog.h"
+#include "playerinformation.h"
+
+CPlayerWatcherBase::CPlayerWatcherBase(MRemConCommandInterface& aCommandInterface)
+	: iCommandInterface(aCommandInterface), iCommands()
+	{
+	LOG_FUNC;
+	}
+
+CPlayerWatcherBase::~CPlayerWatcherBase()
+	{
+	LOG_FUNC;
+	}
+
+void CPlayerWatcherBase::StopWatchingPlayer(TRemConClientId aClientId)
+	{
+	LOG_FUNC;
+	CInternalCommand* command = *iCommands.Find(aClientId);
+	__ASSERT_DEBUG(command, AVRCP_PANIC(ENotWatchingPlayer));
+
+	iCommands.Remove(aClientId);
+	command->DecrementUsers();
+	}
+
+void CPlayerWatcherBase::MessageSent(CAvrcpCommand& /*aCommand*/, TInt /*aSendResult*/)
+	{
+	LOG_FUNC;
+	__DEBUG_ONLY(AVRCP_PANIC(ELowerInterfaceUsedOnInternalHandler));
+	}
+
+void CPlayerWatcherBase::MaxPacketSize(TInt /*aMtu*/)
+	{
+	LOG_FUNC;
+	__DEBUG_ONLY(AVRCP_PANIC(ELowerInterfaceUsedOnInternalHandler));
+	}
+
+void CPlayerWatcherBase::ReceiveCommandL(const TDesC8& /*aMessageInformation*/, SymbianAvctp::TTransactionLabel /*aTransLabel*/, const TBTDevAddr& /*aAddr*/)
+	{
+	LOG_FUNC;
+	__DEBUG_ONLY(AVRCP_PANIC(ELowerInterfaceUsedOnInternalHandler));
+	}
+
+CInternalCommand& CPlayerWatcherBase::FindCommand(TUid __DEBUG_ONLY(aInterfaceUid),
+		TUint aTransactionId, TRemConClientId& aFoundClientId)
+	{
+	__ASSERT_DEBUG(aInterfaceUid == TUid::Uid(KRemConPlayerInformationUid) || aInterfaceUid == TUid::Uid(KRemConMediaBrowseApiUid), AVRCP_PANIC(EResponseForWrongInterface));
+	THashMapIter<TRemConClientId, CInternalCommand*> commandIter(iCommands);
+
+	CInternalCommand* command = NULL;
+	while(commandIter.NextValue())
+		{
+		command = *commandIter.CurrentValue();
+		if(command->RemConCommandId() == aTransactionId)
+			{
+			aFoundClientId = *commandIter.CurrentKey();
+			break;
+			}
+		}
+
+	// If command is NULL we reached the end of our iter without finding the match
+	__ASSERT_DEBUG(command, AVRCP_PANIC(EUnmatchedResponseFromRemCon));
+
+	return *command;
+	}
+
+TInt CPlayerWatcherBase::SendRemConResponse(TUid aInterfaceUid, TUint aTransactionId, RBuf8& aData)
+	{
+	LOG_FUNC;
+
+	TRemConClientId clientId;
+	CInternalCommand& command = FindCommand(aInterfaceUid, aTransactionId, clientId);
+
+	ReceiveUpdate(command, clientId, aData);
+
+	return KErrNone;
+	}
+
+void CPlayerWatcherBase::SendReject(TUid aInterfaceUid, TUint aTransactionId)
+	{
+	TRemConClientId clientId;
+	(void)FindCommand(aInterfaceUid, aTransactionId, clientId);
+
+	ReceiveReject(clientId);
+	}
+
+void CPlayerWatcherBase::Disconnect()
+	{
+	LOG_FUNC;
+	}
+
+CPlayStatusWatcher* CPlayStatusWatcher::NewL(MPlayStatusObserver& aObserver, MRemConCommandInterface& aCommandInterface)
+	{
+	LOG_STATIC_FUNC;
+	CPlayStatusWatcher* watcher = new(ELeave)CPlayStatusWatcher(aObserver, aCommandInterface);
+	return watcher;
+	}
+
+CPlayStatusWatcher::CPlayStatusWatcher(MPlayStatusObserver& aObserver,
+		MRemConCommandInterface& aCommandInterface)
+	: CPlayerWatcherBase(aCommandInterface), iObserver(aObserver)
+	{
+	LOG_FUNC;
+	}
+
+CPlayStatusWatcher::~CPlayStatusWatcher()
+	{
+	LOG_FUNC;
+	}
+
+void CPlayStatusWatcher::StartWatchingPlayerL(TRemConClientId aClientId)
+	{
+	LOG_FUNC;
+	__ASSERT_DEBUG(!iCommands.Find(aClientId), AVRCP_PANIC(EAlreadyWatchingPlayer));
+
+	CInternalCommand* command = CInternalCommand::NewL(TUid::Uid(KRemConPlayerInformationUid),
+			0,
+			EGetPlayStatusUpdate,
+			KNullDesC8);
+
+	CleanupStack::PushL(command);
+	iCommands.InsertL(aClientId, command);
+	CleanupStack::Pop(command);
+	command->IncrementUsers();
+
+	// Initially request uid notification relative to stopped
+	SendPlayStatusUpdateRequest(*command, aClientId, MPlayerEventsObserver::EStopped);
+	}
+
+void CPlayStatusWatcher::SendPlayStatusUpdateRequest(CInternalCommand& aCommand, TRemConClientId& aClientId, MPlayerEventsObserver::TPlaybackStatus aPlaybackStatus)
+	{
+	LOG_FUNC;
+
+	RRemConPlayerInformationGetPlayStatusUpdateRequest request;
+	request.iStatus = aPlaybackStatus;
+
+	TBuf8<sizeof(MPlayerEventsObserver::TPlaybackStatus)> buf;
+	TRAPD(err, request.WriteL(buf));
+
+	// We know how big the request is so this should never fail
+	__ASSERT_DEBUG(err == KErrNone, AVRCP_PANIC(EUidUpdateRequestWriteFailure));
+
+	TUint transId = iCommandInterface.MrcciNewTransactionId();
+	TRAP(err, aCommand.ResetL(transId, buf));
+
+	if(err == KErrNone)
+		{
+		iCommandInterface.MrcciNewCommand(aCommand, aClientId);
+		}
+	else
+		{
+		// Doom
+		iObserver.MpsoError(aClientId);
+		}
+	}
+
+void CPlayStatusWatcher::ReceiveUpdate(CInternalCommand& aCommand, TRemConClientId aClientId, RBuf8& aData)
+	{
+	LOG_FUNC;
+
+	// Read 4 byte Big-Endian error code before the payload
+	RAvrcpIPCError errorResponse;
+	TRAPD(err, errorResponse.ReadL(aData));
+	err = err ? err : errorResponse.iError;
+
+	RRemConPlayerInformationGetPlayStatusUpdateResponse response;
+	if(!err)
+		{
+		// Parse the rest of the response (minus error code)
+		TRAP(err, response.ReadL(aData.RightTPtr(aData.Length() - KLengthErrorResponse)));
+		}
+
+	aData.Close(); // data has been used now
+
+	if(!err)
+		{
+		iObserver.MpsoPlayStatusChanged(aClientId, response.iStatus);
+		SendPlayStatusUpdateRequest(aCommand, aClientId, response.iStatus);
+		}
+	else
+		{
+		// Should never get here with a valid player.  This client is
+		// sending us junk.
+		iObserver.MpsoError(aClientId);
+		}
+	}
+
+void CPlayStatusWatcher::ReceiveReject(TRemConClientId aClientId)
+	{
+	LOG_FUNC;
+	iObserver.MpsoError(aClientId);
+	}
+
+CUidWatcher* CUidWatcher::NewL(MUidObserver& aObserver,
+		MRemConCommandInterface& aCommandInterface)
+	{
+	LOG_STATIC_FUNC;
+	CUidWatcher* watcher = new(ELeave)CUidWatcher(aObserver, aCommandInterface);
+	return watcher;
+	}
+
+CUidWatcher::CUidWatcher(MUidObserver& aObserver,
+		MRemConCommandInterface& aCommandInterface)
+	: CPlayerWatcherBase(aCommandInterface), iObserver(aObserver)
+	{
+	LOG_FUNC;
+	}
+
+CUidWatcher::~CUidWatcher()
+	{
+	LOG_FUNC;
+	}
+
+void CUidWatcher::StartWatchingPlayerL(TRemConClientId aClientId)
+	{
+	LOG_FUNC;
+	__ASSERT_DEBUG(!iCommands.Find(aClientId), AVRCP_PANIC(EAlreadyWatchingPlayer));
+
+	CInternalCommand* command = CInternalCommand::NewL(TUid::Uid(KRemConMediaBrowseApiUid),
+			0,
+			EMediaLibraryStateCookieUpdateOperationId,
+			KNullDesC8);
+
+	CleanupStack::PushL(command);
+	iCommands.InsertL(aClientId, command);
+	CleanupStack::Pop(command);
+	command->IncrementUsers();
+
+	// Initially request uid notification relative to 0 uid counter
+	SendUidUpdateRequest(*command, aClientId, 0);
+	}
+
+void CUidWatcher::SendUidUpdateRequest(CInternalCommand& aCommand, TRemConClientId& aClientId, TUint16 aUidCounter)
+	{
+	LOG_FUNC;
+	RRemConUidsChangedRequest request;
+	request.iInitialUidCounter = aUidCounter;
+	TBuf8<sizeof(TUint16)> buf;
+	TRAPD(err, request.WriteL(buf));
+	// We know how big the request is so this should never fail
+	__ASSERT_DEBUG(err == KErrNone, AVRCP_PANIC(EUidUpdateRequestWriteFailure));
+
+	TUint transId = iCommandInterface.MrcciNewTransactionId();
+	TRAP(err, aCommand.ResetL(transId, buf));
+
+	if(err == KErrNone)
+		{
+		iCommandInterface.MrcciNewCommand(aCommand, aClientId);
+		}
+	else
+		{
+		// Doom
+		iObserver.MuoError(aClientId);
+		}
+	}
+
+void CUidWatcher::ReceiveUpdate(CInternalCommand& aCommand, TRemConClientId aClientId, RBuf8& aData)
+	{
+	LOG_FUNC;
+	RRemConUidsChangedResponse response;
+	TRAPD(err, response.ReadL(aData));
+	aData.Close(); // data has been used now
+
+	if(!err)
+		{
+		iObserver.MuoUidChanged(aClientId, response.iUidCounter);
+		SendUidUpdateRequest(aCommand, aClientId, response.iUidCounter);
+		}
+	else
+		{
+		// Should never get here with a valid player.  This client is
+		// sending us junk.
+		iObserver.MuoError(aClientId);
+		}
+	}
+
+void CUidWatcher::ReceiveReject(TRemConClientId aClientId)
+	{
+	LOG_FUNC;
+	iObserver.MuoError(aClientId);
+	}
+
+
+