--- /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);
+ }
+
+
+