bluetoothappprofiles/avrcp/absolutevolumeapi/src/absolutevolumeapitarget.cpp
changeset 70 f5508c13dfe0
parent 67 16e4b9007960
child 71 083fd884d7dd
equal deleted inserted replaced
67:16e4b9007960 70:f5508c13dfe0
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 
       
    18 /**
       
    19  @file
       
    20  @publishedAll
       
    21  @released
       
    22 */
       
    23 
       
    24 #include <absolutevolumeapitarget.h>
       
    25 #include <absolutevolumeapitargetobserver.h>
       
    26 #include <remconinterfaceselector.h>
       
    27 #include <absolutevolumeapi.h>
       
    28 #include <absolutevolumeutils.h>
       
    29 #include <bluetooth/logger.h>
       
    30 
       
    31 #ifdef __FLOG_ACTIVE
       
    32 _LIT8(KLogComponent, LOG_COMPONENT_REMCONABSOLUTEVOLUME);
       
    33 _LIT8(KLogFormat, "Operation Id = 0x%x, Data Lengh = %d");
       
    34 _LIT8(KLogNewL, "CRemConAbsoluteVolumeTarget::NewL");
       
    35 #endif
       
    36 
       
    37 /**
       
    38 Allocates and constructs a new CRemConAbsoluteVolumeTarget object
       
    39 
       
    40 @param aInterfaceSelector The interface selector. The client must have 
       
    41        created one of these first.
       
    42 @param aObserver The observer through which the client will receive absolute
       
    43        volume commands from M class MRemConAbsoluteVolumeTargetObserver.
       
    44 @param aVolume The initial relative volume on the client.
       
    45 @param aMaxVolume The client maximum volume against which aVolume is relative.
       
    46 @return A new CRemConAbsoluteVolumeTarget, owned by the interface selector.
       
    47 @panic AbsoluteVolumeTarget 0 if aMaxVolume is zero
       
    48        AbsoluteVolumeTarget 1 if aVolume greater than aMaxVolume
       
    49        
       
    50 */
       
    51 EXPORT_C CRemConAbsoluteVolumeTarget* CRemConAbsoluteVolumeTarget::NewL(
       
    52 		CRemConInterfaceSelector& aInterfaceSelector, 
       
    53 		MRemConAbsoluteVolumeTargetObserver& aObserver,
       
    54 		TUint32 aVolume, 
       
    55 		TUint32 aMaxVolume)
       
    56 	{
       
    57 	LOG(KLogNewL);
       
    58 	
       
    59 	__ASSERT_ALWAYS(aMaxVolume > 0, 
       
    60 			User::Panic(KAbsoluteVolumeTargetPanicName, 
       
    61 					ETargetInvalidMaxVolume)
       
    62 			);
       
    63 	__ASSERT_ALWAYS(aVolume <= aMaxVolume, 
       
    64 			User::Panic(KAbsoluteVolumeTargetPanicName, 
       
    65 					ETargetVolumeBeyondMaxVolume)
       
    66 			);
       
    67 	
       
    68 	CRemConAbsoluteVolumeTarget* self = 
       
    69 	new(ELeave) CRemConAbsoluteVolumeTarget(aInterfaceSelector, 
       
    70 			aObserver, aVolume, aMaxVolume);
       
    71 	
       
    72 	CleanupStack::PushL(self);
       
    73 	self->ConstructL();
       
    74 	CleanupStack::Pop(self);
       
    75 	return self;
       
    76 	}
       
    77 
       
    78 /** 
       
    79 Constructor.
       
    80 @param aInterfaceSelector The interface selector.
       
    81 @param aObserver The observer of this interface.
       
    82 @param aVolume The initial relative volume on the client
       
    83 @param aMaxVolume The maximum volume on the client against which 
       
    84        aVolume is relative.
       
    85 */
       
    86 CRemConAbsoluteVolumeTarget::CRemConAbsoluteVolumeTarget(
       
    87 		CRemConInterfaceSelector& aInterfaceSelector, 
       
    88 		MRemConAbsoluteVolumeTargetObserver& aObserver,
       
    89 		TUint32 aVolume, 
       
    90 		TUint32 aMaxVolume)
       
    91 :	CRemConInterfaceBase(TUid::Uid(KRemConAbsoluteVolumeTargetApiUid),
       
    92 		KAbsoluteVolumeRequestDataSize, 
       
    93 		aInterfaceSelector,
       
    94 		ERemConClientTypeTarget), 
       
    95 	iObserver(aObserver),
       
    96 	iAbsoluteVolumeNotificationRequest(EFalse),
       
    97 	iClientVolume(aVolume),
       
    98 	iClientMaxVolume(aMaxVolume)
       
    99 	{
       
   100 	}
       
   101 	
       
   102 void CRemConAbsoluteVolumeTarget::ConstructL()
       
   103 	{
       
   104 	iOutBuf.CreateL(KAbsoluteVolumeResponseDataSize);
       
   105 
       
   106 	//Mandate the following features supported.
       
   107 	RRemConInterfaceFeatures features;
       
   108 	User::LeaveIfError(features.Open());
       
   109 	CleanupClosePushL(features);
       
   110 	features.AddOperationL(KRemConSetAbsoluteVolume);
       
   111 	
       
   112 	BaseConstructL(features);
       
   113 	CleanupStack::PopAndDestroy(&features);
       
   114 	}
       
   115 
       
   116 EXPORT_C CRemConAbsoluteVolumeTarget::~CRemConAbsoluteVolumeTarget()
       
   117 	{
       
   118 	iOutBuf.Close();
       
   119 	}
       
   120 
       
   121 TAny* CRemConAbsoluteVolumeTarget::GetInterfaceIf(TUid aUid)
       
   122 	{
       
   123 	TAny* ret = NULL;
       
   124 	if ( aUid == TUid::Uid(KRemConInterfaceIf2) )
       
   125 		{
       
   126 		ret = reinterpret_cast<TAny*>(
       
   127 			static_cast<MRemConInterfaceIf2*>(this)
       
   128 			);
       
   129 		}
       
   130 
       
   131 	return ret;
       
   132 	}
       
   133 
       
   134 /** 
       
   135 Called by the client in response to a MrcavtoSetAbsoluteVolume() call.
       
   136 
       
   137 @param aVolume The relative volume against the client maximum volume.  
       
   138 @param aErr The error code.
       
   139      - KErrNone if the client has changed its absolute volume.
       
   140      - System wide error code otherwise.
       
   141 @panic AbsoluteVolumeTarget 1, if volume is greater than max volume.
       
   142 */
       
   143 EXPORT_C void CRemConAbsoluteVolumeTarget::SetAbsoluteVolumeResponse(
       
   144 		TUint32 aVolume, 
       
   145 		TInt aErr)
       
   146 	{
       
   147 	__ASSERT_ALWAYS(aVolume <= iClientMaxVolume, 
       
   148 			User::Panic(KAbsoluteVolumeTargetPanicName, 
       
   149 					ETargetVolumeBeyondMaxVolume)
       
   150 			);
       
   151 	
       
   152 	RRemConAbsoluteVolumeResponse response;
       
   153 	response.iError = KErrNone;
       
   154 	response.iVolume = aVolume;
       
   155 	response.iMaxVolume = iClientMaxVolume;
       
   156 	TRAPD(error, response.WriteL(iOutBuf));
       
   157 	if (error != KErrNone)
       
   158 		{
       
   159 		SendError(KErrAbsoluteVolumeInternalError, KRemConSetAbsoluteVolume);
       
   160 		return;
       
   161 		}
       
   162 	
       
   163 	if (aErr == KErrNone)
       
   164 		{
       
   165 		// send the response back to the CT
       
   166 		error = InterfaceSelector().SendUnreliable(
       
   167 				TUid::Uid(KRemConAbsoluteVolumeTargetApiUid),
       
   168 				KRemConSetAbsoluteVolume, ERemConResponse, iOutBuf );
       
   169 		}
       
   170 	else
       
   171 		{
       
   172 		SendError(KErrAbsoluteVolumeInternalError, KRemConSetAbsoluteVolume);
       
   173 		}
       
   174 	}
       
   175 
       
   176 /** 
       
   177 Must be called each time the volume changes on the client.
       
   178 
       
   179 It is used to inform the controller if it has requested updates on the client
       
   180 volume change.
       
   181 
       
   182 @param aVolume The relative volume against the client maximum volume. 
       
   183 @panic AbsoluteVolume 1, if volume greater than the client max volume.
       
   184 */
       
   185 EXPORT_C void CRemConAbsoluteVolumeTarget::AbsoluteVolumeChanged(
       
   186 		TUint32 aVolume)
       
   187 	{
       
   188 	__ASSERT_ALWAYS(aVolume <= iClientMaxVolume, 
       
   189 			User::Panic(KAbsoluteVolumeTargetPanicName, 
       
   190 					ETargetVolumeBeyondMaxVolume)
       
   191 			);
       
   192 	
       
   193 	if (aVolume != iClientVolume)
       
   194 		{
       
   195 		// Records the current volume each time
       
   196 		// when the client absolute volume is changed
       
   197 		iClientVolume = aVolume;
       
   198 		
       
   199 		if (iAbsoluteVolumeNotificationRequest)
       
   200 			{
       
   201 			iAbsoluteVolumeNotificationRequest = EFalse;
       
   202 			SendNotificationResponse(ERemConNotifyResponseChanged);
       
   203 			}
       
   204 		}
       
   205 	}
       
   206 
       
   207 // From MRemConInterfaceIf
       
   208 void CRemConAbsoluteVolumeTarget::SendError(TInt aError, TUint aOperationId)
       
   209 	{
       
   210 	TInt error = KErrNone;
       
   211 	RRemConAbsoluteVolumeResponse errRsp;
       
   212 	errRsp.iError = aError;
       
   213 	TRAP(error, errRsp.WriteL(iOutBuf));
       
   214 	if (error == KErrNone)
       
   215 		{
       
   216 		InterfaceSelector().SendUnreliable(
       
   217 				TUid::Uid(KRemConAbsoluteVolumeTargetApiUid),
       
   218 				aOperationId, ERemConResponse, iOutBuf);
       
   219 		}
       
   220 	}
       
   221 
       
   222 void CRemConAbsoluteVolumeTarget::MrcibNewMessage(TUint aOperationId, 
       
   223 		const TDesC8& aData, 
       
   224 		TRemConMessageSubType aMsgSubType)
       
   225 	{
       
   226 	LOG_FUNC
       
   227 	LOG2(KLogFormat, aOperationId, aData.Length());
       
   228 
       
   229 	switch(aOperationId)
       
   230 		{
       
   231 	case KRemConSetAbsoluteVolume:
       
   232 		{
       
   233 		ProcessSetAbsoluteVolume(aData);
       
   234 		break;
       
   235 		}
       
   236 	case KRemConAbsoluteVolumeNotification:
       
   237 		{
       
   238 		// register for Notifications
       
   239 		if (aMsgSubType == ERemConNotifyCommandAwaitingInterim)
       
   240 			{
       
   241 			ProcessGetStatusAndBeginObserving();
       
   242 			}
       
   243 		else if (aMsgSubType == ERemConNotifyCommandAwaitingChanged)
       
   244 			{
       
   245 			ProcessGetStatus();
       
   246 			}
       
   247 	 	break;
       
   248 		}
       
   249 	default:
       
   250 		break; 
       
   251 		};
       
   252 	}
       
   253 
       
   254 /**
       
   255 Processes the request for setting absolute volume.
       
   256 
       
   257 @param aData The absolute volume data to be setted.
       
   258 */
       
   259 void CRemConAbsoluteVolumeTarget::ProcessSetAbsoluteVolume(
       
   260 		const TDesC8& aData)
       
   261 	{	
       
   262 	TInt error;
       
   263 	RRemConAbsoluteVolumeRequest request;
       
   264 	TRAP(error, request.ReadL(aData));
       
   265 	if ( error == KErrNone)
       
   266 		{
       
   267 		iObserver.MrcavtoSetAbsoluteVolumeRequest(request.iVolume, 
       
   268 				request.iMaxVolume);
       
   269 		}
       
   270 	else
       
   271 		{
       
   272 		SendError(KErrAbsoluteVolumeInternalError, KRemConSetAbsoluteVolume);
       
   273 		}
       
   274 	}
       
   275 
       
   276 /**
       
   277 Processes the request for notify command waiting interim.
       
   278 */
       
   279 void CRemConAbsoluteVolumeTarget::ProcessGetStatusAndBeginObserving()
       
   280 	{
       
   281 	//Flag is ETure to indicate the request for absolute volume change 
       
   282 	//notification has been received.
       
   283 	iAbsoluteVolumeNotificationRequest = ETrue;
       
   284 		
       
   285 	//send the interim response with the current absolute volume.
       
   286 	SendNotificationResponse(ERemConNotifyResponseInterim);
       
   287 	}
       
   288 
       
   289 /**
       
   290 Processes the request for notify command waiting changed.
       
   291 */
       
   292 void CRemConAbsoluteVolumeTarget::ProcessGetStatus()
       
   293 	{
       
   294 	// send the current value
       
   295 	SendNotificationResponse(ERemConNotifyResponseChanged);
       
   296 	}
       
   297 
       
   298 /**
       
   299 Sends absolute volume interim or change response according to the message 
       
   300 type aMsgSubType
       
   301 
       
   302 @param aMsgSubType The remcon submessage type.
       
   303 */
       
   304 void CRemConAbsoluteVolumeTarget::SendNotificationResponse(
       
   305 		TRemConMessageSubType aMsgSubType)
       
   306 	{
       
   307 	LOG_FUNC
       
   308 
       
   309 	TInt error = 0;
       
   310 	RRemConAbsoluteVolumeResponse response;
       
   311 	response.iError = KErrNone;
       
   312 	response.iVolume = iClientVolume;
       
   313 	response.iMaxVolume = iClientMaxVolume;
       
   314 	TRAP(error, response.WriteL(iOutBuf));
       
   315 	if (error == KErrNone)
       
   316 		{
       
   317 		error = InterfaceSelector().SendUnreliable(
       
   318 				TUid::Uid(KRemConAbsoluteVolumeTargetApiUid),
       
   319 				KRemConAbsoluteVolumeNotification, 
       
   320 				ERemConResponse, 
       
   321 				aMsgSubType,
       
   322 				iOutBuf);
       
   323 		}
       
   324 	}