sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include "MmfDrmPluginServerSession.h" sl@0: #include "MmfDrmPluginClientServer.h" sl@0: #include "MmfDrmPluginServer.h" sl@0: sl@0: /* sl@0: Create a DRM Plugin Server Session sl@0: */ sl@0: CMMFDRMPluginServerSession* CMMFDRMPluginServerSession::NewL() sl@0: { sl@0: CMMFDRMPluginServerSession* self = new(ELeave) CMMFDRMPluginServerSession(); sl@0: return self; sl@0: } sl@0: sl@0: CMMFDRMPluginServerSession::~CMMFDRMPluginServerSession() sl@0: { sl@0: CMMFDRMPluginServer* server = sl@0: const_cast(static_cast(Server())); sl@0: if (server) sl@0: { sl@0: server->DecrementSessionId(); sl@0: } sl@0: if (iData) sl@0: { sl@0: delete iData; sl@0: } sl@0: iControllerSessionHandle.Close(); sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::CreateL(const CMmfIpcServer& aServer) sl@0: { sl@0: CMmfIpcSession::CreateL(aServer); sl@0: CMMFDRMPluginServer* server = sl@0: static_cast(CONST_CAST(CMmfIpcServer*, &aServer)); sl@0: server->IncrementSessionId(); sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::ServiceL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: switch (aMessage.Function()) sl@0: { sl@0: case EMMFControllerLaunchRequest: sl@0: DoLaunchControllerL(aMessage); sl@0: aMessage.Complete(KErrNone); sl@0: break; sl@0: case EMMFControllerSessionHandle: sl@0: if (!iControllerSessionHandle.Handle()) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: aMessage.Complete(iControllerSessionHandle); sl@0: break; sl@0: case EMMFControllerThreadPanic: sl@0: DoPanicControllerThreadL(aMessage); sl@0: aMessage.Complete(KErrNone); sl@0: break; sl@0: case EMMFControllerThreadKill: sl@0: DoKillControllerThreadL(aMessage); sl@0: aMessage.Complete(KErrNone); sl@0: break; sl@0: case EMMFControllerSetThreadPriority: sl@0: DoSetThreadPriorityL(aMessage); sl@0: aMessage.Complete(KErrNone); sl@0: break; sl@0: case EMMFDRMContentOpenByFilePath: sl@0: DoOpenContentByFilePathL(aMessage); sl@0: aMessage.Complete(KErrNone); sl@0: break; sl@0: case EMMFDRMContentOpenByFileHandle: sl@0: DoOpenContentByFileHandleL(aMessage); sl@0: aMessage.Complete(KErrNone); sl@0: break; sl@0: case EMMFDRMContentEvaluateIntent: sl@0: { sl@0: TInt err = DoEvaluateContentIntent(aMessage); sl@0: aMessage.Complete(err); sl@0: } sl@0: break; sl@0: case EMMFDRMContentGetMimeType: sl@0: DoGetContentMimeTypeL(aMessage); sl@0: aMessage.Complete(KErrNone); sl@0: break; sl@0: case EMMFDRMContentGetFileHeader: sl@0: DoGetContentFileHeaderL(aMessage); sl@0: aMessage.Complete(KErrNone); sl@0: break; sl@0: case EMMFSetDrmPluginServerTimeout: sl@0: DoSetDrmPluginServerTimeout(aMessage); sl@0: aMessage.Complete(KErrNone); sl@0: break; sl@0: default: sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: CMMFDRMPluginServerSession::CMMFDRMPluginServerSession() sl@0: { sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::DoLaunchControllerL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: if (iControllerSessionHandle.Handle()) sl@0: { sl@0: User::Leave(KErrAlreadyExists); sl@0: } sl@0: TThreadId controllerTID; sl@0: RMMFControllerServerProxy controllerSessionHandle; sl@0: CMMFDRMPluginServer* server = sl@0: const_cast(static_cast(Server())); sl@0: sl@0: RThread clientThread; sl@0: CleanupClosePushL(clientThread); sl@0: User::LeaveIfError(aMessage.Client(clientThread)); sl@0: sl@0: TPckg maxHeapSize(0); sl@0: TPckg useShareHeap(ETrue); sl@0: TPckg stackSize(0); sl@0: sl@0: aMessage.ReadL(0, maxHeapSize); sl@0: aMessage.ReadL(1, useShareHeap); sl@0: aMessage.ReadL(3, stackSize); sl@0: sl@0: User::LeaveIfError(server->StartControllerServer(clientThread, maxHeapSize(), useShareHeap(), sl@0: controllerSessionHandle, controllerTID, stackSize())); sl@0: SetControllerServerInfo(controllerSessionHandle, controllerTID); sl@0: sl@0: TPckgBuf threadId(iControllerThreadID); sl@0: aMessage.WriteL(2, threadId); sl@0: CleanupStack::PopAndDestroy(&clientThread); sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::DoPanicControllerThreadL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TPckgBuf controllerTid(0); sl@0: aMessage.ReadL(0, controllerTid); sl@0: sl@0: TInt desLen = aMessage.GetDesLengthL(1); sl@0: HBufC* category = HBufC::NewLC(desLen); sl@0: TPtr categoryPtr(category->Des()); sl@0: aMessage.ReadL(1, categoryPtr); sl@0: sl@0: TPckg panicReason(0); sl@0: aMessage.ReadL(2, panicReason); sl@0: sl@0: CMMFDRMPluginServer* server = sl@0: const_cast(static_cast(Server())); sl@0: server->PanicControllerThread(controllerTid(), categoryPtr, panicReason()); sl@0: sl@0: CleanupStack::PopAndDestroy(category); sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::DoKillControllerThreadL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TPckgBuf controllerTid(0); sl@0: aMessage.ReadL(0, controllerTid); sl@0: sl@0: TPckg killReason(0); sl@0: aMessage.ReadL(1, killReason); sl@0: sl@0: CMMFDRMPluginServer* server = sl@0: const_cast(static_cast(Server())); sl@0: server->KillControllerThread(controllerTid(), killReason()); sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::SetControllerServerInfo(RHandleBase& aControllerSessionHandle, sl@0: TThreadId& aControllerThreadId) sl@0: { sl@0: iControllerSessionHandle = aControllerSessionHandle; sl@0: iControllerThreadID = aControllerThreadId; sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::DoSetThreadPriorityL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TPckgBuf threadId; sl@0: TPckgBuf priority; sl@0: sl@0: aMessage.ReadL(0, threadId); sl@0: aMessage.ReadL(1, priority); sl@0: sl@0: CMMFDRMPluginServer* server = sl@0: const_cast(static_cast(Server())); sl@0: User::LeaveIfError(server->SetThreadPriority(threadId(), priority())); sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::DoOpenContentByFilePathL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: if (iData == NULL) sl@0: { sl@0: TInt length = aMessage.GetDesLengthL(0); sl@0: HBufC* filePath = HBufC::NewLC(length); sl@0: TPtr filePathPtr(filePath->Des()); sl@0: aMessage.ReadL(0, filePathPtr); sl@0: sl@0: length = aMessage.GetDesLengthL(1); sl@0: HBufC8* initData = HBufC8::NewLC(length); sl@0: TPtr8 initDataPtr(initData->Des()); sl@0: aMessage.ReadL(1, initDataPtr); sl@0: sl@0: HBufC* uniqueId = NULL; sl@0: TBool UIEnabled; sl@0: ContentAccess::TIntent intent; sl@0: GetContentInitDataL(initDataPtr, uniqueId, UIEnabled, intent); sl@0: CleanupStack::PopAndDestroy(initData); sl@0: CleanupStack::PushL(uniqueId); sl@0: sl@0: iData = CData::NewL(TVirtualPathPtr(filePathPtr, *uniqueId), EContentShareReadWrite); sl@0: TInt err = iData->SetProperty(EAgentPropertyAgentUI, UIEnabled); sl@0: if (err != KErrNone && err != KErrCANotSupported) sl@0: { sl@0: // KErrCANotSupported isn't a problem for us so eat the error code. sl@0: User::Leave(err); sl@0: } sl@0: User::LeaveIfError(iData->EvaluateIntent(intent)); sl@0: sl@0: CleanupStack::PopAndDestroy(2, filePath); // uniqueId, filePath sl@0: } sl@0: else sl@0: { sl@0: User::Leave(KErrAlreadyExists); sl@0: } sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::DoOpenContentByFileHandleL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: if (iData == NULL) sl@0: { sl@0: RFile file; sl@0: User::LeaveIfError(file.AdoptFromClient(aMessage, 0, 1)); sl@0: CleanupClosePushL(file); sl@0: sl@0: TInt length = aMessage.GetDesLengthL(2); sl@0: HBufC8* initData = HBufC8::NewLC(length); sl@0: TPtr8 initDataPtr(initData->Des()); sl@0: aMessage.ReadL(2, initDataPtr); sl@0: sl@0: HBufC* uniqueId = NULL; sl@0: TBool UIEnabled; sl@0: ContentAccess::TIntent intent; sl@0: GetContentInitDataL(initDataPtr, uniqueId, UIEnabled, intent); sl@0: CleanupStack::PopAndDestroy(initData); sl@0: CleanupStack::PushL(uniqueId); sl@0: sl@0: iData = CData::NewL(file, *uniqueId); sl@0: TInt err = iData->SetProperty(EAgentPropertyAgentUI, UIEnabled); sl@0: if (err != KErrNone && err != KErrCANotSupported) sl@0: { sl@0: // KErrCANotSupported isn't a problem for us so eat the error code. sl@0: User::Leave(err); sl@0: } sl@0: User::LeaveIfError(iData->EvaluateIntent(intent)); sl@0: sl@0: CleanupStack::PopAndDestroy(2, &file); // uniqueId, file sl@0: } sl@0: else sl@0: { sl@0: User::Leave(KErrAlreadyExists); sl@0: } sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::GetContentInitDataL(const TDesC8& aInitData, HBufC*& aUniqueId, sl@0: TBool& aUIEnabled, ContentAccess::TIntent& aIntent) sl@0: { sl@0: if (aUniqueId) sl@0: { sl@0: delete aUniqueId; sl@0: aUniqueId = NULL; sl@0: } sl@0: sl@0: RDesReadStream stream(aInitData); sl@0: CleanupClosePushL(stream); sl@0: sl@0: TInt length = stream.ReadInt32L(); sl@0: aUniqueId = HBufC::NewLC(length); sl@0: TPtr ptr = aUniqueId->Des(); sl@0: stream.ReadL(ptr, length); sl@0: sl@0: aUIEnabled = stream.ReadInt32L(); sl@0: TPckgBuf intentPckg; sl@0: stream.ReadL(intentPckg); sl@0: aIntent = intentPckg(); sl@0: sl@0: CleanupStack::Pop(aUniqueId); sl@0: CleanupStack::PopAndDestroy(&stream); sl@0: } sl@0: sl@0: TInt CMMFDRMPluginServerSession::DoEvaluateContentIntent(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TInt err; sl@0: if (iData) sl@0: { sl@0: TPckgBuf intentPckg; sl@0: err = aMessage.Read(0, intentPckg); sl@0: if (err == KErrNone) sl@0: { sl@0: err = iData->EvaluateIntent(intentPckg()); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: err = KErrGeneral; sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::DoGetContentMimeTypeL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: if (iData) sl@0: { sl@0: TBool success = ETrue; sl@0: TInt length = aMessage.GetDesMaxLengthL(0); sl@0: sl@0: HBufC* mimeType = HBufC::NewLC(length); sl@0: TPtr mimeTypePtr = mimeType->Des(); sl@0: TInt err = iData->GetStringAttribute(EMimeType, mimeTypePtr); sl@0: sl@0: if (err == KErrNone) sl@0: { sl@0: HBufC8* mimeType8 = HBufC8::NewLC(length); sl@0: TPtr8 mimeTypePtr8 = mimeType8->Des(); sl@0: mimeTypePtr8.Copy(mimeTypePtr); sl@0: sl@0: aMessage.WriteL(0, mimeTypePtr8); sl@0: CleanupStack::PopAndDestroy(mimeType8); sl@0: } sl@0: else sl@0: { sl@0: success = EFalse; sl@0: } sl@0: CleanupStack::PopAndDestroy(mimeType); sl@0: sl@0: TPckg successPckg(success); sl@0: aMessage.WriteL(1, successPckg); sl@0: } sl@0: else sl@0: { sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::DoGetContentFileHeaderL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: if (iData) sl@0: { sl@0: TInt size = 0; sl@0: iData->DataSizeL(size); sl@0: sl@0: TInt maxLength = aMessage.Int0(); sl@0: sl@0: TInt desLength = aMessage.GetDesMaxLengthL(1); sl@0: HBufC8* header = HBufC8::NewLC(desLength); sl@0: TPtr8 headerPtr = header->Des(); sl@0: sl@0: if (size > 0) sl@0: { sl@0: if (size > maxLength) sl@0: { sl@0: size = maxLength; sl@0: } sl@0: TInt pos = 0; sl@0: User::LeaveIfError(iData->Seek(ESeekStart, pos)); sl@0: User::LeaveIfError(iData->Read(headerPtr, size)); sl@0: aMessage.WriteL(1, headerPtr); sl@0: } sl@0: CleanupStack::PopAndDestroy(header); sl@0: } sl@0: else sl@0: { sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: } sl@0: sl@0: void CMMFDRMPluginServerSession::DoSetDrmPluginServerTimeout(const RMmfIpcMessage& aMessage) sl@0: { sl@0: CMMFDRMPluginServer* server = sl@0: const_cast(static_cast(Server())); sl@0: server->SetTimeout(aMessage.Int0()); sl@0: } sl@0: