1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmlibs/mmfw/SecureDRM/src/Server/MmfDrmPluginServer.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,359 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <e32math.h>
1.20 +#include <mmf/common/mmfcontrollerframework.h>
1.21 +#include "MmfDrmPluginServer.h"
1.22 +#include "MmfDrmPluginServerStart.h"
1.23 +#include "MmfDrmPluginServerSession.h"
1.24 +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
1.25 +#include <mmf/common/mmfcontrollerframeworkclasses.h>
1.26 +#endif
1.27 +
1.28 +CMMFDRMPluginServer* CMMFDRMPluginServer::NewL()
1.29 + {
1.30 + CMMFDRMPluginServer* s = new(ELeave) CMMFDRMPluginServer();
1.31 + CleanupStack::PushL(s);
1.32 + s->ConstructL();
1.33 + CleanupStack::Pop();
1.34 + return s;
1.35 + }
1.36 +
1.37 +CMMFDRMPluginServer::CMMFDRMPluginServer() :
1.38 + CMmfIpcServer(EPriorityStandard)
1.39 + {
1.40 + }
1.41 +
1.42 +void CMMFDRMPluginServer::ConstructL()
1.43 + {
1.44 + iDelayServerShutDown = CDelayServerShutDown::NewL();
1.45 + // Call base class to Start server
1.46 + StartL(KDrmPluginServerName);
1.47 + }
1.48 +
1.49 +CMMFDRMPluginServer::~CMMFDRMPluginServer()
1.50 + {
1.51 + iControllerServList.ResetAndDestroy();
1.52 + iControllerServList.Close();
1.53 + delete iDelayServerShutDown;
1.54 + }
1.55 +
1.56 +CMmfIpcSession* CMMFDRMPluginServer::NewSessionL(const TVersion& aVersion) const
1.57 + {
1.58 + TVersion v(KMMFDRMPluginServerVersion,
1.59 + KMMFDRMPluginServerMinorVersionNumber,
1.60 + KMMFDRMPluginServerBuildVersionNumber);
1.61 + if(!User::QueryVersionSupported(v, aVersion))
1.62 + {
1.63 + User::Leave(KErrNotSupported);
1.64 + }
1.65 +
1.66 + for(TInt i = 0; i < iControllerServList.Count(); i++)
1.67 + {
1.68 + CStartAndMonitorControllerThread* controllerMonThread
1.69 + = iControllerServList[i];
1.70 + if(!controllerMonThread->IsActive())
1.71 + {
1.72 + iControllerServList.Remove(i);
1.73 + delete controllerMonThread;
1.74 + }
1.75 + }
1.76 + iControllerServList.Compress();
1.77 +
1.78 + CMMFDRMPluginServerSession* session = CMMFDRMPluginServerSession::NewL();
1.79 + return session;
1.80 + }
1.81 +
1.82 +void CMMFDRMPluginServer::IncrementSessionId()
1.83 + {
1.84 + iSessionCount++;
1.85 + }
1.86 +
1.87 +void CMMFDRMPluginServer::DecrementSessionId()
1.88 + {
1.89 + iSessionCount--;
1.90 + if(iSessionCount == 0 && iControllerCount == 0)
1.91 + {
1.92 + // Guarantee that server will be closed, after a period of time, even
1.93 + // a session has been created without a controller thread initialized
1.94 + if(!iDelayServerShutDown->IsActive())
1.95 + {
1.96 + // If shut down timer has been started previously, that setup has the piority
1.97 + iDelayServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(iServerTimeout));
1.98 + }
1.99 + }
1.100 + }
1.101 +
1.102 +void CMMFDRMPluginServer::IncrementControllerCount()
1.103 + {
1.104 + iControllerCount++;
1.105 + if(iControllerCount)
1.106 + {
1.107 + //In the case we started the shutdown due to no more controllers
1.108 + iDelayServerShutDown->Cancel();
1.109 + }
1.110 + }
1.111 +
1.112 +void CMMFDRMPluginServer::DecrementControllerCount()
1.113 + {
1.114 + iControllerCount--;
1.115 + if (iControllerCount == 0)
1.116 + {
1.117 + iDelayServerShutDown->SetDelay(TTimeIntervalMicroSeconds32(iServerTimeout));
1.118 + }
1.119 + }
1.120 +
1.121 +TInt CMMFDRMPluginServer::StartControllerServer(const RThread& aClientThread, TUint aMaxHeapSize, TBool aUseSharedHeap,
1.122 + RMMFControllerServerProxy& aControllerSessionHandle, TThreadId& aControllerTID, TUint aStackSize) const
1.123 + {
1.124 + CStartAndMonitorControllerThread* monitor = NULL;
1.125 +
1.126 + TRAPD(err, monitor =
1.127 + CStartAndMonitorControllerThread::NewL(const_cast<CMMFDRMPluginServer*>(this)));
1.128 + if(err != KErrNone)
1.129 + {
1.130 + delete monitor;
1.131 + return err;
1.132 + }
1.133 +
1.134 + err = iControllerServList.Append(monitor);
1.135 + if(err != KErrNone)
1.136 + {
1.137 + delete monitor;
1.138 + return err;
1.139 + }
1.140 +
1.141 + return monitor->StartControllerServer(aClientThread, aMaxHeapSize, aUseSharedHeap,
1.142 + aControllerSessionHandle, aControllerTID, aStackSize);
1.143 + }
1.144 +
1.145 +void CMMFDRMPluginServer::PanicControllerThread(TThreadId aTid, const TDesC& aCategory,TInt aReason)
1.146 + {
1.147 + for(TInt i = 0; i < iControllerServList.Count(); i++)
1.148 + {
1.149 + if(iControllerServList[i]->Thread().Id() == aTid)
1.150 + {
1.151 + iControllerServList[i]->Thread().Panic(aCategory, aReason);
1.152 + return;
1.153 + }
1.154 + }
1.155 + }
1.156 +
1.157 +void CMMFDRMPluginServer::KillControllerThread(TThreadId aTid, TInt aReason)
1.158 + {
1.159 + for(TInt i = 0; i < iControllerServList.Count(); i++)
1.160 + {
1.161 + if(iControllerServList[i]->Thread().Id() == aTid)
1.162 + {
1.163 + iControllerServList[i]->Thread().Kill(aReason);
1.164 + return;
1.165 + }
1.166 + }
1.167 + }
1.168 +
1.169 +TInt CMMFDRMPluginServer::SetThreadPriority(TThreadId aTid, TThreadPriority aPriority)
1.170 + {
1.171 + TBool threadFound = EFalse;
1.172 + for(TInt i = 0; i < iControllerServList.Count(); i++)
1.173 + {
1.174 + const RThread& controllerThread = iControllerServList[i]->Thread();
1.175 + if (controllerThread.Id() == aTid)
1.176 + {
1.177 + if (controllerThread.Priority() != aPriority)
1.178 + {
1.179 + controllerThread.Suspend();
1.180 + controllerThread.SetPriority(aPriority);
1.181 + controllerThread.Resume();
1.182 + }
1.183 + threadFound = ETrue;
1.184 + break;
1.185 + }
1.186 + }
1.187 + return threadFound? KErrNone: KErrNotFound;
1.188 + }
1.189 +
1.190 +CMMFDRMPluginServer::CDelayServerShutDown* CMMFDRMPluginServer::CDelayServerShutDown::NewL()
1.191 + {
1.192 + CDelayServerShutDown* self = new(ELeave) CDelayServerShutDown;
1.193 + CleanupStack::PushL(self);
1.194 + self->ConstructL();
1.195 + CleanupStack::Pop();
1.196 + return self;
1.197 + }
1.198 +
1.199 +CMMFDRMPluginServer::CDelayServerShutDown::CDelayServerShutDown() : CActive(0)
1.200 + {
1.201 + }
1.202 +
1.203 +void CMMFDRMPluginServer::CDelayServerShutDown::ConstructL()
1.204 + {
1.205 + User::LeaveIfError(iShutDownTimer.CreateLocal());
1.206 + CActiveScheduler::Add(this);
1.207 + }
1.208 +
1.209 +CMMFDRMPluginServer::CDelayServerShutDown::~CDelayServerShutDown()
1.210 + {
1.211 + Cancel();
1.212 + iShutDownTimer.Close();
1.213 + }
1.214 +
1.215 +void CMMFDRMPluginServer::CDelayServerShutDown::SetDelay(TTimeIntervalMicroSeconds32 aDelay)
1.216 + {
1.217 + __ASSERT_ALWAYS(!IsActive(), User::Panic(_L("CMMFDRMPluginServer"), 1));
1.218 + iShutDownTimer.After(iStatus, aDelay);
1.219 + SetActive();
1.220 + }
1.221 +
1.222 +void CMMFDRMPluginServer::CDelayServerShutDown::RunL()
1.223 + {
1.224 + CActiveScheduler::Stop();
1.225 + }
1.226 +
1.227 +
1.228 +void CMMFDRMPluginServer::CDelayServerShutDown::DoCancel()
1.229 + {
1.230 + iShutDownTimer.Cancel();
1.231 + }
1.232 +
1.233 +CStartAndMonitorControllerThread* CStartAndMonitorControllerThread::NewL(CMMFDRMPluginServer* aPluginServer)
1.234 + {
1.235 + CStartAndMonitorControllerThread* self = new(ELeave) CStartAndMonitorControllerThread(aPluginServer);
1.236 + CleanupStack::PushL(self);
1.237 + self->ConstructL();
1.238 + CleanupStack::Pop();
1.239 + return self;
1.240 + }
1.241 +
1.242 +void CStartAndMonitorControllerThread::ConstructL()
1.243 + {
1.244 + CActiveScheduler::Add(this);
1.245 + }
1.246 +
1.247 +TInt CStartAndMonitorControllerThread::StartControllerServer(const RThread& /*aClientThread*/, TUint aMaxHeapSize, TBool aUseSharedHeap,
1.248 + RMMFControllerServerProxy& aControllerSessionHandle, TThreadId& aControllerTID,TUint aStackSize)
1.249 + {
1.250 + Cancel();
1.251 + TInt err = KErrNone;
1.252 +
1.253 + RServer2 controllerServer;
1.254 + TControllerProxyServerParams params;
1.255 + params.iServer = &controllerServer;
1.256 + params.iUsingSharedHeap = aUseSharedHeap;
1.257 +
1.258 + TName name;
1.259 + name.Append(KMMFControllerProxyServerName);
1.260 +
1.261 + // Threads create own heap (default behaviour)
1.262 + if(aMaxHeapSize < static_cast<TUint>(KMinHeapSize))
1.263 + {
1.264 + aMaxHeapSize = KMinHeapSize; //else raises a USER 111 panic
1.265 + }
1.266 + else if(aMaxHeapSize > static_cast<TUint>(KMMFControllerProxyMaxHeapSize))
1.267 + {
1.268 + aMaxHeapSize = KMMFControllerProxyMaxHeapSize;
1.269 + }
1.270 +
1.271 + err = iServerThread.Create(name, &CMMFControllerProxyServer::StartThread,
1.272 + aStackSize, KMinHeapSize, aMaxHeapSize,
1.273 + ¶ms, EOwnerThread);
1.274 + if (err)
1.275 + {
1.276 + return err;
1.277 + }
1.278 +
1.279 + // Synchronise with the server
1.280 + TRequestStatus reqStatus;
1.281 + iServerThread.Rendezvous(reqStatus);
1.282 +
1.283 + if (reqStatus!=KRequestPending)
1.284 + {
1.285 + iServerThread.Kill(0);
1.286 + }
1.287 + else
1.288 + {
1.289 + iServerThread.SetPriority(EPriorityNormal);
1.290 + iServerThread.Resume();
1.291 + // Server will call the reciprocal static synchronise call
1.292 + }
1.293 +
1.294 + User::WaitForRequest(reqStatus); // wait for start or death
1.295 + if(reqStatus.Int() != KErrNone)
1.296 + {
1.297 + iServerThread.Close();
1.298 + controllerServer.Close();
1.299 + return reqStatus.Int();
1.300 + }
1.301 +
1.302 + err = aControllerSessionHandle.Open(controllerServer);
1.303 + if(err != KErrNone)
1.304 + {
1.305 + iServerThread.Close();
1.306 + controllerServer.Close();
1.307 + return err;
1.308 + }
1.309 +
1.310 + iStatus = KRequestPending;
1.311 + iServerThread.Logon(iStatus);
1.312 + if (iStatus != KRequestPending)
1.313 + {
1.314 + // Failed to logon
1.315 + aControllerSessionHandle.Close();
1.316 + iServerThread.Close();
1.317 + controllerServer.Close();
1.318 + return iStatus.Int();
1.319 + }
1.320 + else
1.321 + {
1.322 + SetActive();
1.323 + }
1.324 +
1.325 + aControllerSessionHandle.ShareProtected();
1.326 + aControllerTID = iServerThread.Id();
1.327 + iDrmPluginServer->IncrementControllerCount();
1.328 + return KErrNone;
1.329 + }
1.330 +
1.331 +
1.332 +CStartAndMonitorControllerThread::CStartAndMonitorControllerThread(CMMFDRMPluginServer* aPluginServer)
1.333 + : CActive(EPriorityStandard)
1.334 + {
1.335 + iDrmPluginServer = aPluginServer;
1.336 + }
1.337 +
1.338 +CStartAndMonitorControllerThread::~CStartAndMonitorControllerThread()
1.339 + {
1.340 + Cancel();
1.341 + }
1.342 +
1.343 +void CStartAndMonitorControllerThread::RunL()
1.344 + {
1.345 + iServerThread.Close();
1.346 + iDrmPluginServer->DecrementControllerCount();
1.347 + }
1.348 +
1.349 +void CStartAndMonitorControllerThread::DoCancel()
1.350 + {
1.351 + iServerThread.LogonCancel(iStatus);
1.352 + iServerThread.Kill(0);
1.353 + iServerThread.Close();
1.354 + iDrmPluginServer->DecrementControllerCount();
1.355 + }
1.356 +
1.357 +TInt RMMFControllerServerProxy::Open(RServer2& aControllerServerHandle)
1.358 + {
1.359 + TInt err = CreateSession(aControllerServerHandle, KMMFControllerProxyVersion,
1.360 + -1, EIpcSession_GlobalSharable);
1.361 + return err;
1.362 + }