1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicscomposition/openwfsupport/src/streammap.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,337 @@
1.4 +// Copyright (c) 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 +// streammap.cpp: creates and maintaines the association between native stream and a TSurfaceId
1.18 +//
1.19 +//
1.20 +
1.21 +#include "streammap.h"
1.22 +#include <graphics/updateserverprovider.h>
1.23 +#include <graphics/surfacemanager.h>
1.24 +#include <e32property.h>
1.25 +#include <e32std.h>
1.26 +#include <e32cmn.h>
1.27 +#include "openwfcpanic.h"
1.28 +#include "surfacestream.h"
1.29 +#include "contentupdateproxy.h"
1.30 +
1.31 +static const TInt KOpenWfcInteropCleanupKey = 0x10286FC5;
1.32 +
1.33 +COpenWfcStreamMap* COpenWfcStreamMap::pInstance = NULL;
1.34 +
1.35 +TUint32 COpenWfcStreamMap::HashFunction(const TSurfaceId& aHashKey)
1.36 + {
1.37 + TPckgC<TSurfaceId> pckg(aHashKey);
1.38 + return DefaultHash::Des8(pckg);
1.39 + }
1.40 +
1.41 +EXPORT_C COpenWfcStreamMap& COpenWfcStreamMap::InstanceL()
1.42 + {
1.43 + // would have been nice to try to protect this area with a mutex, however,
1.44 + // the preliminary analyses show we can guarantee the safe creation of the mutex
1.45 + // by invoking InstanceL() from the place the CGce instances are created
1.46 + // If necessary, in future, the code can be expanded by using a named mutex.
1.47 + if (!pInstance)
1.48 + {
1.49 + COpenWfcStreamMap* newInstance = new(ELeave)COpenWfcStreamMap();
1.50 + CleanupStack::PushL(newInstance);
1.51 + newInstance->ConstructL();
1.52 + CleanupStack::Pop(newInstance);
1.53 + pInstance=newInstance;
1.54 + }
1.55 + return *pInstance;
1.56 + }
1.57 +
1.58 +CSurfaceStream* COpenWfcStreamMap::Find(const TSurfaceId& aSurfaceId)
1.59 + {
1.60 + Guard g(iMutex);
1.61 + CSurfaceStream** ns = iMap.Find(aSurfaceId);
1.62 + // used if statement to ease debug help
1.63 + if (ns)
1.64 + {
1.65 + (*ns)->AddReference();
1.66 + return *ns;
1.67 + }
1.68 + return NULL;
1.69 + }
1.70 +
1.71 +CSurfaceStream* COpenWfcStreamMap::AcquireL(const TSurfaceId& aSurfaceId)
1.72 + {
1.73 + Guard* pGuard = new(ELeave) Guard(iMutex);
1.74 + User::LeaveIfNull(pGuard);
1.75 + CleanupDeletePushL(pGuard);
1.76 +
1.77 + CSurfaceStream** ns = NULL;
1.78 + CSurfaceStream* ret = NULL;
1.79 + ns = iMap.Find(aSurfaceId);
1.80 + if (ns)
1.81 + {
1.82 + WFCI_ASSERT_DEBUG((*ns), EOwfPanicInvalidHasMap); // should have never happened
1.83 + ret = *ns;
1.84 + }
1.85 + else
1.86 + {
1.87 + ret = CSurfaceStream::NewLC(aSurfaceId);
1.88 + User::LeaveIfError(iMap.Insert(aSurfaceId, ret));
1.89 + CleanupStack::Pop();
1.90 + }
1.91 + ret->AddReference();
1.92 + CleanupStack::PopAndDestroy(pGuard);
1.93 + return ret;
1.94 + }
1.95 +
1.96 +EXPORT_C TInt COpenWfcStreamMap::Count()
1.97 + {
1.98 + Guard g(iMutex);
1.99 + TInt count = iMap.Count();
1.100 + return count;
1.101 + }
1.102 +
1.103 +EXPORT_C RSurfaceManager& COpenWfcStreamMap::SurfaceManager()
1.104 + {
1.105 + WFCI_ASSERT_DEBUG(iSurfaceManager, EOwfPanicInvalidHasMap);
1.106 + return *iSurfaceManager;
1.107 + }
1.108 +
1.109 +TInt COpenWfcStreamMap::LockDestroy(CSurfaceStream* aStream)
1.110 + {
1.111 + Guard g(iMutex);
1.112 + TInt ret = KErrNone;
1.113 + if (aStream)
1.114 + {
1.115 + if (aStream->RemainingReference())
1.116 + {
1.117 + const TSurfaceId& surfaceId = aStream->SurfaceId();
1.118 + CSurfaceStream** ns = iMap.Find(surfaceId);
1.119 + // used if statement to ease debug help
1.120 + if (ns && ((*ns) == aStream))
1.121 + {
1.122 + TInt ret = iMap.Remove(surfaceId);
1.123 + delete aStream;
1.124 + }
1.125 + else
1.126 + {
1.127 + ret = KErrNotFound;
1.128 + }
1.129 + }
1.130 + else // RemainingReference
1.131 + {
1.132 + ret = KErrInUse;
1.133 + }
1.134 + }
1.135 + else // aStream
1.136 + {
1.137 + ret = KErrArgument;
1.138 + }
1.139 + return ret;
1.140 + }
1.141 +
1.142 +COpenWfcStreamMap::COpenWfcStreamMap():
1.143 +iMap(THashFunction32<TSurfaceId>(COpenWfcStreamMap::HashFunction), TIdentityRelation<TSurfaceId>()),
1.144 +iSurfaceManager(NULL),
1.145 +iRegisteredUpdaters()
1.146 + {
1.147 + }
1.148 +
1.149 +TInt COpenWfcStreamMap::DeleteSingleton(TAny* aData)
1.150 +/**
1.151 + * aData A pointer to the heap registered for this callback
1.152 + */
1.153 + {
1.154 + // Blank the property for this callback
1.155 + RThread t;
1.156 + RProperty prop;
1.157 + TCallBack cb(NULL, NULL);
1.158 + TPckgC<TCallBack> cbPckg(cb);
1.159 + prop.Set(TUid::Uid(t.SecureId().iId), KOpenWfcInteropCleanupKey, cbPckg);
1.160 + prop.Close();
1.161 + t.Close();
1.162 +
1.163 + if (aData == &User::Heap())
1.164 + {
1.165 + delete pInstance;
1.166 + pInstance = NULL;
1.167 + return ETrue;
1.168 + }
1.169 + return EFalse;
1.170 + }
1.171 +
1.172 +COpenWfcStreamMap::~COpenWfcStreamMap()
1.173 + {
1.174 + iMutex.Wait();
1.175 + {
1.176 + THashMapIter<TSurfaceId, CSurfaceStream*> iter(iMap);
1.177 + const TSurfaceId* nextKey = iter.NextKey();
1.178 + CSurfaceStream* const* ns = NULL;
1.179 + while (nextKey)
1.180 + {
1.181 + ns = iter.CurrentValue();
1.182 + if (ns && *ns)
1.183 + {
1.184 + delete (*ns);
1.185 + }
1.186 + nextKey = iter.NextKey();
1.187 + }
1.188 + }
1.189 + iMap.Close();
1.190 + if (iSurfaceManager)
1.191 + {
1.192 + iSurfaceManager->Close();
1.193 + delete iSurfaceManager;
1.194 + iSurfaceManager = NULL;
1.195 + }
1.196 + iMutex.Signal();
1.197 + iMutex.Close();
1.198 +
1.199 + {
1.200 + THashMapIter<TInt32, CExtensionContainer*> iter(iRegisteredUpdaters);
1.201 + const TInt32* nextKey = iter.NextKey();
1.202 + CExtensionContainer* const* extensionContainer = NULL;
1.203 + while (nextKey)
1.204 + {
1.205 + extensionContainer = iter.CurrentValue();
1.206 + if (extensionContainer && *extensionContainer)
1.207 + {
1.208 + delete (*extensionContainer);
1.209 + }
1.210 + nextKey = iter.NextKey();
1.211 + }
1.212 + }
1.213 + iRegisteredUpdaters.Close();
1.214 + }
1.215 +
1.216 +void COpenWfcStreamMap::ConstructL()
1.217 + {
1.218 + User::LeaveIfError(iMutex.CreateLocal());
1.219 + iMap.Reserve(iInitialSize);
1.220 + TSurfaceId surface = TSurfaceId::CreateNullId();
1.221 + User::LeaveIfError(iMap.Insert(surface, NULL));
1.222 +
1.223 + iSurfaceManager = new(ELeave) RSurfaceManager();
1.224 + User::LeaveIfError(iSurfaceManager->Open());
1.225 + RProcess process;
1.226 + TUidType uidType = process.Type();
1.227 + const TInt32 KWservUid = 268450592;
1.228 + const TUid& uid1 = uidType[2];
1.229 +
1.230 + if(uid1.iUid == KWservUid) //only wserv process can start the server
1.231 + {
1.232 + StartSurfaceUpdateServer(iSurfUpdateServ);
1.233 + }
1.234 +
1.235 + // Register the cleanup function in a property defined by WServ
1.236 + RThread t;
1.237 + TUid category = {t.SecureId().iId};
1.238 + RProperty prop;
1.239 + TCallBack cb(DeleteSingleton, &User::Heap());
1.240 + TPckgC<TCallBack> cbPckg(cb);
1.241 +
1.242 + // If the property cannot be set the assumption is that the cleanup is not needed
1.243 + (void) prop.Set(category, KOpenWfcInteropCleanupKey, cbPckg);
1.244 + prop.Close();
1.245 + t.Close();
1.246 +
1.247 + // StreamMap is constructed from main thread
1.248 + SetMainHeap();
1.249 + }
1.250 +
1.251 +COpenWfcStreamMap::Guard::Guard(RFastLock& aLock):
1.252 +iLock(aLock)
1.253 + {
1.254 + iLock.Wait();
1.255 + }
1.256 +
1.257 +COpenWfcStreamMap::Guard::~Guard()
1.258 + {
1.259 + iLock.Signal();
1.260 + }
1.261 +
1.262 +EXPORT_C RHeap* COpenWfcStreamMap::GetMainHeap()
1.263 + {
1.264 + return iMainHeap;
1.265 + }
1.266 +
1.267 +void COpenWfcStreamMap::SetMainHeap()
1.268 + {
1.269 + iMainHeap = &User::Heap();
1.270 + }
1.271 +
1.272 +TInt COpenWfcStreamMap::RegisterScreenNotifications(TInt aScreenNum, TInt aPriority,TInt aInternalVersion)
1.273 + {
1.274 + COpenWfcStreamMap* pInstance = NULL;
1.275 + TRAPD(err,pInstance = &COpenWfcStreamMap::InstanceL());
1.276 + if (err != KErrNone)
1.277 + {
1.278 + return err;
1.279 + }
1.280 +
1.281 + if (iRegisteredUpdaters.Find(aScreenNum)!= NULL)
1.282 + {
1.283 + return KErrAlreadyExists;
1.284 + }
1.285 +
1.286 + CExtensionContainer* updateProxy = NULL;
1.287 + TRAP(err, updateProxy = CContentUpdateProxy::NewL(aScreenNum, pInstance,aInternalVersion,aPriority));
1.288 + if (err)
1.289 + {
1.290 + return err;
1.291 + }
1.292 +
1.293 + if ((err = iRegisteredUpdaters.Insert(aScreenNum, updateProxy)) != KErrNone)
1.294 + {
1.295 + delete updateProxy;
1.296 + return err;
1.297 + }
1.298 +
1.299 + if (!pInstance->iSurfUpdateServ)
1.300 + {
1.301 + return KErrNotReady; //For testing purposes the backend proxy still exists.
1.302 + }
1.303 + err = iSurfUpdateServ->Register(aScreenNum, updateProxy, aPriority);
1.304 + if (err!=KErrNone)
1.305 + {
1.306 + delete updateProxy;
1.307 + iRegisteredUpdaters.Remove(aScreenNum);
1.308 + }
1.309 + return err;
1.310 + }
1.311 +
1.312 +CExtensionContainer* COpenWfcStreamMap::RegisteredScreenNotifications(TInt aScreenNum)
1.313 + {
1.314 + return *iRegisteredUpdaters.Find(aScreenNum);
1.315 + }
1.316 +
1.317 +TInt COpenWfcStreamMap::UnregisterScreenNotifications(TInt aScreenNum)
1.318 + {
1.319 + TInt err = KErrNone;
1.320 + CExtensionContainer** backend = iRegisteredUpdaters.Find(aScreenNum);
1.321 + if (backend)
1.322 + {
1.323 + delete *backend;
1.324 + iRegisteredUpdaters.Remove(aScreenNum);
1.325 + if (iSurfUpdateServ)
1.326 + {
1.327 + err = iSurfUpdateServ->Register(aScreenNum, NULL, 0);
1.328 + }
1.329 + else
1.330 + {
1.331 + err = KErrNotReady;
1.332 + }
1.333 + }
1.334 + else
1.335 + {
1.336 + err = KErrNotFound;
1.337 + }
1.338 +
1.339 + return err;
1.340 + }