photosgallery/collectionframework/datasource/manager/src/glxdatasource.cpp
changeset 0 4e91876724a2
equal deleted inserted replaced
-1:000000000000 0:4e91876724a2
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Implementation of the Data Source Class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 #include "glxdatasource.h"
       
    24 
       
    25 #include <glxsingletonstore.h>
       
    26 #include <glxpanic.h>
       
    27 #include <glxtracer.h>
       
    28 
       
    29 #include "glxdatasourcetask.h"
       
    30 #include "mglxdatasourceupdateobserver.h"
       
    31 #include "mglxdatasourcerequestobserver.h"
       
    32 
       
    33 // ---------------------------------------------------------------------------
       
    34 // CDataSourceArrayOwner::InstanceL
       
    35 // ---------------------------------------------------------------------------
       
    36 //
       
    37 CDataSourceArrayOwner* CDataSourceArrayOwner::InstanceL() 
       
    38 	{
       
    39     TRACER("CDataSourceArrayOwner::InstanceL()");
       
    40     return CGlxSingletonStore::InstanceL(&NewL);
       
    41     }
       
    42     
       
    43 // ---------------------------------------------------------------------------
       
    44 // CDataSourceArrayOwner::Close
       
    45 // ---------------------------------------------------------------------------
       
    46 //
       
    47 void CDataSourceArrayOwner::Close() 
       
    48    {
       
    49     TRACER("void CDataSourceArrayOwner::Close()");
       
    50    CGlxSingletonStore::Close(this);
       
    51    }
       
    52   
       
    53 // ---------------------------------------------------------------------------
       
    54 // CDataSourceArrayOwner::Array
       
    55 // ---------------------------------------------------------------------------
       
    56 //
       
    57 RPointerArray<CGlxDataSource>& CDataSourceArrayOwner::Array()
       
    58 	{
       
    59     TRACER("CDataSourceArrayOwner::Array()");
       
    60     return iDataSources;
       
    61 	}
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // CDataSourceArrayOwner::NewL
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 CDataSourceArrayOwner* CDataSourceArrayOwner::NewL() 
       
    68    {
       
    69     TRACER("CDataSourceArrayOwner* CDataSourceArrayOwner::NewL()");
       
    70    return new (ELeave) CDataSourceArrayOwner();
       
    71    }
       
    72 
       
    73 // ---------------------------------------------------------------------------
       
    74 // CDataSourceArrayOwner::~CDataSourceArrayOwner
       
    75 // ---------------------------------------------------------------------------
       
    76 //
       
    77 CDataSourceArrayOwner::~CDataSourceArrayOwner()
       
    78    {
       
    79     TRACER("CDataSourceArrayOwner::~CDataSourceArrayOwner()");
       
    80    iDataSources.Close();
       
    81    }    
       
    82 
       
    83 // ---------------------------------------------------------------------------
       
    84 // Constructor
       
    85 // ---------------------------------------------------------------------------
       
    86 //
       
    87 EXPORT_C CGlxDataSource::CGlxDataSource()
       
    88     : CActive(EPriorityStandard)
       
    89     {
       
    90     TRACER("EXPORT_C CGlxDataSource::CGlxDataSource()");
       
    91     CActiveScheduler::Add(this);
       
    92     }
       
    93 
       
    94 // ---------------------------------------------------------------------------
       
    95 // MGlxDataSource::OpenDataSourceL
       
    96 // ---------------------------------------------------------------------------
       
    97 //
       
    98 EXPORT_C MGlxDataSource* MGlxDataSource::OpenDataSourceL(const TUid& aDataSource, MGlxDataSourceUpdateObserver& aObserver)
       
    99 	{
       
   100     TRACER("MGlxDataSource* MGlxDataSource::OpenDataSourceL()");
       
   101 	CDataSourceArrayOwner* dsArrayOwner = CDataSourceArrayOwner::InstanceL();
       
   102 	CleanupClosePushL(*dsArrayOwner);
       
   103 	RPointerArray<CGlxDataSource>& dataSoruceArray = dsArrayOwner->Array();
       
   104 	CGlxDataSource* dataSource = NULL;
       
   105 	if (dataSoruceArray.Count())
       
   106 		{
       
   107 		for (TInt i = 0;i < dataSoruceArray.Count(); i++)
       
   108 			{
       
   109 			if (dataSoruceArray[i]->Uid() == aDataSource)
       
   110 				{
       
   111 				dataSource = dataSoruceArray[i];
       
   112 				dataSource->AddObserverL(aObserver);
       
   113 				break;
       
   114 				}
       
   115 			}
       
   116 		}
       
   117 	if (!dataSource)
       
   118 		{
       
   119 		REComSession ecomSession = REComSession::OpenL();
       
   120 		CleanupClosePushL(ecomSession);
       
   121 		TUid dtorKey;
       
   122 		dataSource = reinterpret_cast<CGlxDataSource*>(
       
   123            REComSession::CreateImplementationL(aDataSource, dtorKey));
       
   124         CleanupStack::PushL(dataSource);
       
   125         dataSoruceArray.AppendL(dataSource);
       
   126         dataSource->SetUid(aDataSource);
       
   127         dataSource->SetDtorKey(dtorKey);
       
   128         dataSource->AddObserverL(aObserver);
       
   129         CleanupStack::Pop(dataSource);
       
   130         dataSource->SetEComSession(ecomSession);
       
   131         CleanupStack::Pop(&ecomSession);
       
   132         dataSource->SetDataSourceArrayOwner(dsArrayOwner);
       
   133         CleanupStack::Pop(dsArrayOwner);
       
   134 		}
       
   135 	else
       
   136 		{
       
   137 		CleanupStack::PopAndDestroy(dsArrayOwner);
       
   138 		}
       
   139 	
       
   140     return dataSource;
       
   141 	}
       
   142 
       
   143 // ---------------------------------------------------------------------------
       
   144 // CGlxDataSource::Close
       
   145 // ---------------------------------------------------------------------------
       
   146 //
       
   147 EXPORT_C void CGlxDataSource::Close(MGlxDataSourceUpdateObserver& aObserver)
       
   148 	{
       
   149     TRACER("void CGlxDataSource::Close(MGlxDataSourceUpdateObserver& aObserver)");
       
   150 	TInt observer = iDataSourceObservers.Find(&aObserver);
       
   151 	__ASSERT_DEBUG(observer !=KErrNotFound, Panic(EGlxPanicLogicError)); // Closing non-existant observer
       
   152 	iDataSourceObservers.Remove(observer);
       
   153 	if (iDataSourceObservers.Count() == 0)
       
   154 		{
       
   155 		RPointerArray<CGlxDataSource>& dataSourceArray = iDataSourceArrayOwner->Array();
       
   156 		TInt dataSource = dataSourceArray.Find(this);
       
   157 		__ASSERT_DEBUG(dataSource !=KErrNotFound, Panic(EGlxPanicLogicError)); // Closing non-existant observer
       
   158 		dataSourceArray.Remove(dataSource);
       
   159 		REComSession ecomSession = iEComSession;
       
   160 		TInt count = dataSourceArray.Count();
       
   161 		delete this;
       
   162 		if (count == 0)
       
   163 			{
       
   164 			ecomSession.Close();
       
   165 			}
       
   166 		}	
       
   167 	}
       
   168 
       
   169 // ---------------------------------------------------------------------------
       
   170 // CGlxDataSource::~CGlxDataSource
       
   171 // ---------------------------------------------------------------------------
       
   172 //
       
   173 EXPORT_C CGlxDataSource::~CGlxDataSource()
       
   174 	{
       
   175     TRACER("EXPORT_C CGlxDataSource::~CGlxDataSource()");
       
   176     Cancel();
       
   177 	iDataSourceObservers.Close();
       
   178     REComSession::DestroyedImplementation(iDtorKey);
       
   179     iTasks.ResetAndDestroy();
       
   180 	iDataSourceArrayOwner->Close();
       
   181 	}
       
   182 
       
   183 // ---------------------------------------------------------------------------
       
   184 // CGlxDataSource::AddObserverL
       
   185 // ---------------------------------------------------------------------------
       
   186 //
       
   187 void CGlxDataSource::AddObserverL(MGlxDataSourceUpdateObserver& aObserver)
       
   188 	{
       
   189     TRACER("void CGlxDataSource::AddObserverL(MGlxDataSourceUpdateObserver& aObserver)");
       
   190 	iDataSourceObservers.AppendL(&aObserver);
       
   191 	}
       
   192 
       
   193 
       
   194 // ---------------------------------------------------------------------------
       
   195 // CGlxDataSource::RunL
       
   196 // ---------------------------------------------------------------------------
       
   197 //
       
   198 EXPORT_C void CGlxDataSource::RunL()
       
   199     {
       
   200     TRACER("void CGlxDataSource::RunL()");
       
   201     TAction action = static_cast<TAction>(iStatus.Int());
       
   202     
       
   203     switch (action)
       
   204         {
       
   205         case ECleanupAndExecute:
       
   206             {
       
   207             delete iTasks[0];
       
   208             iTasks.Remove(0);
       
   209             TaskCompletedL();
       
   210             }
       
   211         // Don't break - fall through 
       
   212         case EExecuteOnly:
       
   213             {
       
   214             if ( (iTasks.Count() > 0) && ( iDataSourceReady || !iTasks[0]->IsDataSourceNeeded() ) )
       
   215                 {
       
   216                 TaskStartedL();
       
   217                 iTasks[0]->ExecuteRequestL(); // Execute the oldest request
       
   218                 }
       
   219             }
       
   220         break;
       
   221         }
       
   222     }
       
   223 
       
   224 // ---------------------------------------------------------------------------
       
   225 // CGlxDataSource::DoCancel
       
   226 // ---------------------------------------------------------------------------
       
   227 //
       
   228 EXPORT_C void CGlxDataSource::DoCancel()
       
   229     {
       
   230     TRACER("void CGlxDataSource::DoCancel()");
       
   231     // CActive::Cancel() will wait for the request to complete.
       
   232     // It is not necessary to take any action here.
       
   233     }
       
   234 
       
   235 // ---------------------------------------------------------------------------
       
   236 // CGlxDataSource::RunError
       
   237 // ---------------------------------------------------------------------------
       
   238 //
       
   239 EXPORT_C TInt CGlxDataSource::RunError(TInt aError)
       
   240     {
       
   241     TRACER("TInt CGlxDataSource::RunError(TInt aError)");
       
   242     __ASSERT_DEBUG(iTasks.Count() > 0, Panic(EGlxPanicLogicError));
       
   243     iTasks[0]->HandleRequestComplete(aError);
       
   244     
       
   245     return KErrNone;
       
   246     }
       
   247 
       
   248 // ---------------------------------------------------------------------------
       
   249 // CGlxDataSource::CompleteSelf
       
   250 // ---------------------------------------------------------------------------
       
   251 //
       
   252 void CGlxDataSource::CompleteSelf(TAction aAction)
       
   253     {
       
   254     TRACER("void CGlxDataSource::CompleteSelf(TAction aAction)");
       
   255     TRequestStatus* status=&iStatus;
       
   256     User::RequestComplete(status, aAction);
       
   257     SetActive();    
       
   258     }
       
   259 
       
   260 // ---------------------------------------------------------------------------
       
   261 // CGlxDataSource::DataSourceRequestL
       
   262 // ---------------------------------------------------------------------------
       
   263 //
       
   264 EXPORT_C void CGlxDataSource::DataSourceRequestL(CGlxRequest* aRequest, MGlxDataSourceRequestObserver& aObserver)
       
   265 	{
       
   266     TRACER("void CGlxDataSource::DataSourceRequestL()");
       
   267 	CGlxDataSourceTask* newRequest = CreateTaskL(aRequest, aObserver);
       
   268 	iTasks.AppendL(newRequest);
       
   269 	TryStartTask();
       
   270 	}
       
   271 
       
   272 // ---------------------------------------------------------------------------
       
   273 // CGlxDataSource::TryStartTask
       
   274 // ---------------------------------------------------------------------------
       
   275 //
       
   276 EXPORT_C void CGlxDataSource::TryStartTask(TBool aFirstStart)
       
   277 	{
       
   278     TRACER("void CGlxDataSource::TryStartTask(TBool aFirstStart)");
       
   279 	if ( ( aFirstStart ? iTasks.Count() >= 1 : iTasks.Count() == 1 ) && !IsActive() )
       
   280     // There is one request i.e. it was just added by the call to AppendL() above and we are not waiting 
       
   281     // for a an existing request to complete. If we are waiting for a request to complete then the request 
       
   282     // we have just added will run later.
       
   283 		{
       
   284         CompleteSelf(EExecuteOnly);
       
   285 		}
       
   286 	}
       
   287 	
       
   288 // ---------------------------------------------------------------------------
       
   289 // CGlxDataSource::HandleTaskComplete
       
   290 // ---------------------------------------------------------------------------
       
   291 //
       
   292 EXPORT_C void CGlxDataSource::HandleTaskComplete(CGlxDataSourceTask* aRequest)
       
   293 	{
       
   294     TRACER("void CGlxDataSource::HandleTaskComplete(CGlxDataSourceTask* aRequest)");
       
   295 	__ASSERT_DEBUG(iTasks.Find(aRequest) == 0, Panic( EGlxPanicLogicError )); // The only request that should be executing is the 0th request in the array.
       
   296     CompleteSelf(ECleanupAndExecute);
       
   297 	}
       
   298 
       
   299 // ---------------------------------------------------------------------------
       
   300 // CGlxDataSource::CancelRequest
       
   301 // ---------------------------------------------------------------------------
       
   302 //
       
   303 EXPORT_C void CGlxDataSource::CancelRequest(MGlxDataSourceRequestObserver& aObserver)
       
   304 	{
       
   305     TRACER("void CGlxDataSource::CancelRequest(MGlxDataSourceRequestObserver& aObserver)");    
       
   306     for (TInt i = 0; i < iTasks.Count(); i++)
       
   307 		{
       
   308 		if (iTasks[i]->ObserverMatch(aObserver))
       
   309 			{            
       
   310             if (i == 0) // Cancel the active request
       
   311                 {
       
   312                 if (!IsActive())
       
   313                     {
       
   314                     // We can only cancel the request if it is currently executing. The active object being
       
   315                     // active indicates that the request has not yet started or has already completed.
       
   316                     iTasks[0]->CancelRequest();
       
   317                     }
       
   318                 Cancel();
       
   319                 CompleteSelf(ECleanupAndExecute);
       
   320                 }
       
   321             else // The request is waiting to be executed - just remove it from the queue.
       
   322                 {
       
   323                 delete iTasks[i];
       
   324                 iTasks.Remove(i);
       
   325                 }
       
   326             break;
       
   327 			}
       
   328 		}
       
   329 	}
       
   330 
       
   331 // ---------------------------------------------------------------------------
       
   332 // CGlxDataSource::BroadcastMessage
       
   333 // ---------------------------------------------------------------------------
       
   334 //
       
   335 EXPORT_C void CGlxDataSource::BroadcastMessage(CMPXMessage& aMessage)
       
   336 	{
       
   337     TRACER("void CGlxDataSource::BroadcastMessage(CMPXMessage& aMessage)");
       
   338 	__ASSERT_DEBUG(iDataSourceObservers.Count(), Panic(EGlxPanicLogicError));
       
   339 	// There should always be at least 1 observer because they are passed in
       
   340 	// when the object is instatiated.
       
   341 	iDataSourceObservers[0]->HandleMessage(aMessage);
       
   342 	}