graphicscomposition/openwfsupport/src/streammap.cpp
changeset 0 5d03bc08d59c
child 98 bf7481649c98
child 163 bbf46f59e123
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 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 // streammap.cpp: creates and maintaines the association between native stream and a TSurfaceId
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "streammap.h"
       
    19 #include <graphics/updateserverprovider.h>
       
    20 #include <e32property.h>
       
    21 #include <e32std.h>
       
    22 #include <e32cmn.h>
       
    23 #include "openwfcpanic.h"
       
    24 #include "surfacestream.h"
       
    25 #include "contentupdateproxy.h"
       
    26 
       
    27 static const TInt KOpenWfcInteropCleanupKey = 0x10286FC5;
       
    28 
       
    29 TEMPLATE_SPECIALIZATION class RHashTableBase::Defaults<TSurfaceId, RHashTableBase::EDefaultSpecifier_Normal>
       
    30 	{
       
    31 public:
       
    32 	inline static TGeneralHashFunction32 Hash();
       
    33 	inline static TGeneralIdentityRelation Id();
       
    34 	};
       
    35 
       
    36 inline TGeneralHashFunction32 RHashTableBase::Defaults<TSurfaceId, RHashTableBase::EDefaultSpecifier_Normal>::Hash()
       
    37 	{return (TGeneralHashFunction32)&DefaultHash::Integer;}
       
    38 
       
    39 inline TGeneralIdentityRelation RHashTableBase::Defaults<TSurfaceId, RHashTableBase::EDefaultSpecifier_Normal>::Id()
       
    40 	{return (TGeneralIdentityRelation)&DefaultIdentity::Integer;}
       
    41 
       
    42 
       
    43 COpenWfcStreamMap* COpenWfcStreamMap::pInstance = NULL;
       
    44 
       
    45 TUint32 COpenWfcStreamMap::HashFunction(const TSurfaceId& aHashKey)
       
    46 	{
       
    47 	TPckgC<TSurfaceId> pckg(aHashKey);
       
    48 	return DefaultHash::Des8(pckg);
       
    49 	}
       
    50 
       
    51 EXPORT_C COpenWfcStreamMap& COpenWfcStreamMap::InstanceL()
       
    52 	{
       
    53 	// would have been nice to try to protect this area with a mutex, however,
       
    54 	// the preliminary analyses show we can guarantee the safe creation of the mutex
       
    55 	// by invoking InstanceL() from the place the CGce instances are created
       
    56 	// If necessary, in future, the code can be expanded by using a named mutex.
       
    57 	if (!pInstance)
       
    58 		{
       
    59 		COpenWfcStreamMap* newInstance = new(ELeave)COpenWfcStreamMap();
       
    60 		CleanupStack::PushL(newInstance);
       
    61 		newInstance->ConstructL();
       
    62 		CleanupStack::Pop(newInstance);
       
    63 		pInstance=newInstance;
       
    64 		}
       
    65 	return *pInstance;
       
    66 	}
       
    67 
       
    68 EXPORT_C TInt COpenWfcStreamMap::Reserve(TInt aExpand)
       
    69 	{
       
    70 	Guard g(iMutex);
       
    71 	TInt ret = iMap.Reserve(aExpand);
       
    72 	return ret;
       
    73 	}
       
    74 
       
    75 CSurfaceStream* COpenWfcStreamMap::Find(const TSurfaceId& aSurfaceId)
       
    76 	{
       
    77 	Guard g(iMutex);
       
    78 	CSurfaceStream** ns = iMap.Find(aSurfaceId);
       
    79 	// used if statement to ease debug help
       
    80 	if (ns)
       
    81 		{
       
    82 		(*ns)->AddReference();
       
    83 		return *ns;
       
    84 		}
       
    85 	return NULL;
       
    86 	}
       
    87 
       
    88 CSurfaceStream* COpenWfcStreamMap::AcquireL(const TSurfaceId& aSurfaceId)
       
    89 	{
       
    90 	Guard* pGuard = new(ELeave) Guard(iMutex);
       
    91 	User::LeaveIfNull(pGuard);
       
    92 	CleanupDeletePushL(pGuard);
       
    93 	
       
    94 	CSurfaceStream** ns = NULL;
       
    95 	CSurfaceStream* ret = NULL;
       
    96 	ns = iMap.Find(aSurfaceId);
       
    97 	if (ns)
       
    98 		{
       
    99 		WFCI_ASSERT_DEBUG((*ns), EOwfPanicInvalidHasMap);  // should have never happened
       
   100 		ret = *ns;
       
   101 		}
       
   102 	else
       
   103 		{
       
   104 		ret = CSurfaceStream::NewLC(aSurfaceId);
       
   105 		User::LeaveIfError(iMap.Insert(aSurfaceId, ret));
       
   106 		CleanupStack::Pop();
       
   107 		}
       
   108 	ret->AddReference();
       
   109 	CleanupStack::PopAndDestroy(pGuard);
       
   110 	return ret;
       
   111 	}
       
   112 
       
   113 EXPORT_C TInt COpenWfcStreamMap::Count()
       
   114 	{
       
   115 	Guard g(iMutex);
       
   116 	TInt count = iMap.Count();
       
   117 	return count;
       
   118 	}
       
   119 
       
   120 RSurfaceManager& COpenWfcStreamMap::SurfaceManager()
       
   121 	{
       
   122 	return iSurfaceManager;
       
   123 	}
       
   124 
       
   125 TInt COpenWfcStreamMap::LockDestroy(CSurfaceStream* aStream)
       
   126 	{
       
   127 	Guard g(iMutex);
       
   128 	TInt ret = KErrNone;
       
   129 	if (aStream)
       
   130 		{
       
   131 		if (aStream->RemainingReference())
       
   132 			{
       
   133 			const TSurfaceId& surfaceId = aStream->SurfaceId();
       
   134 			CSurfaceStream** ns = iMap.Find(surfaceId);
       
   135 			// used if statement to ease debug help
       
   136 			if (ns && ((*ns) == aStream))
       
   137 				{
       
   138 				TInt ret = iMap.Remove(surfaceId);
       
   139 				delete aStream;
       
   140 				}
       
   141 			else
       
   142 				{
       
   143 				ret = KErrNotFound;
       
   144 				}
       
   145 			}
       
   146 		else	// RemainingReference
       
   147 			{
       
   148 			ret = KErrInUse;
       
   149 			}
       
   150 		}
       
   151 	else	// aStream
       
   152 		{
       
   153 		ret = KErrArgument;
       
   154 		}
       
   155 	return ret;
       
   156 	}
       
   157 
       
   158 COpenWfcStreamMap::COpenWfcStreamMap():
       
   159 iMap(THashFunction32<TSurfaceId>(COpenWfcStreamMap::HashFunction), TIdentityRelation<TSurfaceId>()),
       
   160 iRegisteredUpdaters()
       
   161 	{
       
   162 	}
       
   163 
       
   164 TInt COpenWfcStreamMap::DeleteSingleton(TAny* aData)
       
   165 /**
       
   166  * aData    A pointer to the heap registered for this callback
       
   167  */
       
   168     {
       
   169     // Blank the property for this callback
       
   170     RThread t;
       
   171     RProperty prop;
       
   172     TCallBack cb(NULL, NULL);
       
   173     TPckgC<TCallBack> cbPckg(cb);
       
   174     prop.Set(TUid::Uid(t.SecureId().iId), KOpenWfcInteropCleanupKey, cbPckg);
       
   175     prop.Close();
       
   176     t.Close();
       
   177     
       
   178     if (aData == &User::Heap())
       
   179         {
       
   180         delete pInstance;
       
   181         pInstance = NULL;                
       
   182         return ETrue;
       
   183         }
       
   184     return EFalse;
       
   185     }
       
   186 
       
   187 COpenWfcStreamMap::~COpenWfcStreamMap()
       
   188 	{
       
   189 	iMutex.Wait();
       
   190         {
       
   191         THashMapIter<TSurfaceId, CSurfaceStream*> iter(iMap);
       
   192         const TSurfaceId* nextKey = iter.NextKey();
       
   193         CSurfaceStream* const* ns = NULL;
       
   194         while (nextKey)
       
   195             {
       
   196             ns = iter.NextValue();
       
   197             if (ns && *ns)
       
   198                 {
       
   199                 delete (*ns);
       
   200                 }
       
   201             nextKey = iter.NextKey();		
       
   202             }
       
   203         }
       
   204 	iMap.Close();
       
   205 	iSurfaceManager.Close();
       
   206 	iMutex.Signal();
       
   207 	iMutex.Close();
       
   208 	
       
   209         {
       
   210         THashMapIter<TInt32, CExtensionContainer*> iter(iRegisteredUpdaters);
       
   211         const TInt32* nextKey = iter.NextKey();
       
   212         CExtensionContainer* const* extensionContainer = NULL;
       
   213         while (nextKey)
       
   214             {
       
   215             extensionContainer = iter.NextValue();
       
   216             if (extensionContainer && *extensionContainer)
       
   217                 {
       
   218                 delete (*extensionContainer);
       
   219                 }
       
   220             nextKey = iter.NextKey();       
       
   221             }
       
   222         }
       
   223 	iRegisteredUpdaters.Close();
       
   224 	}
       
   225 
       
   226 COpenWfcStreamMap::COpenWfcStreamMap(const COpenWfcStreamMap&)
       
   227 	{
       
   228 	Panic(EOwfPanicInvalidCallStreamMap);
       
   229 	}
       
   230 
       
   231 COpenWfcStreamMap& COpenWfcStreamMap::operator= (const COpenWfcStreamMap&)
       
   232 	{
       
   233 	Panic(EOwfPanicInvalidCallStreamMap);
       
   234 	return *this;
       
   235 	}
       
   236 
       
   237 void COpenWfcStreamMap::ConstructL()
       
   238 	{
       
   239 	User::LeaveIfError(iMutex.CreateLocal());
       
   240 	iMap.Reserve(iInitialSize);
       
   241 	TSurfaceId surface = TSurfaceId::CreateNullId();
       
   242 	User::LeaveIfError(iMap.Insert(surface, NULL));
       
   243 
       
   244 	User::LeaveIfError(iSurfaceManager.Open());
       
   245 	RProcess process;
       
   246 	TUidType uidType = process.Type();
       
   247 	const TInt32 KWservUid = 268450592;
       
   248 	const TUid& uid1 = uidType[2];
       
   249 
       
   250 	if(uid1.iUid == KWservUid) //only wserv process can start the server
       
   251 		{
       
   252 		StartSurfaceUpdateServer(iSurfUpdateServ);
       
   253 		}
       
   254 	
       
   255 	// Register the cleanup function in a property defined by WServ
       
   256 	RThread t;		
       
   257 	TUid category = {t.SecureId().iId};
       
   258 	RProperty prop;
       
   259 	TCallBack cb(DeleteSingleton, &User::Heap());
       
   260     TPckgC<TCallBack> cbPckg(cb);
       
   261     
       
   262     // If the property cannot be set the assumption is that the cleanup is not needed
       
   263     (void) prop.Set(category, KOpenWfcInteropCleanupKey, cbPckg);
       
   264     prop.Close();
       
   265 	t.Close();	
       
   266 	
       
   267 	// StreamMap is constructed from main thread
       
   268 	SetMainHeap();
       
   269 	}
       
   270 
       
   271 COpenWfcStreamMap::Guard::Guard(RFastLock& aLock):
       
   272 iLock(aLock)
       
   273 	{
       
   274 	iLock.Wait();
       
   275 	}
       
   276 
       
   277 COpenWfcStreamMap::Guard::~Guard()
       
   278 	{
       
   279 	iLock.Signal();
       
   280 	}
       
   281 
       
   282 EXPORT_C RHeap* COpenWfcStreamMap::GetMainHeap()
       
   283 	{
       
   284 	return iMainHeap;
       
   285 	}
       
   286 
       
   287 void COpenWfcStreamMap::SetMainHeap()
       
   288 	{
       
   289 	iMainHeap = &User::Heap();
       
   290 	}
       
   291 
       
   292 TInt COpenWfcStreamMap::RegisterScreenNotifications(TInt aScreenNum, TInt aPriority,TInt aInternalVersion)
       
   293 	{
       
   294 	COpenWfcStreamMap* pInstance = NULL;
       
   295 	TRAPD(err,pInstance = &COpenWfcStreamMap::InstanceL());
       
   296 	if (err != KErrNone)
       
   297 	    {
       
   298 	    return err;
       
   299 	    }
       
   300 	
       
   301 	if (iRegisteredUpdaters.Find(aScreenNum)!= NULL)
       
   302 		{
       
   303 		return KErrAlreadyExists;
       
   304 		}
       
   305 	
       
   306 	CExtensionContainer* updateProxy = NULL;
       
   307 	TRAP(err, updateProxy = CContentUpdateProxy::NewL(aScreenNum, pInstance,aInternalVersion,aPriority));
       
   308 	if (err)
       
   309 		{
       
   310 		return err;
       
   311 		}
       
   312 	
       
   313 	if ((err = iRegisteredUpdaters.Insert(aScreenNum, updateProxy)) != KErrNone)
       
   314 	    {
       
   315         delete updateProxy;
       
   316 	    return err;
       
   317 	    }
       
   318 
       
   319     if (!pInstance->iSurfUpdateServ)
       
   320         {
       
   321         return KErrNotReady;    //For testing purposes the backend proxy still exists.
       
   322         }
       
   323 	err = iSurfUpdateServ->Register(aScreenNum, updateProxy, aPriority);
       
   324 	if (err!=KErrNone)
       
   325 	    {
       
   326         delete updateProxy;
       
   327         iRegisteredUpdaters.Remove(aScreenNum);
       
   328 	    }
       
   329 	return err;
       
   330 	}
       
   331 
       
   332 CExtensionContainer* COpenWfcStreamMap::RegisteredScreenNotifications(TInt aScreenNum)
       
   333     {
       
   334     return *iRegisteredUpdaters.Find(aScreenNum);
       
   335     }
       
   336 
       
   337 TInt COpenWfcStreamMap::UnregisterScreenNotifications(TInt aScreenNum)
       
   338 	{
       
   339 	TInt err = KErrNone;
       
   340 	CExtensionContainer** backend = iRegisteredUpdaters.Find(aScreenNum);
       
   341 	if (backend)
       
   342 	    {
       
   343 	    delete *backend;
       
   344 	    iRegisteredUpdaters.Remove(aScreenNum);
       
   345         if (iSurfUpdateServ)
       
   346             {
       
   347             err = iSurfUpdateServ->Register(aScreenNum, NULL, 0);
       
   348             }
       
   349         else
       
   350             {
       
   351             err = KErrNotReady;
       
   352             }
       
   353 	    }
       
   354 	else
       
   355 	    {
       
   356 	    err = KErrNotFound;
       
   357 	    }
       
   358 
       
   359 	return err;
       
   360 	}