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