--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btaudioman/src/basrvaccman.cpp Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,848 @@
+/*
+* Copyright (c) 2005-2006 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: Implementation of an accessory management.
+* Version : %version: 14.1.7 %
+*
+*/
+
+
+// INCLUDE FILES
+#include <centralrepository.h>
+#include "basrvaccman.h"
+#include "BTAccSession.h"
+#include "BTAccClientSrv.h"
+#include "basrvacc.h"
+#include "BTAccInfo.h"
+#include "basrvpluginman.h"
+#include "BTAccFwIf.h"
+#include "debug.h"
+
+const TInt KOpenAudioListenerId = 20;
+const TInt KCloseAudioListenerId = 21;
+const TInt KShowNoteRequest = 22;
+const TInt KAsyncHandlingRequest = 23;
+
+// ================= MEMBER FUNCTIONS =======================
+
+CBasrvAccMan* CBasrvAccMan::NewL()
+ {
+ CBasrvAccMan* self = new (ELeave) CBasrvAccMan();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CBasrvAccMan::~CBasrvAccMan()
+ {
+ delete iOpenListener;
+ delete iCloseListener;
+ delete iAsyncHandlingActive;
+
+ // Response to any buffered audio request from Audio Policy.
+ if (iAccfw)
+ {
+ TInt count = iAudioRequests.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ if (iAudioRequests[i].iReqType == EOpenReqFromAudioPolicy)
+ {
+ TRAP_IGNORE(iAccfw->AudioConnectionOpenCompleteL(
+ iAudioRequests[i].iAddr, KErrDisconnected));
+ }
+ else if (iAudioRequests[i].iReqType == ECloseReqFromAudioPolicy)
+ {
+ TRAP_IGNORE(iAccfw->AudioConnectionCloseCompleteL(
+ iAudioRequests[i].iAddr, KErrDisconnected));
+ }
+ }
+ }
+
+ iAudioRequests.Close();
+ iAccs.ResetAndDestroy();
+ iAccs.Close();
+ delete iAccfw;
+ delete iPluginMan;
+ iNotifierArray.ResetAndDestroy();
+ iNotifierArray.Close();
+ iClientRequests.Close();
+ DestructVariant();
+ TRACE_FUNC
+ }
+
+void CBasrvAccMan::LoadServicesL()
+ {
+ TRACE_FUNC
+ if (!iPluginMan)
+ {
+ iPluginMan = CBasrvPluginMan::NewL();
+ }
+ iPluginMan->LoadPluginsL(*this);
+ }
+
+void CBasrvAccMan::ConnectL(CBTAccSession& aSession, const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC
+ TClientRequestCache request;
+ request.iSession = &aSession;
+ request.iRequest = EBTAccSrvConnectToAccessory;
+ request.iAddr = aAddr;
+ iClientRequests.AppendL(request);
+
+ //remove the last item from the RArray if a leave occurs later
+ TCleanupItem cleanupItem(CleanupLastItemFromClientRequestsArray, &iClientRequests);
+ CleanupStack::PushL(cleanupItem);
+
+ TInt idx = FindAcc(aAddr);
+ if (idx >= 0)
+ {
+ iAccs[idx]->ConnectL(aAddr);
+ }
+ else
+ {
+ CBasrvAcc* acc = CBasrvAcc::NewLC(*this);
+ iAccs.AppendL(acc);
+ CleanupStack::Pop(acc);
+ acc->ConnectL(aAddr);
+ }
+
+ CleanupStack::Pop(&iClientRequests);
+ }
+
+void CBasrvAccMan::CancelConnect(const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC
+ TInt idx = FindAcc(aAddr);
+ if (idx >= 0)
+ {
+ TInt count = iClientRequests.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ if (iClientRequests[i].iAddr == aAddr &&
+ iClientRequests[i].iRequest == EBTAccSrvConnectToAccessory)
+ {
+ iClientRequests.Remove(i);
+ break;
+ }
+ }
+ iAccs[idx]->CancelConnect();
+ }
+ }
+
+void CBasrvAccMan::DisconnectL(CBTAccSession& aSession, const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC
+ TInt idx = FindAcc(aAddr);
+ if (idx >= 0)
+ {
+ RemoveAudioRequest(aAddr);
+ TClientRequestCache request;
+ request.iSession = &aSession;
+ request.iRequest = EBTAccSrvDisconnectAccessory;
+ request.iAddr = aAddr;
+ iClientRequests.AppendL(request);
+ iAccs[idx]->DisconnectL();
+ }
+ else
+ {
+ aSession.DisconnectCompleted(EAnyMonoAudioProfiles, KErrNotFound);
+ }
+ }
+
+void CBasrvAccMan::DisconnectAllL(CBTAccSession& aSession)
+ {
+ TRACE_FUNC
+ if (!iDisconnectAllPending)
+ {
+ TInt count = iAccs.Count();
+ if (!count)
+ {
+ aSession.DisconnectAllCompleted(KErrNone);
+ }
+ else
+ {
+ iSessionOfDisconnectAll = &aSession;
+ for (TInt i = 0; i < count; i++)
+ {
+ RemoveAudioRequest(iAccs[i]->Remote());
+ iAccs[i]->DisconnectL();
+ }
+ iDisconnectAllPending = ETrue;
+ }
+ }
+ }
+
+void CBasrvAccMan::SetProfileNotifySession(CBTAccSession& aSession)
+ {
+ iProfileNotifySession = &aSession;
+ }
+
+void CBasrvAccMan::ClearProfileNotifySession(CBTAccSession& aSession)
+ {
+ //if the session passed in is equal to what we have stored
+ if (&aSession == iProfileNotifySession)
+ {
+ //invalidate the pointer to the session
+ iProfileNotifySession = NULL;
+ }
+ }
+
+const TAccInfo* CBasrvAccMan::AccInfo(const TBTDevAddr& aAddr)
+ {
+ TInt count = iAccs.Count();
+ const TAccInfo* info = NULL;
+ for (TInt i = 0; i < count; i++)
+ {
+ info = iAccs[i]->AccInfo(aAddr);
+ if (info)
+ {
+ return info;
+ }
+ }
+ return NULL;
+ }
+
+CBasrvPluginMan& CBasrvAccMan::PluginMan()
+ {
+ return *iPluginMan;
+ }
+
+void CBasrvAccMan::ConnectCompletedL(const TBTDevAddr& aAddr, TInt aErr,
+ TInt aProfile, const RArray<TBTDevAddr>* aConflicts)
+ {
+ TRACE_FUNC
+ TInt count = iClientRequests.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ if (iClientRequests[i].iAddr == aAddr &&
+ iClientRequests[i].iRequest == EBTAccSrvConnectToAccessory)
+ {
+ iClientRequests[i].iSession->ConnectCompleted(aErr, aProfile, aConflicts);
+ iClientRequests.Remove(i);
+ break;
+ }
+ }
+ }
+
+void CBasrvAccMan::DisconnectCompletedL(const TBTDevAddr& aAddr, TInt aProfile, TInt aErr)
+ {
+ TRACE_FUNC
+ TInt count = iClientRequests.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ if (iClientRequests[i].iAddr == aAddr &&
+ iClientRequests[i].iRequest == EBTAccSrvDisconnectAccessory)
+ {
+ iClientRequests[i].iSession->DisconnectCompleted(aProfile, aErr);
+ iClientRequests.Remove(i);
+ break;
+ }
+ }
+ }
+
+#define TRACE_AUDIO_REQUEST_COMPLETE \
+ TRACE_INFO_SEG(\
+ {\
+ TBuf<12> buf;\
+ aAddr.GetReadable(buf);\
+ Trace(_L("[Audio Request Complete] %d %d at '%S', err %d"), \
+ iAudioRequests[0].iReqType, aType, &buf, aErr);\
+ });
+
+TInt CBasrvAccMan::OpenAudioCompleted(const TBTDevAddr& aAddr, TAccAudioType aType, TInt aErr)
+ {
+ TInt err = KErrNone;
+ if (iAudioRequests.Count())
+ {
+ TRACE_AUDIO_REQUEST_COMPLETE
+ TRequestType reqType = iAudioRequests[0].iReqType;
+ iAudioRequests.Remove(0);
+ TInt latency = iPluginMan->AudioLinkLatency();
+ if (reqType == EOpenReqFromAudioPolicy)
+ {
+
+ TRAP(err, AccfwConnectionL()->AudioConnectionOpenCompleteL(aAddr, aErr, latency))
+ TRACE_INFO((_L("AccfwConnectionL()->AudioConnectionOpenCompleteL trap %d"), err))
+ if (!err && !aErr)
+ {
+ err = NotifyAccFwAudioOpened(aAddr, aType, latency);
+ }
+ else if (err == KErrAlreadyExists && !aErr)
+ {
+ RejectAudioLink(aAddr, aType);
+ }
+ }
+ }
+ if (!err) // if err, a rejecting audio link has been scheduled.
+ {
+ TRAP_IGNORE(DoAudioRequestL());
+ }
+ return err;
+ }
+
+TInt CBasrvAccMan::CloseAudioCompleted(const TBTDevAddr& aAddr, TAccAudioType aType, TInt aErr)
+ {
+ TInt err = KErrNone;
+ if (iAudioRequests.Count())
+ {
+ TRACE_AUDIO_REQUEST_COMPLETE
+ if (iAudioRequests[0].iReqType == ECloseReqFromAudioPolicy)
+ {
+ TRAP(err, AccfwConnectionL()->NotifyAudioLinkCloseL(aAddr, aType));
+ TRACE_INFO((_L("AccfwConnectionL()->NotifyAudioLinkCloseL trap %d"), err))
+ TRAP(err, AccfwConnectionL()->AudioConnectionCloseCompleteL(aAddr, aErr));
+ TRACE_INFO((_L("AccfwConnectionL()->AudioConnectionCloseCompleteL trap %d"), err))
+ }
+ iAudioRequests.Remove(0);
+ }
+ if (iAudioRequests.Count())
+ {
+ TRAP_IGNORE(DoAudioRequestL());
+ }
+ return err;
+ }
+
+void CBasrvAccMan::AccObsoleted(CBasrvAcc* aAcc, const TBTDevAddr& /*aAddr*/)
+ {
+ TRACE_FUNC
+ TInt idx = iAccs.Find(aAcc);
+ if (idx >= 0)
+ {
+ RemoveAudioRequest(iAccs[idx]->Remote());
+ delete aAcc;
+ iAccs.Remove(idx);
+ }
+ if (!iAccs.Count())
+ {
+ delete iOpenListener;
+ iOpenListener = NULL;
+ delete iCloseListener;
+ iCloseListener = NULL;
+ delete iAccfw;
+ iAccfw = NULL;
+ iAudioRequests.Reset();
+ if (iDisconnectAllPending)
+ {
+ iDisconnectAllPending = EFalse;
+ if (iSessionOfDisconnectAll)
+ iSessionOfDisconnectAll->DisconnectAllCompleted(KErrNone);
+ }
+ }
+ }
+
+CBasrvAccfwIf* CBasrvAccMan::AccfwConnectionL(const TAccInfo* aInfo)
+ {
+ if (!iAccfw)
+ {
+ iAccfw = CBasrvAccfwIf::NewL(aInfo);
+ }
+ return iAccfw;
+ }
+
+CBasrvAccfwIf* CBasrvAccMan::NewAccfwConnectionInstanceL()
+ {
+ TRACE_FUNC
+ return CBasrvAccfwIf::NewL(NULL);
+ }
+
+void CBasrvAccMan::ListenAudioRequestL()
+ {
+ TRACE_FUNC
+ if (!iOpenListener)
+ {
+ iCloseListener = CBasrvActive::NewL(*this, CActive::EPriorityStandard, KCloseAudioListenerId);
+ iOpenListener = CBasrvActive::NewL(*this, CActive::EPriorityStandard, KOpenAudioListenerId);
+ AccfwConnectionL()->NotifyBTAudioLinkOpenReq(iOpenAddr,iOpenListener->iStatus, iOpenType);
+ iOpenListener->GoActive();
+ AccfwConnectionL()->NotifyBTAudioLinkCloseReq(iCloseAddr,iCloseListener->iStatus, iCloseType);
+ iCloseListener->GoActive();
+ }
+ }
+
+void CBasrvAccMan::CancelAudioRequestListen()
+ {
+ delete iOpenListener;
+ iOpenListener = NULL;
+ delete iCloseListener;
+ iCloseListener = NULL;
+ TRACE_FUNC
+ }
+
+void CBasrvAccMan::RemoveAudioRequest(const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC
+ TInt count = iAudioRequests.Count();
+ TInt i = 0;
+ while(count && i < count)
+ {
+ if (iAudioRequests[i].iAddr == aAddr)
+ {
+ TRACE_INFO_SEG(
+ {
+ TBuf<12> buf;
+ aAddr.GetReadable(buf);
+ Trace(_L("[Audio Request Aborted] %d %d at '%S'"),
+ iAudioRequests[i].iReqType, iAudioRequests[i].iAudioType, &buf);
+ });
+ if (iAudioRequests[i].iReqType == EOpenReqFromAudioPolicy)
+ {
+ TRAP_IGNORE(AccfwConnectionL()->AudioConnectionOpenCompleteL(aAddr, KErrDisconnected));
+ }
+ else if (iAudioRequests[i].iReqType == ECloseReqFromAudioPolicy)
+ {
+ TRAP_IGNORE(AccfwConnectionL()->AudioConnectionCloseCompleteL(aAddr, KErrDisconnected));
+ }
+ iAudioRequests.Remove(i);
+ count--;
+ }
+ else
+ {
+ i++;
+ }
+ }
+ }
+
+void CBasrvAccMan::ShowNote(TBTGenericInfoNoteType aNote, const TBTDevAddr& aAddr)
+ {
+ TRACE_INFO((_L("CBasrvAccMan::ShowNote %d"), aNote))
+ TRAPD(err, iNotifierArray.Append(CBasrvActiveNotifier::NewL(*this, CActive::EPriorityStandard, KShowNoteRequest, aAddr, aNote)));
+ if (err)
+ {
+ TRACE_ERROR((_L("could not construct active notifer object")))
+ return;
+ }
+ }
+
+void CBasrvAccMan::FilterProfileSupport(TAccInfo& aInfo)
+ {
+ TInt pluginbit = iPluginMan->AvailablePlugins();
+ aInfo.iSuppProfiles &= pluginbit;
+ }
+
+TInt CBasrvAccMan::NotifyAccFwAudioOpened(const TBTDevAddr& aAddr, TAccAudioType aType, TInt /*aLatency*/)
+ {
+ TRAPD(err, AccfwConnectionL()->NotifyAudioLinkOpenL(aAddr, aType));
+ TRACE_INFO((_L("AccfwConnectionL()->NotifyAudioLinkOpenL type %d trap %d"), aType, err))
+ if (err)
+ {
+ RejectAudioLink(aAddr, aType);
+ }
+ return err;
+ }
+
+TInt CBasrvAccMan::AccInfos(RPointerArray<const TAccInfo>& aInfos)
+ {
+ TInt count = iAccs.Count();
+ TInt err = KErrNone;
+
+ for (TInt i = 0; i < count; i++)
+ {
+ err = aInfos.Append(&(iAccs[i]->AccInfo()));
+
+ if (err != KErrNone)
+ {
+ //an error occured so cleanup
+ aInfos.Close();
+ break;
+ }
+ }
+
+ return err;
+ }
+
+void CBasrvAccMan::NotifyClientNewProfile(TInt aProfile, const TBTDevAddr& aAddr)
+ {
+ if (iProfileNotifySession)
+ {
+ iProfileNotifySession->NotifyClientNewProfile(aProfile, aAddr);
+ }
+ }
+
+void CBasrvAccMan::NotifyClientNoProfile(TInt aProfile, const TBTDevAddr& aAddr)
+ {
+ if (iProfileNotifySession)
+ {
+ iProfileNotifySession->NotifyClientNoProfile(aProfile, aAddr);
+ }
+ }
+
+TBTEngConnectionStatus CBasrvAccMan::ConnectionStatus4Client(const TBTDevAddr& aAddr) const
+ {
+ TInt count = iAccs.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ if (iAccs[i]->Remote() == aAddr)
+ {
+ return iAccs[i]->ConnectionStatus();
+ }
+ }
+ return EBTEngNotConnected;
+ }
+
+TBool CBasrvAccMan::IsAvrcpVolCTSupported()
+ {
+ return iAvrcpVolCTSupported;
+ }
+
+TBool CBasrvAccMan::IsAbsoluteVolumeSupported(const TBTDevAddr& aAddr)
+ {
+ TInt count = iAccs.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ if (iAccs[i]->Remote() == aAddr)
+ {
+ TBool ret = iAccs[i]->AccInfo().iAvrcpVersion == TAccInfo::EAvrcpVersion14 ? ETrue : EFalse;
+ return ret;
+ }
+ }
+ return EFalse;
+ }
+
+TBool CBasrvAccMan::DisconnectIfAudioOpenFails()
+ {
+ return iDisconnectIfAudioOpenFails;
+ }
+
+void CBasrvAccMan::NewAccessory( const TBTDevAddr& aAddr, TProfiles aProfile )
+ {
+ TRACE_INFO_SEG(
+ {
+ TBuf<12> buf;
+ aAddr.GetReadable(buf);
+ Trace(_L("[profile remote connect] profile %d, BTAddr '%S' "), aProfile, &buf );
+ });
+
+ TInt idx = FindAcc(aAddr);
+ if (idx >= 0)
+ {
+ TRAP_IGNORE(iAccs[idx]->AccessoryConnectedL(aAddr, aProfile));
+ }
+ else
+ {
+ CBasrvAcc* acc = NULL;
+ TRAP_IGNORE(acc = CBasrvAcc::NewL(*this));
+ if (acc)
+ {
+ TInt err = iAccs.Append(acc);
+ if (err)
+ delete acc;
+ else
+ {
+ TRAP_IGNORE(acc->AccessoryConnectedL(aAddr, aProfile));
+ }
+ }
+ }
+ }
+
+void CBasrvAccMan::AccessoryDisconnected(const TBTDevAddr& aAddr, TProfiles aProfile)
+ {
+ TRACE_INFO_SEG(
+ {
+ TBuf<12> buf;
+ aAddr.GetReadable(buf);
+ Trace(_L("[profile remote disconnect] profile %d, BTAddr '%S' "), aProfile, &buf );
+ });
+ TInt idx = FindAcc(aAddr);
+ if (idx >= 0)
+ {
+ TRAP_IGNORE(iAccs[idx]->AccessoryDisconnectedL(aProfile));
+ }
+ }
+
+void CBasrvAccMan::RemoteAudioOpened(const TBTDevAddr& aAddr, TProfiles aProfile)
+ {
+ TRACE_INFO_SEG(
+ {
+ TBuf<12> buf;
+ aAddr.GetReadable(buf);
+ Trace(_L("[Audio remote open] profile %d, BTAddr '%S' "), aProfile, &buf );
+ });
+
+ TInt idx = FindAcc(aAddr);
+ if (idx >= 0)
+ {
+ // Check if another audio link opened already
+ TInt audiolinks = AudioLinkStatus();
+
+ if ( ( audiolinks && audiolinks != aProfile) ||
+ ( iAudioRequests.Count() &&
+ iAudioRequests[0].iOngoing &&
+ iAudioRequests[0].iAddr == aAddr) )
+ {
+ // another audio type is opened while we have an audio link or pending audio request.
+ if (iAudioRequests.Count())
+ {
+ TRACE_INFO((_L(" [audio link check] existing audio link %x, audio request pending ? %d. Audio should be rejected!"),
+ audiolinks, iAudioRequests[0].iOngoing))
+ }
+ else
+ {
+ TRACE_INFO((_L(" [audio link check] existing audio link %x. Audio should be rejected!"),
+ audiolinks))
+ }
+ RejectAudioLink(aAddr, (aProfile == EStereo) ? EAccStereoAudio : EAccMonoAudio);
+ }
+ else
+ {
+ iAccs[idx]->AccOpenedAudio(aProfile);
+ }
+ }
+ }
+
+void CBasrvAccMan::RemoteAudioClosed(const TBTDevAddr& aAddr, TProfiles aProfile)
+ {
+ TRACE_INFO_SEG(
+ {
+ TBuf<12> buf;
+ aAddr.GetReadable(buf);
+ Trace(_L("[Audio remote close] profile %d, BTAddr '%S' "), aProfile, &buf );
+ });
+ TInt idx = FindAcc(aAddr);
+ if (idx >= 0)
+ {
+ iAccs[idx]->AccClosedAudio(aProfile);
+ }
+ }
+
+TInt CBasrvAccMan::DisableNREC(const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC
+ TInt idx = FindAcc(aAddr);
+ if (idx >= 0)
+ {
+ TInt err = KErrNone;
+ TRAPD(trap, err = AccfwConnectionL()->DisableNREC(aAddr));
+ if (trap)
+ return trap;
+ return err;
+ }
+ return KErrNotFound;
+ }
+
+void CBasrvAccMan::AccessoryTemporarilyUnavailable(const TBTDevAddr& /*aAddr*/, TProfiles /*aType*/)
+ {
+ TRACE_INFO((_L("AccessoryTemporarilyUnavailable Deprecated !!!")))
+ }
+
+TInt CBasrvAccMan::ConnectionStatus(const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC
+ TInt count = iAccs.Count();
+ const TAccInfo* info = NULL;
+ for (TInt i = 0; i < count; i++)
+ {
+ info = iAccs[i]->AccInfo(aAddr);
+ if (info)
+ {
+ return info->iConnProfiles;
+ }
+ }
+ return 0;
+ }
+
+void CBasrvAccMan::RequestCompletedL(CBasrvActive& aActive)
+ {
+ TRACE_FUNC
+ switch (aActive.RequestId())
+ {
+ case KOpenAudioListenerId:
+ {
+ if (aActive.iStatus == KErrNone)
+ {
+ TAudioRequest req;
+ req.iAddr = iOpenAddr;
+ req.iAudioType = iOpenType;
+ req.iReqType = EOpenReqFromAudioPolicy;
+ req.iOngoing = EFalse;
+
+ TRACE_INFO_SEG(
+ {
+ TBuf<12> buf;
+ iOpenAddr.GetReadable(buf);
+ Trace(_L("[Audio Request Buf] 1(Open) %d at '%S'"), iOpenType, &buf);
+ });
+
+ AccfwConnectionL()->NotifyBTAudioLinkOpenReq(iOpenAddr, aActive.iStatus, iOpenType);
+ aActive.GoActive();
+ iAudioRequests.AppendL(req);
+ DoAudioRequestL();
+ }
+ break;
+ }
+ case KCloseAudioListenerId:
+ if (aActive.iStatus == KErrNone)
+ {
+ TAudioRequest req;
+ req.iAddr = iCloseAddr;
+ req.iAudioType = iCloseType;
+ req.iReqType = ECloseReqFromAudioPolicy;
+ req.iOngoing = EFalse;
+ TRACE_INFO_SEG(
+ {
+ TBuf<12> buf;
+ iCloseAddr.GetReadable(buf);
+ Trace(_L("[Audio Request Buf] 0(Close) %d at '%S'"), iCloseType, &buf);
+ });
+ AccfwConnectionL()->NotifyBTAudioLinkCloseReq(iCloseAddr, aActive.iStatus, iCloseType);
+ aActive.GoActive();
+ iAudioRequests.AppendL(req);
+ DoAudioRequestL();
+ }
+ break;
+ case KShowNoteRequest:
+ {
+ TInt index = iNotifierArray.Find(&aActive);
+ if(index>=0)
+ {
+ delete iNotifierArray[index];
+ iNotifierArray.Remove(index);
+ }
+ break;
+ }
+ case KAsyncHandlingRequest:
+ {
+ DoAudioRequestL();
+ delete iAsyncHandlingActive;
+ iAsyncHandlingActive = NULL;
+ break;
+ }
+ default:
+ {
+
+ }
+ }
+ }
+
+void CBasrvAccMan::CancelRequest(CBasrvActive& aActive)
+ {
+ TRACE_FUNC
+ if (aActive.RequestId() == KOpenAudioListenerId)
+ {
+ TRAP_IGNORE(AccfwConnectionL()->CancelNotifyBTAudioLinkOpenReq());
+ }
+ else if (aActive.RequestId() == KCloseAudioListenerId)
+ {
+ TRAP_IGNORE(AccfwConnectionL()->CancelNotifyBTAudioLinkCloseReq());
+ }
+ }
+
+CBasrvAccMan::CBasrvAccMan()
+ {
+ }
+
+void CBasrvAccMan::DoAudioRequestL()
+ {
+ TRACE_FUNC
+ if (iAudioRequests.Count() && !iAudioRequests[0].iOngoing && (!iAsyncHandlingActive || !iAsyncHandlingActive->IsActive()))
+ {
+ iAudioRequests[0].iOngoing = ETrue;
+ TInt err = KErrNotFound;
+ TInt idx = FindAcc(iAudioRequests[0].iAddr);
+ if (idx >= 0)
+ {
+ if (iAudioRequests[0].iReqType == EOpenReqFromAudioPolicy)
+ {
+ TRAP(err, iAccs[idx]->OpenAudioL(iAudioRequests[0].iAudioType));
+ }
+ else
+ {
+ TRAP(err, iAccs[idx]->CloseAudioL(iAudioRequests[0].iAudioType));
+ }
+ TRACE_INFO_SEG({
+ if ( iAudioRequests.Count() )
+ {
+ TBuf<12> buf;
+ iAudioRequests[0].iAddr.GetReadable(buf);
+ Trace(_L("[Audio Request Start] %d %d at '%S', trap %d"),
+ iAudioRequests[0].iReqType, iAudioRequests[0].iAudioType, &buf, err);
+ }
+ });
+ }
+ if (err)
+ {
+ if (iAudioRequests[0].iReqType == EOpenReqFromAudioPolicy)
+ OpenAudioCompleted(iAudioRequests[0].iAddr, iAudioRequests[0].iAudioType, err);
+ else if(iAudioRequests[0].iReqType == ECloseReqFromAudioPolicy)
+ CloseAudioCompleted(iAudioRequests[0].iAddr, iAudioRequests[0].iAudioType, err);
+ }
+ }
+ }
+
+TInt CBasrvAccMan::FindAcc(const TBTDevAddr& aRemote)
+ {
+ TInt count = iAccs.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ if (iAccs[i]->Remote() == aRemote)
+ {
+ return i;
+ }
+ }
+ return KErrNotFound;
+ }
+
+TInt CBasrvAccMan::AudioLinkStatus()
+ {
+ TInt profiles = 0;
+ TInt count = iAccs.Count();
+ for (TInt i = 0; i < count; i++)
+ {
+ profiles |= iAccs[i]->AccInfo().iAudioOpenedProfiles;
+ }
+ return profiles;
+ }
+
+void CBasrvAccMan::RejectAudioLink(const TBTDevAddr& aAddr, TAccAudioType aType)
+ {
+ TAudioRequest req;
+ req.iAddr = aAddr;
+ req.iAudioType = aType;
+ req.iReqType = ERejectAudioOpenedByAcc;
+ req.iOngoing = EFalse;
+ TInt idx = 0;
+ if (iAudioRequests.Count() && iAudioRequests[0].iOngoing)
+ {
+ idx = 1;
+ }
+ TInt err = iAudioRequests.Insert(req, idx);
+ TRACE_INFO_SEG(
+ {
+ TBuf<12> buf;
+ iCloseAddr.GetReadable(buf);
+ Trace(_L("[Audio Request buf] 2(Reject) %d at '%S', to index %d"), iCloseType, &buf, idx);
+ });
+
+ if (!err && !iAsyncHandlingActive && !iAudioRequests[0].iOngoing)
+ {
+ // Start rejection asynchronously
+ iAsyncHandlingActive =
+ CBasrvActive::New(*this, CActive::EPriorityStandard, KAsyncHandlingRequest);
+ if (iAsyncHandlingActive)
+ {
+ iAsyncHandlingActive->iStatus = KRequestPending;
+ TRequestStatus* sta = &(iAsyncHandlingActive->iStatus);
+ User::RequestComplete(sta, KErrNone);
+ iAsyncHandlingActive->GoActive();
+ }
+ }
+ }
+
+void CBasrvAccMan::CleanupLastItemFromClientRequestsArray(TAny* aPtr)
+ {
+ //cast the pointer passed in to the correct RArray type
+ RArray<TClientRequestCache>& clientRequests = *static_cast<RArray<TClientRequestCache>*>(aPtr);
+
+ //remove the last item from the array
+ clientRequests.Remove(clientRequests.Count() - 1);
+ }