mmlibs/mmfw/src/ControllerFramework/mmfcontrollerserver.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2002-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 #include <mmf/common/mmfcontroller.h>
       
    17 #include <mmf/server/mmffile.h>
       
    18 #include <mmf/common/mmfdrmcustomcommands.h>
       
    19 #include <mmf/common/mmfstandardcustomcommands.h>
       
    20 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    21 #include <mmf/common/mmfcontrollerextendeddata.h>
       
    22 #include <mmf/common/mmfcustomcommandparsermanager.h>
       
    23 #endif
       
    24 
       
    25 inline void ExtendedDataTlsCleanup(TAny* /*aPtr*/)
       
    26 	{
       
    27 	delete static_cast<CMMFControllerExtendedData*>(Dll::Tls());
       
    28 	Dll::SetTls(NULL);
       
    29 	}
       
    30 
       
    31 CMMFController* CMMFController::NewL(TUid aControllerUid, MAsyncEventHandler& aEventHandler, TThreadId aClientTid)
       
    32 	{
       
    33 	Dll::SetTls(CMMFController::CreateExtendedDataL(aClientTid));
       
    34 	CleanupStack::PushL(TCleanupItem(&ExtendedDataTlsCleanup, NULL));
       
    35 	CMMFController* s = REINTERPRET_CAST(CMMFController*,REComSession::CreateImplementationL(aControllerUid,_FOFF(CMMFController,iDtor_ID_Key)));
       
    36 	CleanupStack::PushL(s);
       
    37 	s->ConstructL(aEventHandler, aClientTid);
       
    38 	CleanupStack::Pop(s);
       
    39 	CleanupStack::PopAndDestroy();	// TCleanupItem(ExtendedDataTlsCleanup)
       
    40 	return s;
       
    41 	}
       
    42 
       
    43 void CMMFController::ConstructL(MAsyncEventHandler& aEventHandler, TThreadId aClientTid)
       
    44 	{
       
    45 	iAsyncEventHandler = &aEventHandler;
       
    46 	
       
    47 	// If extended data hasn't been initialized, GetExtendedDataL will initialize it and
       
    48 	// add it into iMMFObjectContainer
       
    49 #ifdef _DEBUG
       
    50 	CMMFControllerExtendedData* extendData =
       
    51 #endif
       
    52 		GetExtendedDataL();
       
    53 #ifdef _DEBUG
       
    54 	ASSERT(extendData->ClientThreadId() == aClientTid);
       
    55 #else
       
    56 	(void)aClientTid;	// remove compilation error
       
    57 #endif
       
    58 	}
       
    59 
       
    60 EXPORT_C CMMFController::~CMMFController()
       
    61 	{
       
    62 	delete iCustomCommandParserManager;
       
    63 	delete iMMFObjectContainer;
       
    64 	delete iMetaDataBuffer;
       
    65 	REComSession::DestroyedImplementation(iDtor_ID_Key);
       
    66 	}
       
    67 
       
    68 EXPORT_C TInt CMMFController::DoSendEventToClient(const TMMFEvent& aEvent)
       
    69 	{
       
    70 	return iAsyncEventHandler->SendEventToClient(aEvent);
       
    71 	}
       
    72 
       
    73 EXPORT_C CMMFObjectContainer& CMMFController::MMFObjectContainerL()
       
    74 	{
       
    75 	// Construct iMMFObjectContainer if we haven't already.
       
    76 	if (!iMMFObjectContainer)
       
    77 		iMMFObjectContainer = new(ELeave) CMMFObjectContainer;
       
    78 	return *iMMFObjectContainer;
       
    79 	}
       
    80 
       
    81 EXPORT_C void CMMFController::AddCustomCommandParserL(CMMFCustomCommandParserBase& aParser)
       
    82 	{
       
    83 	// Construct iCustomCommandParserManager if we haven't already
       
    84 	if (!iCustomCommandParserManager)
       
    85 		iCustomCommandParserManager = CMMFCustomCommandParserManager::NewL();
       
    86 	iCustomCommandParserManager->AddCustomCommandParserL(aParser);
       
    87 	}
       
    88 
       
    89 
       
    90 EXPORT_C void CMMFController::HandleRequestL(TMMFMessage& aMessage)
       
    91 	{
       
    92 	// If the message has the constant controller destination handle, pass the message to
       
    93 	// the controller plugin to handle.
       
    94 	// Otherwise, the message must be for one of the MMFObjects.
       
    95 	if (aMessage.Destination().DestinationHandle() == KMMFObjectHandleController)
       
    96 		{
       
    97 		// If the message has an interface ID for this controller, handle it here.
       
    98 		// Otherwise, pass it to the controller plugin to handle as a custom command.
       
    99 		if (aMessage.Destination().InterfaceId() == KUidInterfaceMMFController)
       
   100 			{
       
   101 			TBool complete = ETrue;
       
   102 			switch (aMessage.Function())
       
   103 				{
       
   104 			case EMMFControllerAddDataSource:
       
   105 				complete = DoAddDataSourceL(aMessage);
       
   106 				break;
       
   107 			case EMMFControllerAddDataSink:
       
   108 				complete = DoAddDataSinkL(aMessage);
       
   109 				break;
       
   110 			case EMMFControllerRemoveDataSource:
       
   111 				complete = DoRemoveDataSourceL(aMessage);
       
   112 				break;
       
   113 			case EMMFControllerRemoveDataSink:
       
   114 				complete = DoRemoveDataSinkL(aMessage);
       
   115 				break;
       
   116 			case EMMFControllerReset:
       
   117 				complete = DoResetL(aMessage);
       
   118 				break;
       
   119 			case EMMFControllerPrime:
       
   120 				complete = DoPrimeL(aMessage);
       
   121 				break;
       
   122 			case EMMFControllerPlay:
       
   123 				complete = DoPlayL(aMessage);
       
   124 				break;
       
   125 			case EMMFControllerPause:
       
   126 				complete = DoPauseL(aMessage);
       
   127 				break;
       
   128 			case EMMFControllerStop:
       
   129 				complete = DoStopL(aMessage);
       
   130 				break;
       
   131 			case EMMFControllerGetPosition:
       
   132 				complete = DoGetPositionL(aMessage);
       
   133 				break;
       
   134 			case EMMFControllerSetPosition:
       
   135 				complete = DoSetPositionL(aMessage);
       
   136 				break;
       
   137 			case EMMFControllerGetDuration:
       
   138 				complete = DoGetDurationL(aMessage);
       
   139 				break;
       
   140 			case EMMFControllerGetNumberOfMetaDataEntries:
       
   141 				complete = DoGetNumberOfMetaDataEntriesL(aMessage);
       
   142 				break;
       
   143 			case EMMFControllerGetSizeOfMetaDataEntry:
       
   144 				complete = DoGetSizeOfMetaDataEntryL(aMessage);
       
   145 				break;
       
   146 			case EMMFControllerGetMetaDataEntry:
       
   147 				complete = DoGetMetaDataEntryL(aMessage);
       
   148 				break;
       
   149 			case EMMFControllerSetPrioritySettings:
       
   150 				complete = DoSetPrioritySettingsL(aMessage);
       
   151 				break;
       
   152 			case EMMFControllerCancelAddDataSource:
       
   153 				complete = ETrue;//Nothing to cancel since AddDataSource is synchronous server-side
       
   154 				break;
       
   155 			case EMMFControllerCancelAddDataSink:
       
   156 				complete = ETrue;//Nothing to cancel since AddDataSink is synchronous server-side
       
   157 				break;
       
   158 			case EMMFControllerAddFileHandleDataSource:
       
   159 				complete = DoAddFileHandleDataSourceL(aMessage);
       
   160 				break;
       
   161 			case EMMFControllerAddFileHandleDataSink:
       
   162 				complete = DoAddFileHandleDataSinkL(aMessage);
       
   163 				break;
       
   164 			case EMMFControllerSourceSinkInitDataPreload:
       
   165 				complete = DoPreloadSourceSinkInitDataL(aMessage);
       
   166 				break;
       
   167 			case EMMFControllerAddFileHandleDataSourceWithInitData:
       
   168 				complete = DoAddFileHandleDataSourceWithInitDataL(aMessage);
       
   169 				break;
       
   170 			case EMMFControllerAddFileHandleDataSinkWithInitData:
       
   171 				complete = DoAddFileHandleDataSinkWithInitDataL(aMessage);
       
   172 				break;
       
   173 			default:
       
   174 				User::Leave(KErrNotSupported);
       
   175 				break;
       
   176 				}
       
   177 			if (complete)
       
   178 				aMessage.Complete(KErrNone);
       
   179 			}
       
   180 		else
       
   181 			{
       
   182 			// Must be a custom command
       
   183 			DoCustomCommand(aMessage);
       
   184 			}
       
   185 		}
       
   186 	else
       
   187 		{
       
   188 		// Message for one of the MMF Objects
       
   189 		CMMFObject* object = NULL;
       
   190 		User::LeaveIfError(MMFObjectContainerL().FindMMFObject(aMessage.Destination(), object));
       
   191 		object->HandleRequest(aMessage);
       
   192 		}
       
   193 
       
   194 	}
       
   195 
       
   196 TBool CMMFController::DoAddDataSourceL(TMMFMessage& aMessage)
       
   197 	{
       
   198 	// Get the UID of the source from the client
       
   199 	TMMFUidPckg uidPckg;
       
   200 	aMessage.ReadData1FromClientL(uidPckg);
       
   201 
       
   202 	// Get the size of the init data and create a buffer to hold it
       
   203 	TInt desLength = aMessage.SizeOfData2FromClient();
       
   204 	// Leaving here in order to prevent a panic in the NewLC if the value is negative
       
   205 	User::LeaveIfError(desLength); 
       
   206 	HBufC8* buf = HBufC8::NewLC(desLength);
       
   207 	TPtr8 ptr = buf->Des();
       
   208 	aMessage.ReadData2FromClientL(ptr);
       
   209 
       
   210 	// Create the source
       
   211 	MDataSource* source = MDataSource::NewSourceL(uidPckg(), *buf);
       
   212 	CleanupStack::PopAndDestroy(buf);//buf
       
   213 	AddMDataSourceAndRepondClientL(source, aMessage);
       
   214 	
       
   215 	return ETrue;
       
   216 	}
       
   217 	
       
   218 	
       
   219 TBool CMMFController::DoAddDataSinkL(TMMFMessage& aMessage)
       
   220 	{
       
   221 	// Get the UID of the sink from the client
       
   222 	TMMFUidPckg uidPckg;
       
   223 	aMessage.ReadData1FromClientL(uidPckg);
       
   224 
       
   225 	// Get the size of the init data and create a buffer to hold it
       
   226 	TInt desLength = aMessage.SizeOfData2FromClient();
       
   227 	// Leaving here in order to prevent a panic in the NewLC if the value is negative
       
   228 	User::LeaveIfError(desLength);
       
   229 	HBufC8* buf = HBufC8::NewLC(desLength);
       
   230 	TPtr8 ptr = buf->Des();
       
   231 	aMessage.ReadData2FromClientL(ptr);
       
   232 
       
   233 	// Create the sink
       
   234 	MDataSink* sink = MDataSink::NewSinkL(uidPckg(), *buf);
       
   235 	CleanupStack::PopAndDestroy(buf);//buf
       
   236 	AddMDataSinkAndRepondClientL(sink, aMessage);
       
   237 	
       
   238 	return ETrue;
       
   239 	}
       
   240 	
       
   241 TBool CMMFController::DoRemoveDataSourceL(TMMFMessage& aMessage)
       
   242 	{
       
   243 	TMMFMessageDestinationPckg handleInfo;
       
   244 	aMessage.ReadData1FromClientL(handleInfo);
       
   245 	
       
   246 	// Find the correct source
       
   247 	CMMFObject* object = NULL;
       
   248 	CMMFDataSourceHolder* holder = NULL;
       
   249 	User::LeaveIfError(MMFObjectContainerL().FindMMFObject(handleInfo(), object));
       
   250 	// Cast the object found if possible..
       
   251 	if (object->Handle().InterfaceId() == KUidInterfaceMMFDataSourceHolder)
       
   252 		holder = STATIC_CAST(CMMFDataSourceHolder*, object);
       
   253 	else
       
   254 		User::Leave(KErrBadHandle);
       
   255 
       
   256 	// Try to remove the data source from the plugin
       
   257 	RemoveDataSourceL(holder->DataSource());
       
   258 
       
   259 	// If we're here, the removal worked so remove the source from the object array and delete it
       
   260 	MMFObjectContainerL().RemoveAndDestroyMMFObject(*holder);
       
   261 	return ETrue;
       
   262 	}
       
   263 
       
   264 TBool CMMFController::DoRemoveDataSinkL(TMMFMessage& aMessage)
       
   265 	{
       
   266 	TMMFMessageDestinationPckg handleInfo;
       
   267 	aMessage.ReadData1FromClientL(handleInfo);
       
   268 	
       
   269 	// Find the correct source
       
   270 	CMMFObject* object = NULL;
       
   271 	CMMFDataSinkHolder* holder = NULL;
       
   272 	User::LeaveIfError(MMFObjectContainerL().FindMMFObject(handleInfo(), object));
       
   273 	// Cast the object found if possible..
       
   274 	if (object->Handle().InterfaceId() == KUidInterfaceMMFDataSinkHolder)
       
   275 		holder = STATIC_CAST(CMMFDataSinkHolder*, object);
       
   276 	else
       
   277 		User::Leave(KErrBadHandle);
       
   278 
       
   279 	// Try to remove the data sink from the plugin
       
   280 	RemoveDataSinkL(holder->DataSink());
       
   281 
       
   282 	// If we're here, the removal worked so remove the source from the object array and delete it
       
   283 	MMFObjectContainerL().RemoveAndDestroyMMFObject(*holder);
       
   284 	return ETrue;
       
   285 	}
       
   286 
       
   287 TBool CMMFController::DoResetL(TMMFMessage& /*aMessage*/)
       
   288 	{
       
   289 	ResetL();
       
   290 	// Controller extended data must be kept until the death of controller
       
   291 	const RPointerArray<CMMFObject>& objects = iMMFObjectContainer->MMFObjects();
       
   292 	for (TInt i = objects.Count()-1; i >= 0; i--)
       
   293 		{
       
   294 		CMMFObject* object = objects[i];
       
   295 		if (object->Handle().InterfaceId() != KUidMMFControllerExtendedDataHolder)
       
   296 			{
       
   297 			iMMFObjectContainer->RemoveAndDestroyMMFObject(*object);
       
   298 			}
       
   299 		}
       
   300 	return ETrue;
       
   301 	}
       
   302 
       
   303 TBool CMMFController::DoPrimeL(TMMFMessage& aMessage)
       
   304 	{
       
   305 	PrimeL(aMessage);
       
   306 	return EFalse;
       
   307 	}
       
   308 
       
   309 
       
   310 EXPORT_C void CMMFController::PrimeL(TMMFMessage& aMessage)
       
   311 	{
       
   312 	PrimeL();
       
   313 	aMessage.Complete(KErrNone);
       
   314 	}
       
   315 
       
   316 
       
   317 TBool CMMFController::DoPlayL(TMMFMessage& aMessage)
       
   318 	{
       
   319 	PlayL(aMessage);
       
   320 	return EFalse;
       
   321 	}
       
   322 
       
   323 EXPORT_C void CMMFController::PlayL(TMMFMessage& aMessage)
       
   324 	{
       
   325 	PlayL();
       
   326 	aMessage.Complete(KErrNone);
       
   327 	}
       
   328 
       
   329 
       
   330 
       
   331 TBool CMMFController::DoPauseL(TMMFMessage& aMessage)
       
   332 	{
       
   333 	PauseL(aMessage);
       
   334 	return EFalse;
       
   335 	}
       
   336 
       
   337 EXPORT_C void CMMFController::PauseL(TMMFMessage& aMessage)
       
   338 	{
       
   339 	PauseL();
       
   340 	aMessage.Complete(KErrNone);
       
   341 	}
       
   342 
       
   343 
       
   344 TBool CMMFController::DoStopL(TMMFMessage& aMessage)
       
   345 	{
       
   346 	StopL(aMessage);
       
   347 	return EFalse;
       
   348 	}
       
   349 
       
   350 EXPORT_C void CMMFController::StopL(TMMFMessage& aMessage)
       
   351 	{
       
   352 	StopL();
       
   353 	aMessage.Complete(KErrNone);
       
   354 	}
       
   355 
       
   356 
       
   357 
       
   358 TBool CMMFController::DoGetPositionL(TMMFMessage& aMessage)
       
   359 	{
       
   360 	TMMFTimeIntervalMicroSecondsPckg pckg(PositionL());
       
   361 	aMessage.WriteDataToClientL(pckg);
       
   362 	return ETrue;
       
   363 	}
       
   364 
       
   365 TBool CMMFController::DoSetPositionL(TMMFMessage& aMessage)
       
   366 	{
       
   367 	TMMFTimeIntervalMicroSecondsPckg pckg;
       
   368 	aMessage.ReadData1FromClientL(pckg);
       
   369 	SetPositionL(pckg());
       
   370 	return ETrue;
       
   371 	}
       
   372 
       
   373 TBool CMMFController::DoGetDurationL(TMMFMessage& aMessage)
       
   374 	{
       
   375 	TMMFTimeIntervalMicroSecondsPckg pckg(DurationL());
       
   376 	aMessage.WriteDataToClientL(pckg);
       
   377 	return ETrue;
       
   378 	}
       
   379 
       
   380 TBool CMMFController::DoSetPrioritySettingsL(TMMFMessage& aMessage)
       
   381 	{
       
   382 	TMMFPrioritySettingsPckg pckg;
       
   383 	aMessage.ReadData1FromClientL(pckg);
       
   384 	SetPrioritySettings(pckg());
       
   385 	return ETrue;
       
   386 	}
       
   387 
       
   388 void CMMFController::DoCustomCommand(TMMFMessage& aMessage)
       
   389 	{
       
   390 	// First, try giving the message to the custom command parser manager...
       
   391 	TBool handled = EFalse;
       
   392 	if (iCustomCommandParserManager)
       
   393 		{
       
   394 		if (aMessage.Destination().InterfaceId() == KUidInterfaceMMFDRMControl ||
       
   395 			aMessage.Destination().InterfaceId() == KUidInterfaceMMFVideoDRMExt)
       
   396 			{
       
   397 			TBool secureDrmMode = EFalse;
       
   398 			TRAPD(err, secureDrmMode = GetExtendedDataL()->SecureDrmMode());
       
   399 			if (err)
       
   400 				{
       
   401 				aMessage.Complete(err);
       
   402 				handled = ETrue;
       
   403 				}
       
   404 			else if (secureDrmMode)
       
   405 				{
       
   406 				aMessage.Complete(KErrPermissionDenied);
       
   407 				handled = ETrue;
       
   408 				}
       
   409 			}
       
   410 		
       
   411 		if (!handled)
       
   412 			{
       
   413 			handled = iCustomCommandParserManager->HandleRequest(aMessage);
       
   414 			}
       
   415 		}
       
   416 		
       
   417 	// If the ccp manager couldn't handle the message, pass directly to the 
       
   418 	// controller plugin as a custom command.
       
   419 	if (!handled)
       
   420 		CustomCommand(aMessage);
       
   421 	}
       
   422 
       
   423 TBool CMMFController::DoGetNumberOfMetaDataEntriesL(TMMFMessage& aMessage)
       
   424 	{
       
   425 	TInt numberOfEntries;
       
   426 	GetNumberOfMetaDataEntriesL(numberOfEntries);
       
   427 	TPckgBuf<TInt> pckg(numberOfEntries);
       
   428 	aMessage.WriteDataToClientL(pckg);
       
   429 	return ETrue;
       
   430 	}
       
   431 
       
   432 TBool CMMFController::DoGetSizeOfMetaDataEntryL(TMMFMessage& aMessage)
       
   433 	{
       
   434 	// Get the index of the required entry
       
   435 	TPckgBuf<TInt> pckg;
       
   436 	aMessage.ReadData1FromClientL(pckg);
       
   437 	// Get the entry
       
   438 	CMMFMetaDataEntry* entry = GetMetaDataEntryL(pckg());
       
   439 	CleanupStack::PushL(entry);
       
   440 	// Delete any existing buffer
       
   441 	delete iMetaDataBuffer;
       
   442 	iMetaDataBuffer = NULL;
       
   443 	// Create a buffer to hold the externalised entry
       
   444 	iMetaDataBuffer = CBufFlat::NewL(32);
       
   445 	RBufWriteStream s;
       
   446 	s.Open(*iMetaDataBuffer);
       
   447 	CleanupClosePushL(s);
       
   448 	entry->ExternalizeL(s);
       
   449 	CleanupStack::PopAndDestroy(2);//s, entry
       
   450 	// Write the size of the externalised data back to the client
       
   451 	pckg() = iMetaDataBuffer->Ptr(0).Length();
       
   452 	aMessage.WriteDataToClientL(pckg);
       
   453 	return ETrue;
       
   454 	}
       
   455 
       
   456 TBool CMMFController::DoGetMetaDataEntryL(TMMFMessage& aMessage)
       
   457 	{
       
   458 	// We should have already prepared the buffer
       
   459 	if (!iMetaDataBuffer)
       
   460 		User::Leave(KErrNotReady);
       
   461 	aMessage.WriteDataToClientL(iMetaDataBuffer->Ptr(0));
       
   462 	return ETrue;
       
   463 	}
       
   464 
       
   465 TBool CMMFController::DoPreloadSourceSinkInitDataL(TMMFMessage& aMessage)
       
   466 	{
       
   467 	GetExtendedDataL()->ResetSourceSinkInitData();
       
   468 	
       
   469 	// Get the size of the init data and create a buffer to hold it
       
   470 	TInt desLength = aMessage.SizeOfData1FromClient();
       
   471 	HBufC8* sourceSinkInitData = HBufC8::NewLC(desLength);
       
   472 	TPtr8 ptr = sourceSinkInitData->Des();
       
   473 	aMessage.ReadData1FromClientL(ptr);
       
   474 	
       
   475 	GetExtendedDataL()->SetSourceSinkInitData(sourceSinkInitData);
       
   476 	CleanupStack::Pop(sourceSinkInitData);
       
   477 	return ETrue;
       
   478 	}
       
   479 
       
   480 TBool CMMFController::DoAddFileHandleDataSourceWithInitDataL(TMMFMessage& aMessage)
       
   481 	{
       
   482 	if (GetExtendedDataL()->SourceSinkInitData() == NULL)
       
   483 		{
       
   484 		User::Leave(KErrNotReady);
       
   485 		}
       
   486 	HBufC8* initData = GetExtendedDataL()->SourceSinkInitData()->AllocLC();
       
   487 	
       
   488 	// Get the client file handle and replace 
       
   489 	RFile file;
       
   490 	aMessage.AdoptFileHandleFromClientL(1,2, file);
       
   491 	CleanupClosePushL(file);
       
   492 	TPtr8 initDataPtr(initData->Des());
       
   493 	ReplaceFileHandleInInitDataL(&file, initDataPtr);
       
   494 	
       
   495 	// Create the source
       
   496 	MDataSource* source = MDataSource::NewSourceL(KUidMmfFileSource, *initData);
       
   497 	CleanupStack::PopAndDestroy(2, initData);	//file, initData
       
   498 	AddMDataSourceAndRepondClientL(source, aMessage);
       
   499 	
       
   500 	GetExtendedDataL()->ResetSourceSinkInitData();
       
   501 	return ETrue;
       
   502 	}
       
   503 
       
   504 TBool CMMFController::DoAddFileHandleDataSinkWithInitDataL(TMMFMessage& aMessage)
       
   505 	{
       
   506 	if (GetExtendedDataL()->SourceSinkInitData() == NULL)
       
   507 		{
       
   508 		User::Leave(KErrNotReady);
       
   509 		}
       
   510 	HBufC8* initData = GetExtendedDataL()->SourceSinkInitData()->AllocLC();
       
   511 	
       
   512 	// Get the client file handle and replace
       
   513 	RFile file;
       
   514 	aMessage.AdoptFileHandleFromClientL(1,2, file);
       
   515 	CleanupClosePushL(file);
       
   516 	TPtr8 initDataPtr(initData->Des());
       
   517 	ReplaceFileHandleInInitDataL(&file, initDataPtr);
       
   518 	
       
   519 	// Create the sink
       
   520 	MDataSink* sink = MDataSink::NewSinkL(KUidMmfFileSink, *initData);
       
   521 	CleanupStack::PopAndDestroy(2, initData);	//file, initData
       
   522 	AddMDataSinkAndRepondClientL(sink, aMessage);
       
   523 	
       
   524 	GetExtendedDataL()->ResetSourceSinkInitData();
       
   525 	return ETrue;
       
   526 	}
       
   527 	
       
   528 void CMMFController::ReplaceFileHandleInInitDataL(RFile* aFile, TDes8& aInitData)
       
   529 	{
       
   530 	// aInitData should have the second 4bytes data (first 4bytes represent TUid) containing 
       
   531 	// a client RFile pointer.
       
   532 	// This RFile pointer may be invalid due to the fact that client and server threads
       
   533 	// may reside in different processes, and therefore, different memory space.
       
   534 	// In this context, we would rather trust the file handle retrieve from the call
       
   535 	// AdoptFileHandleFromClientL, and replace the RFile pointer with a more reliable one
       
   536 	TPtr8 filePtrStart = aInitData.MidTPtr(sizeof(TUid));
       
   537 	RDesWriteStream writeStream;
       
   538 	writeStream.Open(filePtrStart);
       
   539 	CleanupClosePushL(writeStream);
       
   540 	TPckgBuf<RFile*> filePtr(aFile);
       
   541 	writeStream.WriteL(filePtr);
       
   542 	writeStream.CommitL();
       
   543 	CleanupStack::PopAndDestroy(&writeStream);
       
   544 	}
       
   545 
       
   546 void CMMFController::AddMDataSourceAndRepondClientL(MDataSource* aSource, TMMFMessage& aMessage)
       
   547 	{
       
   548 	CleanupDeletePushL(aSource);	
       
   549 	CMMFDataSourceHolder* holder = new(ELeave) CMMFDataSourceHolder(*aSource);
       
   550 	CleanupStack::Pop(aSource);	//aSource (since now owned by holder)
       
   551 	
       
   552 	CleanupStack::PushL(holder);
       
   553 	// Append holder to array of MMFObjects
       
   554 	User::LeaveIfError(MMFObjectContainerL().AddMMFObject(*holder));
       
   555 	CleanupStack::Pop(holder);//holder
       
   556 
       
   557 	// Write source handle info back to client
       
   558 	TMMFMessageDestination handleInfo(holder->Handle());
       
   559 	TMMFMessageDestinationPckg handlePckg(handleInfo);
       
   560 	TInt error = aMessage.WriteDataToClient(handlePckg);
       
   561 
       
   562 	// Add source to plugin
       
   563 	if (!error)
       
   564 		TRAP(error, AddDataSourceL(*aSource));
       
   565 
       
   566 	if (error)
       
   567 		{
       
   568 		// Source not accepted by plugin or we couldn't write handle info back to client, 
       
   569 		// so delete it and return error to client
       
   570 		MMFObjectContainerL().RemoveAndDestroyMMFObject(*holder);
       
   571 		User::Leave(error);
       
   572 		}	
       
   573 	}
       
   574 
       
   575 void CMMFController::AddMDataSinkAndRepondClientL(MDataSink* aSink, TMMFMessage& aMessage)
       
   576 	{
       
   577 	CleanupDeletePushL(aSink);
       
   578 	CMMFDataSinkHolder* holder = new(ELeave) CMMFDataSinkHolder(*aSink);
       
   579 	CleanupStack::Pop(aSink);	//aSink (since now owned by holder)
       
   580 	
       
   581 	CleanupStack::PushL(holder);
       
   582 	// Append sink to array
       
   583 	User::LeaveIfError(MMFObjectContainerL().AddMMFObject(*holder));
       
   584 	CleanupStack::Pop(holder);//holder
       
   585 
       
   586 	// Write sink handle info back to client
       
   587 	TMMFMessageDestination handleInfo(holder->Handle());
       
   588 	TMMFMessageDestinationPckg handlePckg(handleInfo);
       
   589 	TInt error = aMessage.WriteDataToClient(handlePckg);
       
   590 
       
   591 	// Add sink to plugin
       
   592 	if (!error)
       
   593 		TRAP(error, AddDataSinkL(*aSink));
       
   594 
       
   595 	if (error)
       
   596 		{
       
   597 		// Sink not accepted by plugin or we couldn't write handle info back to client, 
       
   598 		// so delete it and return error to client
       
   599 		MMFObjectContainerL().RemoveAndDestroyMMFObject(*holder);
       
   600 		User::Leave(error);
       
   601 		}
       
   602 	}
       
   603 
       
   604 CMMFControllerExtendedData* CMMFController::GetExtendedDataL()
       
   605 	{
       
   606 	CMMFControllerExtendedData* data = NULL;
       
   607 	
       
   608 	// iMMFObjectContainer and CMMFControllerExtendedData must be constructed 
       
   609 	// in CMMFController constructor. Only 1 CMMFControllerExtendedData object can
       
   610 	// be found in iMMFObjectContainer.		
       
   611 	const RPointerArray<CMMFObject>& objects = MMFObjectContainerL().MMFObjects();
       
   612 	for (TInt i = 0; i < objects.Count(); i++)
       
   613 		{
       
   614 		if (objects[i]->Handle().InterfaceId() == KUidMMFControllerExtendedDataHolder)
       
   615 			{
       
   616 			data = static_cast<CMMFControllerExtendedData*>(objects[i]);
       
   617 			break;
       
   618 			}
       
   619 		}
       
   620 	if (data == NULL)
       
   621 		{
       
   622 		// In this case, extended data has not been constructed and added into iMMFObjectContainer.
       
   623 		// This is a situation where GetExtendedDataL is being indirectly called in the controller
       
   624 		// initialization process (i.e. CMMFController::NewL() or constructor of licensee's controller).
       
   625 		// Extended data should have a copy stored in Dll::Tls already at this point.
       
   626 		const CMMFControllerExtendedData* dataCopy = static_cast<CMMFControllerExtendedData*>(Dll::Tls());
       
   627 		data = CreateExtendedDataL(dataCopy->ClientThreadId());
       
   628 		CleanupStack::PushL(data);
       
   629 		User::LeaveIfError(MMFObjectContainerL().AddMMFObject(*data));
       
   630 		CleanupStack::Pop(data);
       
   631 		}
       
   632 	return data;
       
   633 	}
       
   634 
       
   635 CMMFControllerExtendedData* CMMFController::CreateExtendedDataL(TThreadId aClientTid)
       
   636 	{
       
   637 	// In secureDRMMode, SecureDRM server and user are running in
       
   638 	// different processes.
       
   639 	TProcessId clientProcessId;
       
   640 	RThread clientThread;
       
   641 	CleanupClosePushL(clientThread);
       
   642 	User::LeaveIfError(clientThread.Open(aClientTid));
       
   643 	
       
   644 	RProcess clientProcess;
       
   645 	CleanupClosePushL(clientProcess);
       
   646 	User::LeaveIfError(clientThread.Process(clientProcess));
       
   647 	clientProcessId = clientProcess.Id();
       
   648 	CleanupStack::PopAndDestroy(2, &clientThread);	// clientProcess, clientThread
       
   649 	
       
   650 	RProcess thisProcess;
       
   651 	TBool secureDrmMode = clientProcessId != thisProcess.Id();
       
   652 	thisProcess.Close();
       
   653 	
       
   654 	CMMFControllerExtendedData* dataSet = new(ELeave) CMMFControllerExtendedData();
       
   655 	CleanupStack::PushL(dataSet);
       
   656 	dataSet->SetClientThreadId(aClientTid);
       
   657 	dataSet->SetSecureDrmMode(secureDrmMode);
       
   658 	CleanupStack::Pop(dataSet);
       
   659 	
       
   660 	return dataSet;
       
   661 	}
       
   662 
       
   663 
       
   664 EXPORT_C CMMFCustomCommandParserManager* CMMFCustomCommandParserManager::NewL()
       
   665 	{
       
   666 	return new(ELeave) CMMFCustomCommandParserManager;
       
   667 	}
       
   668 
       
   669 CMMFCustomCommandParserManager::CMMFCustomCommandParserManager()
       
   670 	{
       
   671 	}
       
   672 
       
   673 EXPORT_C CMMFCustomCommandParserManager::~CMMFCustomCommandParserManager()
       
   674 	{
       
   675 	iParsers.ResetAndDestroy();
       
   676 	iParsers.Close();
       
   677 	}
       
   678 
       
   679 EXPORT_C TBool CMMFCustomCommandParserManager::HandleRequest(TMMFMessage& aMessage)
       
   680 	{
       
   681 	TBool handledRequest = EFalse;
       
   682 	for (TInt i=0; i<iParsers.Count(); i++)
       
   683 		{
       
   684 		CMMFCustomCommandParserBase* c = iParsers[i];
       
   685 		if (c->InterfaceId() == aMessage.Destination().InterfaceId())
       
   686 			{
       
   687 			c->HandleRequest(aMessage);
       
   688 			handledRequest = ETrue;
       
   689 			break;
       
   690 			}
       
   691 		}
       
   692 	return handledRequest;
       
   693 	}
       
   694 
       
   695 EXPORT_C void CMMFCustomCommandParserManager::AddCustomCommandParserL(CMMFCustomCommandParserBase& aParser)
       
   696 	{
       
   697 	User::LeaveIfError(iParsers.Append(&aParser));
       
   698 	}
       
   699 
       
   700 
       
   701 TBool CMMFController::DoAddFileHandleDataSourceL(TMMFMessage& aMessage)
       
   702 	{
       
   703 	RFile file;
       
   704 	aMessage.AdoptFileHandleFromClientL(1,2, file);
       
   705 	CleanupClosePushL(file);
       
   706 	TMMFFileHandleConfig fileConfig;
       
   707 	fileConfig().iFile = &file;
       
   708 	// Create the source
       
   709 	MDataSource* source = MDataSource::NewSourceL(KUidMmfFileSource, fileConfig);
       
   710 	CleanupStack::PopAndDestroy(&file);
       
   711 	CleanupDeletePushL(source);	
       
   712 	CMMFDataSourceHolder* holder = new(ELeave) CMMFDataSourceHolder(*source);
       
   713 	CleanupStack::Pop(source);//source (since now owned by holder)
       
   714 
       
   715 	CleanupStack::PushL(holder);
       
   716 	// Append holder to array of MMFObjects
       
   717 	User::LeaveIfError(MMFObjectContainerL().AddMMFObject(*holder));
       
   718 	CleanupStack::Pop(holder);//holder
       
   719 
       
   720 	// Write source handle info back to client
       
   721 	TMMFMessageDestination handleInfo(holder->Handle());
       
   722 	TMMFMessageDestinationPckg handlePckg(handleInfo);
       
   723 	TInt error = aMessage.WriteDataToClient(handlePckg);
       
   724 
       
   725 	// Add source to plugin
       
   726 	if (!error)
       
   727 		TRAP(error, AddDataSourceL(*source));
       
   728 
       
   729 	if (error)
       
   730 		{
       
   731 		// Source not accepted by plugin or we couldn't write handle info back to client, 
       
   732 		// so delete it and return error to client
       
   733 		MMFObjectContainerL().RemoveAndDestroyMMFObject(*holder);
       
   734 		User::Leave(error);
       
   735 		}
       
   736 	
       
   737 	return ETrue;
       
   738 	}
       
   739 
       
   740 
       
   741 TBool CMMFController::DoAddFileHandleDataSinkL(TMMFMessage& aMessage)
       
   742 	{
       
   743 	RFile file;
       
   744 	aMessage.AdoptFileHandleFromClientL(1,2, file);
       
   745 	CleanupClosePushL(file);
       
   746 	TMMFFileHandleConfig fileConfig;
       
   747 	fileConfig().iFile = &file;
       
   748 	// Create the sink
       
   749 	MDataSink* sink = MDataSink::NewSinkL(KUidMmfFileSink, fileConfig);
       
   750 	CleanupStack::PopAndDestroy(&file); // close our handle to the file
       
   751 	CleanupDeletePushL(sink);
       
   752 	CMMFDataSinkHolder* holder = new(ELeave) CMMFDataSinkHolder(*sink);
       
   753 	CleanupStack::Pop(sink);//sink (since now owned by holder)
       
   754 
       
   755 	CleanupStack::PushL(holder);
       
   756 	// Append sink to array
       
   757 	User::LeaveIfError(MMFObjectContainerL().AddMMFObject(*holder));
       
   758 	CleanupStack::Pop(holder);//holder
       
   759 
       
   760 
       
   761 	// Write sink handle info back to client
       
   762 	TMMFMessageDestination handleInfo(holder->Handle());
       
   763 	TMMFMessageDestinationPckg handlePckg(handleInfo);
       
   764 	TInt error = aMessage.WriteDataToClient(handlePckg);
       
   765 
       
   766 	// Add sink to plugin
       
   767 	if (!error)
       
   768 		TRAP(error, AddDataSinkL(*sink));
       
   769 
       
   770 	if (error)
       
   771 		{
       
   772 		// Sink not accepted by plugin or we couldn't write handle info back to client, 
       
   773 		// so delete it and return error to client
       
   774 		MMFObjectContainerL().RemoveAndDestroyMMFObject(*holder);
       
   775 		User::Leave(error);
       
   776 		}
       
   777 	
       
   778 	return ETrue;
       
   779 	}
       
   780 
       
   781 EXPORT_C TThreadId CMMFController::ClientThreadIdL()
       
   782 	{
       
   783 	return GetExtendedDataL()->ClientThreadId();
       
   784 	}
       
   785 
       
   786 EXPORT_C TBool CMMFController::IsSecureDrmModeL()
       
   787 	{
       
   788 	return GetExtendedDataL()->SecureDrmMode();
       
   789 	}
       
   790