common/tools/ats/smoketest/localisation/apparchitecture/apserv/APSSCAN.CPP
changeset 793 0c32c669a39d
child 872 17498133d9ad
equal deleted inserted replaced
792:893b85cda81b 793:0c32c669a39d
       
     1 // Copyright (c) 1997-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 the License "Symbian Foundation License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // AppArc recognizer and application scanning
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "APSSCAN.H"
       
    19 #ifdef USING_ECOM_RECOGS
       
    20 #include <ecom/ecom.h>
       
    21 #endif
       
    22 
       
    23 class CApaFsMonitor::CApaFsNotifier : public CActive
       
    24 	{
       
    25 public:
       
    26 	~CApaFsNotifier();
       
    27 	static CApaFsNotifier* NewLC(RFs& aFs, const TDesC& aLocation, MApaFsChangeObserver& aObserver);
       
    28 	void Start(TNotifyType aNotifyType);
       
    29 private:
       
    30 	CApaFsNotifier(RFs& aFs, MApaFsChangeObserver& aObserver);
       
    31 	void DoCancel();
       
    32 	void RunL();
       
    33 private:
       
    34 	RFs& iFs;
       
    35 	MApaFsChangeObserver& iObserver;
       
    36 	HBufC* iLocation;
       
    37 	};
       
    38 
       
    39 CApaFsMonitor::CApaFsNotifier::~CApaFsNotifier()
       
    40 	{
       
    41 	Cancel();
       
    42 	delete iLocation;
       
    43 	}
       
    44 
       
    45 CApaFsMonitor::CApaFsNotifier* CApaFsMonitor::CApaFsNotifier::NewLC(RFs& aFs, const TDesC& aLocation, MApaFsChangeObserver& aObserver)
       
    46 	{ // static
       
    47 	CApaFsNotifier* self=new(ELeave) CApaFsNotifier(aFs, aObserver);
       
    48 	CleanupStack::PushL(self);
       
    49 	self->iLocation = aLocation.AllocL();
       
    50 	return self;
       
    51 	}
       
    52 
       
    53 CApaFsMonitor::CApaFsNotifier::CApaFsNotifier(RFs& aFs, MApaFsChangeObserver& aObserver)
       
    54 	: CActive(EPriorityLow), // priority must be higher than that of CApaFsMonitor::iFsTimer, to ensure the RunL of each completed CApaFsNotifier object is executed before the RunL of a completed CApaFsMonitor::iFsTimer
       
    55 	iFs(aFs),
       
    56 	iObserver(aObserver)
       
    57 	{
       
    58 	CActiveScheduler::Add(this);
       
    59 	}
       
    60 
       
    61 
       
    62 void CApaFsMonitor::CApaFsNotifier::Start(TNotifyType aNotifyType)
       
    63 	{
       
    64 	if (iLocation->Length())
       
    65 		{
       
    66 		iFs.NotifyChange(aNotifyType, iStatus, *iLocation);
       
    67 		}
       
    68 	else
       
    69 		{
       
    70 		iFs.NotifyChange(aNotifyType, iStatus);
       
    71 		}
       
    72 	SetActive();
       
    73 	}
       
    74 
       
    75 void CApaFsMonitor::CApaFsNotifier::DoCancel()
       
    76 	{
       
    77 	iFs.NotifyChangeCancel(iStatus);
       
    78 	}
       
    79 
       
    80 void CApaFsMonitor::CApaFsNotifier::RunL()
       
    81 	{
       
    82 	if (iStatus == KErrNone)
       
    83 		{
       
    84 		iObserver.FsChanged();
       
    85 		}
       
    86 	}
       
    87 
       
    88 
       
    89 
       
    90 // An FsMonitor checks for any changes to the file system
       
    91 // If a change is detected, a CallBack function is called after a short pause.
       
    92 // If there are further changes, the CallBack is not called again until after 3 secs have elapsed.
       
    93 
       
    94 const TInt KApaFsMonitorPause=250000;			// Wait 0.25s before calling CallBack
       
    95 const TInt KApaFsMonitorPeriod=3000000;			// Don't call CallBack again before 3s have elapsed
       
    96 
       
    97 //
       
    98 // Class CApaFsMonitor
       
    99 //
       
   100 
       
   101 EXPORT_C CApaFsMonitor::~CApaFsMonitor()
       
   102 /** Deletes the timer object, file system change notification
       
   103 active objects and location descriptors. */
       
   104 	{
       
   105 	if (iFsTimer)
       
   106 		{
       
   107 		iFsTimer->Cancel();
       
   108 		delete iFsTimer;
       
   109 		}
       
   110 	iNotifiers.ResetAndDestroy();
       
   111 	iNotifiers.Close();
       
   112 	}
       
   113 
       
   114 CApaFsMonitor::CApaFsMonitor(RFs& aFs, TCallBack aCallBack)
       
   115  	:iFs(aFs),
       
   116  	iCallBack(aCallBack)
       
   117 	{
       
   118 	}
       
   119 
       
   120 
       
   121 EXPORT_C CApaFsMonitor* CApaFsMonitor::NewL(RFs& aFs,const TDesC& aLocation, TCallBack aCallBack)
       
   122 /** Allocates and constructs a file system monitor.
       
   123 
       
   124 @param aFs A session with the file server.
       
   125 @param aLocation Optional name of the file or directory to be 
       
   126 monitored. If the length of the descriptor is zero, the object 
       
   127 monitors changes to all files and directories in the file system.
       
   128 Additional locations to monitor may be specified by calling
       
   129 AddLocationL.
       
   130 @param aCallBack The callback function.
       
   131 @return The file system monitor.
       
   132 @see CApaFsMonitor::AddLocationL() */
       
   133 	{
       
   134 	CApaFsMonitor* self=new(ELeave) CApaFsMonitor(aFs, aCallBack);
       
   135 	CleanupStack::PushL(self);
       
   136 	self->iFsTimer=CPeriodic::NewL(CActive::EPriorityIdle);
       
   137 	self->AddLocationL(aLocation);
       
   138 	CleanupStack::Pop(self);
       
   139 	return self;
       
   140 	}
       
   141 
       
   142 /** Adds an additional file system location to monitor.
       
   143 
       
   144 @param aLocation Name of the file or directory to be monitored. */
       
   145 EXPORT_C void CApaFsMonitor::AddLocationL(const TDesC& aLocation)
       
   146 	{
       
   147 	CApaFsNotifier* const notifier = CApaFsNotifier::NewLC(iFs, aLocation, *this);
       
   148 	User::LeaveIfError(iNotifiers.Append(notifier));
       
   149 	CleanupStack::Pop(notifier);
       
   150 	}
       
   151 
       
   152 /** Cancels all file system notification active objects owned by
       
   153 this monitor.
       
   154 
       
   155 A call to this function may be followed immediately by a call
       
   156 to Start() to change the notification type.
       
   157 
       
   158 @see CApaFsMonitor::Start() */
       
   159 EXPORT_C void CApaFsMonitor::Cancel()
       
   160 	{
       
   161 	const TInt notifierCount = iNotifiers.Count();
       
   162 	for (TInt ii=0; ii < notifierCount; ii++)
       
   163 		{
       
   164 		iNotifiers[ii]->Cancel();
       
   165 		}
       
   166 	}
       
   167 
       
   168 TBool CApaFsMonitor::AnyNotificationImpending() const
       
   169 	{
       
   170 	for (TInt i=iNotifiers.Count()-1; i>=0; --i)
       
   171 		{
       
   172 		if (iNotifiers[i]->iStatus!=KRequestPending)
       
   173 			{
       
   174 			return ETrue;
       
   175 			}
       
   176 		}
       
   177 	return EFalse;
       
   178 	}
       
   179 
       
   180 void CApaFsMonitor::FsChanged()
       
   181 	{
       
   182 	iFsHasChanged=ETrue;
       
   183 	if (!iIsBlocked && !iFsTimer->IsActive())
       
   184 		iFsTimer->Start(KApaFsMonitorPause,KApaFsMonitorPeriod,TCallBack(TimerCallBack,this));
       
   185 	}
       
   186 
       
   187 EXPORT_C void CApaFsMonitor::Start(TNotifyType aNotifyType)
       
   188 /** Sets the type of notification required and starts a file system notification
       
   189 active object for each location being monitored.
       
   190 
       
   191 You can either request notification of changes to all files in the file system, 
       
   192 or to specific files, depending on the aLocation parameter specified in the NewL() 
       
   193 function.
       
   194 
       
   195 @param aNotifyType A set of flags that indicate what kinds of change should cause 
       
   196 notifications. */
       
   197 	{
       
   198 	iNotifyType=aNotifyType;
       
   199 
       
   200 	DoStart();
       
   201 	}
       
   202 
       
   203 void CApaFsMonitor::DoStart()
       
   204 	{
       
   205 	const TInt notifierCount = iNotifiers.Count();
       
   206 	for (TInt ii=0; ii < notifierCount; ii++)
       
   207 		{
       
   208 		CApaFsNotifier* const notifier = iNotifiers[ii];
       
   209 		if (!notifier->IsActive())
       
   210 			{
       
   211 			notifier->Start(iNotifyType);
       
   212 			}
       
   213 		}
       
   214 	}
       
   215 
       
   216 EXPORT_C TNotifyType CApaFsMonitor::NotifyType() const
       
   217 /** Gets the type of notification as passed to Start(). 
       
   218 
       
   219 If Start() has not yet been called, the type of notification is undefined.
       
   220 
       
   221 @return Flags that indicate what kinds of change should cause notifications. */
       
   222 	{
       
   223 	return iNotifyType;
       
   224 	}
       
   225 
       
   226 EXPORT_C void CApaFsMonitor::SetBlocked(TBool aIsBlocked)
       
   227 /** Blocks or unblocks file system monitoring. 
       
   228 
       
   229 While in a blocked state, the callback never gets called. If monitoring is 
       
   230 unblocked using this function, and a change has occurred when in the blocked 
       
   231 state then the timer is started, causing the callback to be called initially 
       
   232 after 0.25 seconds, followed by subsequent delays of 3 seconds.
       
   233 
       
   234 @param aIsBlocked True to block callbacks, false to unblock them. */
       
   235 	{
       
   236 	iIsBlocked=aIsBlocked;
       
   237 	if (iIsBlocked==EFalse)		// If end of a blocked period, notify if a change was detected
       
   238 		{
       
   239 		if (iFsHasChanged && !iFsTimer->IsActive())
       
   240 			{
       
   241 			iFsTimer->Start(KApaFsMonitorPause,KApaFsMonitorPeriod,TCallBack(TimerCallBack,this));
       
   242 			}
       
   243 		}
       
   244 	}
       
   245 
       
   246 TInt CApaFsMonitor::TimerCallBack(TAny* aObject)
       
   247 	{
       
   248 	CApaFsMonitor* self=(CApaFsMonitor*)aObject;
       
   249 	if (self->iFsHasChanged && !self->iIsBlocked)
       
   250 		{
       
   251 		self->iFsHasChanged=EFalse;
       
   252 		self->DoStart();
       
   253 		self->iCallBack.CallBack();		// Should not leave, but if it does, it's OK
       
   254 		}
       
   255 	else
       
   256 		self->iFsTimer->Cancel();
       
   257 	return KErrNone;
       
   258 	}
       
   259 
       
   260 
       
   261 #ifdef USING_ECOM_RECOGS
       
   262 //
       
   263 // CApaEComMonitor class
       
   264 //
       
   265 CApaEComMonitor::CApaEComMonitor(TCallBack aCallBack)
       
   266 	: CActive(EPriorityIdle), iCallBack (aCallBack)
       
   267 	{
       
   268 	CActiveScheduler::Add(this);
       
   269 	}
       
   270 
       
   271 CApaEComMonitor::~CApaEComMonitor()
       
   272 	{
       
   273 	Cancel();
       
   274 	delete iEComTimer;
       
   275 	if (iEComSession)
       
   276 		{
       
   277 		iEComSession->Close();
       
   278 		}
       
   279 	}
       
   280 
       
   281 CApaEComMonitor* CApaEComMonitor::NewL(TCallBack aCallBack)
       
   282 	{
       
   283 	CApaEComMonitor* self=new(ELeave) CApaEComMonitor(aCallBack);
       
   284 	CleanupStack::PushL(self);
       
   285 	self->ConstructL();
       
   286 	CleanupStack::Pop(self);
       
   287 	return self;
       
   288 	}
       
   289 
       
   290 void CApaEComMonitor::ConstructL()
       
   291 	{
       
   292 	iEComSession = &(REComSession::OpenL());
       
   293 	iEComTimer = CPeriodic::NewL(CActive::EPriorityIdle);
       
   294 	}
       
   295 
       
   296 void CApaEComMonitor::DoCancel()
       
   297 	{
       
   298 	iEComTimer->Cancel();
       
   299 	iEComSession->CancelNotifyOnChange(iStatus);
       
   300 	}
       
   301 
       
   302 void CApaEComMonitor::Start ()
       
   303 	{
       
   304 	DoStart();
       
   305 	}
       
   306 
       
   307 void CApaEComMonitor::DoStart()
       
   308 	{
       
   309 	iEComSession->NotifyOnChange (iStatus);
       
   310 	SetActive();
       
   311 	}
       
   312 
       
   313 //callback to to call the ecomrecognizer scanning routine upon notification from ECom
       
   314 TInt CApaEComMonitor::TimerCallBack(TAny* aObject)
       
   315 	{
       
   316 	CApaEComMonitor* self=(CApaEComMonitor*)aObject;
       
   317 	if (self->iEComHasChanged)
       
   318 		{
       
   319 		self->iEComHasChanged=EFalse;
       
   320 		self->DoStart();
       
   321 		self->iCallBack.CallBack();		// Should not leave, but if it does, it's OK
       
   322 		}
       
   323 	else
       
   324 		self->iEComTimer->Cancel();
       
   325 	return KErrNone;
       
   326 	}
       
   327 
       
   328 const TInt KApaEComMonitorPause=250000;			// Wait 0.25s before calling CallBack
       
   329 const TInt KApaEComMonitorPeriod=3000000;			// Don't call CallBack again before 3s have elapsed
       
   330 
       
   331 void CApaEComMonitor::RunL()
       
   332 	{
       
   333 	if (iStatus == KErrNone)
       
   334 		{
       
   335 		iEComHasChanged = ETrue;
       
   336 		if  (!iEComTimer->IsActive())
       
   337 			{
       
   338 			iEComTimer->Start(KApaEComMonitorPause,KApaEComMonitorPeriod,TCallBack(TimerCallBack,this));
       
   339 			}
       
   340 		}
       
   341 	}
       
   342 
       
   343 #endif