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