os/security/contentmgmt/referencedrmagent/contentiterator/contentiterator.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2004-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 the License "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: 
    15 *
    16 */
    17 
    18 
    19 
    20 #include "cafpanic.h"
    21 #include "contentIterator.h"
    22 #include "FileContentIterator.h"
    23 #include "contentiteratordata.h"
    24 
    25 using ContentAccess::CContentIterator;
    26 using ContentAccess::TVirtualPathPtr;
    27 
    28 _LIT(KIteratorThread,"ContentIterator");
    29 EXPORT_C CContentIterator* CContentIterator::NewL(const TDesC& aPath, TBool aRecursive, const TDesC8& aMimeType) 
    30 	{  
    31 	CContentIterator* self = new (ELeave) CContentIterator();
    32 	CleanupStack::PushL(self);
    33 	self->ConstructL(aPath, aRecursive, aMimeType);
    34 	CleanupStack::Pop();
    35 	return self;
    36 	}
    37 
    38 CContentIterator::CContentIterator() : CActive(EPriorityStandard)
    39 	{
    40 	}
    41 
    42 CContentIterator::~CContentIterator()
    43 	{
    44 	// tell thread to cancel and shutdown
    45 	Cancel();
    46 	
    47 	// close thread handle
    48 	iWorkerThread.Close();
    49 	delete info; 
    50 	}
    51 
    52 void CContentIterator::ConstructL(const TDesC& aPath, TBool aRecursive, const TDesC8& aMimeType)
    53 	{	
    54 	// This data buffer will be shared between the client and the worker thread
    55 	info = CContentIteratorData::NewL(aPath,aRecursive,aMimeType);
    56 	
    57 	// create the thread, need a big heap and stack for recursively searching through directories
    58 	User::LeaveIfError(iWorkerThread.Create(KIteratorThread(),CContentIterator::ThreadEntry,32768, KMinHeapSize, 131072, (void *) info , EOwnerProcess));
    59 
    60 	// add ourselves to active scheduler
    61 	CActiveScheduler::Add(this);
    62 
    63 	// Set up notification in case the thread panics etc
    64 	iStatus = KRequestPending;
    65 	iWorkerThread.Logon(iStatus);
    66 	SetActive();
    67 	
    68 	// start the thread
    69 	iWorkerThread.Resume();
    70 	}
    71 
    72 
    73 void CContentIterator::DoCancel()
    74 	{
    75 	// Wait until thread finishes whatever it's doing
    76 	info->Lock();
    77 	 
    78 	// Signal for the thread to close
    79 	info->RunThreadFunction(EIteratorShutdownThread);
    80 	}
    81 
    82 void CContentIterator::RunL()
    83 	{
    84 	// Thread must have completed
    85 	if(iWorkerThread.ExitType() == EExitPanic)
    86 		{
    87 		// Thread panicd, better panic our thread
    88 		User::Panic(KCafPanicString, ECafPanicContentIteratorThreadPanic);
    89 		}
    90 	}
    91 
    92 EXPORT_C TVirtualPathPtr CContentIterator::VirtualPath()
    93 	{
    94 	// Wait until thread finishes whatever it's doing
    95 	info->Lock(); 
    96 	iFileName.Copy(info->Path());	
    97 	iUniqueId.Copy(info->UniqueId());	
    98 	info->Unlock(); 
    99 	return TVirtualPathPtr(iFileName, iUniqueId);
   100 	}
   101 
   102 EXPORT_C const TDesC&  CContentIterator::Name()
   103 	{
   104 	// Wait until thread finishes whatever it's doing
   105 	info->Lock(); 
   106 	iName.Copy(info->Name());	
   107 	info->Unlock(); 
   108 	return iName;
   109 	}
   110 
   111 EXPORT_C const TDesC8& CContentIterator::MimeType()
   112 	{
   113 	// Wait until thread finishes whatever it's doing
   114 	info->Lock(); 
   115 	iMimeType.Copy(info->MimeType());
   116 	info->Unlock(); 
   117 	return iMimeType;
   118 	}
   119 
   120 EXPORT_C void CContentIterator::Next(TRequestStatus &aStatus)
   121 	{
   122 	// Wait until thread finishes whatever it's doing
   123 	info->Lock(); 
   124 
   125 	// Remember which thread and TRequestStatus to notify
   126 	TThreadId id = RThread().Id();
   127 	info->SetClientRequest(id, aStatus);
   128 	
   129 	// Tell it to find the next iteration
   130 	info->RunThreadFunction(EIteratorFindNextContentObject); 
   131 	}
   132 	
   133 
   134 TInt CContentIterator::ThreadEntry(TAny* aAny) 
   135 	{
   136 	TBool exitNow = EFalse;
   137 	TInt err;
   138 	CFileContentIterator* iterator = NULL;
   139 	RThread clientThread;
   140 	CContentIteratorData* info = reinterpret_cast <CContentIteratorData *> (aAny);
   141 	
   142 	// create a trap handler
   143 	CTrapCleanup* cleanup = CTrapCleanup::New();
   144 	
   145 	while(!exitNow)
   146 		{
   147 		// Thread will wait here until signaled by other CContentIterator functions
   148 		switch(info->ThreadWait())
   149 			{
   150 		// Client thread has asked us to shutdown, exit loop
   151 		case EIteratorShutdownThread:
   152 			exitNow = ETrue;
   153 			break;
   154 		// Client thread is asking us to find the next object	
   155 		case EIteratorFindNextContentObject:
   156 			if(!iterator)
   157 				{
   158 				TRAP(err, iterator = CFileContentIterator::NewL(info->Path(), info->IsRecursive(), info->MimeType()));
   159 				info->SetData(KNullDesC(), KNullDesC(), KNullDesC(), KNullDesC8());
   160 				}
   161 			else
   162 				{
   163 				err = iterator->Next();
   164 				}
   165 	
   166 			if(err == KErrNone)
   167 				{
   168 				// If a content object was found, write the value back 
   169 				// into the other thread while the info is still locked
   170 				info->SetData(iterator->FileName(),iterator->UniqueId(), iterator->Name(), iterator->MimeType());
   171 				}
   172 
   173 			// Complete the clients asynchronous request
   174 			info->CompleteClientRequest(err);
   175 			break;
   176 		default:
   177 			User::Panic(KCafPanicString, ECafPanicContentIteratorUnknownRequest);
   178 			break;
   179 			};
   180 
   181 		// Allow the client to post a new request
   182 		info->Unlock(); 
   183 		}
   184 	delete iterator;
   185 	delete cleanup;
   186 	return KErrNone;
   187 	}
   188