diff -r 000000000000 -r f63038272f30 bluetoothappprofiles/avrcp/absolutevolumeapi/src/absolutevolumeapitarget.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothappprofiles/avrcp/absolutevolumeapi/src/absolutevolumeapitarget.cpp Mon Jan 18 20:28:57 2010 +0200 @@ -0,0 +1,324 @@ +// 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: +// + + + +/** + @file + @publishedAll + @released +*/ + +#include +#include +#include +#include +#include +#include + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, LOG_COMPONENT_REMCONABSOLUTEVOLUME); +_LIT8(KLogFormat, "Operation Id = 0x%x, Data Lengh = %d"); +_LIT8(KLogNewL, "CRemConAbsoluteVolumeTarget::NewL"); +#endif + +/** +Allocates and constructs a new CRemConAbsoluteVolumeTarget object + +@param aInterfaceSelector The interface selector. The client must have + created one of these first. +@param aObserver The observer through which the client will receive absolute + volume commands from M class MRemConAbsoluteVolumeTargetObserver. +@param aVolume The initial relative volume on the client. +@param aMaxVolume The client maximum volume against which aVolume is relative. +@return A new CRemConAbsoluteVolumeTarget, owned by the interface selector. +@panic AbsoluteVolumeTarget 0 if aMaxVolume is zero + AbsoluteVolumeTarget 1 if aVolume greater than aMaxVolume + +*/ +EXPORT_C CRemConAbsoluteVolumeTarget* CRemConAbsoluteVolumeTarget::NewL( + CRemConInterfaceSelector& aInterfaceSelector, + MRemConAbsoluteVolumeTargetObserver& aObserver, + TUint32 aVolume, + TUint32 aMaxVolume) + { + LOG(KLogNewL); + + __ASSERT_ALWAYS(aMaxVolume > 0, + User::Panic(KAbsoluteVolumeTargetPanicName, + ETargetInvalidMaxVolume) + ); + __ASSERT_ALWAYS(aVolume <= aMaxVolume, + User::Panic(KAbsoluteVolumeTargetPanicName, + ETargetVolumeBeyondMaxVolume) + ); + + CRemConAbsoluteVolumeTarget* self = + new(ELeave) CRemConAbsoluteVolumeTarget(aInterfaceSelector, + aObserver, aVolume, aMaxVolume); + + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +Constructor. +@param aInterfaceSelector The interface selector. +@param aObserver The observer of this interface. +@param aVolume The initial relative volume on the client +@param aMaxVolume The maximum volume on the client against which + aVolume is relative. +*/ +CRemConAbsoluteVolumeTarget::CRemConAbsoluteVolumeTarget( + CRemConInterfaceSelector& aInterfaceSelector, + MRemConAbsoluteVolumeTargetObserver& aObserver, + TUint32 aVolume, + TUint32 aMaxVolume) +: CRemConInterfaceBase(TUid::Uid(KRemConAbsoluteVolumeTargetApiUid), + KAbsoluteVolumeRequestDataSize, + aInterfaceSelector, + ERemConClientTypeTarget), + iObserver(aObserver), + iAbsoluteVolumeNotificationRequest(EFalse), + iClientVolume(aVolume), + iClientMaxVolume(aMaxVolume) + { + } + +void CRemConAbsoluteVolumeTarget::ConstructL() + { + iOutBuf.CreateL(KAbsoluteVolumeResponseDataSize); + + //Mandate the following features supported. + RRemConInterfaceFeatures features; + User::LeaveIfError(features.Open()); + CleanupClosePushL(features); + features.AddOperationL(KRemConSetAbsoluteVolume); + + BaseConstructL(features); + CleanupStack::PopAndDestroy(&features); + } + +EXPORT_C CRemConAbsoluteVolumeTarget::~CRemConAbsoluteVolumeTarget() + { + iOutBuf.Close(); + } + +TAny* CRemConAbsoluteVolumeTarget::GetInterfaceIf(TUid aUid) + { + TAny* ret = NULL; + if ( aUid == TUid::Uid(KRemConInterfaceIf2) ) + { + ret = reinterpret_cast( + static_cast(this) + ); + } + + return ret; + } + +/** +Called by the client in response to a MrcavtoSetAbsoluteVolume() call. + +@param aVolume The relative volume against the client maximum volume. +@param aErr The error code. + - KErrNone if the client has changed its absolute volume. + - System wide error code otherwise. +@panic AbsoluteVolumeTarget 1, if volume is greater than max volume. +*/ +EXPORT_C void CRemConAbsoluteVolumeTarget::SetAbsoluteVolumeResponse( + TUint32 aVolume, + TInt aErr) + { + __ASSERT_ALWAYS(aVolume <= iClientMaxVolume, + User::Panic(KAbsoluteVolumeTargetPanicName, + ETargetVolumeBeyondMaxVolume) + ); + + RRemConAbsoluteVolumeResponse response; + response.iError = KErrNone; + response.iVolume = aVolume; + response.iMaxVolume = iClientMaxVolume; + TRAPD(error, response.WriteL(iOutBuf)); + if (error != KErrNone) + { + SendError(KErrAbsoluteVolumeInternalError, KRemConSetAbsoluteVolume); + return; + } + + if (aErr == KErrNone) + { + // send the response back to the CT + error = InterfaceSelector().SendUnreliable( + TUid::Uid(KRemConAbsoluteVolumeTargetApiUid), + KRemConSetAbsoluteVolume, ERemConResponse, iOutBuf ); + } + else + { + SendError(KErrAbsoluteVolumeInternalError, KRemConSetAbsoluteVolume); + } + } + +/** +Must be called each time the volume changes on the client. + +It is used to inform the controller if it has requested updates on the client +volume change. + +@param aVolume The relative volume against the client maximum volume. +@panic AbsoluteVolume 1, if volume greater than the client max volume. +*/ +EXPORT_C void CRemConAbsoluteVolumeTarget::AbsoluteVolumeChanged( + TUint32 aVolume) + { + __ASSERT_ALWAYS(aVolume <= iClientMaxVolume, + User::Panic(KAbsoluteVolumeTargetPanicName, + ETargetVolumeBeyondMaxVolume) + ); + + if (aVolume != iClientVolume) + { + // Records the current volume each time + // when the client absolute volume is changed + iClientVolume = aVolume; + + if (iAbsoluteVolumeNotificationRequest) + { + iAbsoluteVolumeNotificationRequest = EFalse; + SendNotificationResponse(ERemConNotifyResponseChanged); + } + } + } + +// From MRemConInterfaceIf +void CRemConAbsoluteVolumeTarget::SendError(TInt aError, TUint aOperationId) + { + TInt error = KErrNone; + RRemConAbsoluteVolumeResponse errRsp; + errRsp.iError = aError; + TRAP(error, errRsp.WriteL(iOutBuf)); + if (error == KErrNone) + { + InterfaceSelector().SendUnreliable( + TUid::Uid(KRemConAbsoluteVolumeTargetApiUid), + aOperationId, ERemConResponse, iOutBuf); + } + } + +void CRemConAbsoluteVolumeTarget::MrcibNewMessage(TUint aOperationId, + const TDesC8& aData, + TRemConMessageSubType aMsgSubType) + { + LOG_FUNC + LOG2(KLogFormat, aOperationId, aData.Length()); + + switch(aOperationId) + { + case KRemConSetAbsoluteVolume: + { + ProcessSetAbsoluteVolume(aData); + break; + } + case KRemConAbsoluteVolumeNotification: + { + // register for Notifications + if (aMsgSubType == ERemConNotifyCommandAwaitingInterim) + { + ProcessGetStatusAndBeginObserving(); + } + else if (aMsgSubType == ERemConNotifyCommandAwaitingChanged) + { + ProcessGetStatus(); + } + break; + } + default: + break; + }; + } + +/** +Processes the request for setting absolute volume. + +@param aData The absolute volume data to be setted. +*/ +void CRemConAbsoluteVolumeTarget::ProcessSetAbsoluteVolume( + const TDesC8& aData) + { + TInt error; + RRemConAbsoluteVolumeRequest request; + TRAP(error, request.ReadL(aData)); + if ( error == KErrNone) + { + iObserver.MrcavtoSetAbsoluteVolumeRequest(request.iVolume, + request.iMaxVolume); + } + else + { + SendError(KErrAbsoluteVolumeInternalError, KRemConSetAbsoluteVolume); + } + } + +/** +Processes the request for notify command waiting interim. +*/ +void CRemConAbsoluteVolumeTarget::ProcessGetStatusAndBeginObserving() + { + //Flag is ETure to indicate the request for absolute volume change + //notification has been received. + iAbsoluteVolumeNotificationRequest = ETrue; + + //send the interim response with the current absolute volume. + SendNotificationResponse(ERemConNotifyResponseInterim); + } + +/** +Processes the request for notify command waiting changed. +*/ +void CRemConAbsoluteVolumeTarget::ProcessGetStatus() + { + // send the current value + SendNotificationResponse(ERemConNotifyResponseChanged); + } + +/** +Sends absolute volume interim or change response according to the message +type aMsgSubType + +@param aMsgSubType The remcon submessage type. +*/ +void CRemConAbsoluteVolumeTarget::SendNotificationResponse( + TRemConMessageSubType aMsgSubType) + { + LOG_FUNC + + TInt error = 0; + RRemConAbsoluteVolumeResponse response; + response.iError = KErrNone; + response.iVolume = iClientVolume; + response.iMaxVolume = iClientMaxVolume; + TRAP(error, response.WriteL(iOutBuf)); + if (error == KErrNone) + { + error = InterfaceSelector().SendUnreliable( + TUid::Uid(KRemConAbsoluteVolumeTargetApiUid), + KRemConAbsoluteVolumeNotification, + ERemConResponse, + aMsgSubType, + iOutBuf); + } + }