Update contrib.
1 // Copyright (c) 2002-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "logservsession.h"
17 #include "LogNotify.h"
18 #include "LogServServer.h"
19 #include "logservpanic.h"
20 #include "LogServView.h"
21 #include "LogServOperationBase.h"
22 #include "LogServBackupInterface.h"
23 #include "LogServOperationFactory.h"
24 #include "LogServOperationManager.h"
25 #include "LogServDatabaseChangeInterface.h"
26 #include "LogServDatabaseChangeDefinition.h"
27 #include "LogServSqlStrings.h"
30 const TInt KLogViewListGranuality = 5;
31 const TInt KLogServPendingGlobalChangesArrayGranularity = 3;
34 /////////////////////////////////////////////////////////////////////////////////////////
35 // -----> CLogServSession (source)
36 /////////////////////////////////////////////////////////////////////////////////////////
38 CLogServSession::CLogServSession(TLogServSessionId aSessionId,
39 MLogServSessionLifetimeObserver& aObserver,
40 MLogServBackupInterface& aBackupInterface,
41 MLogServTaskInterface& aTaskInterface,
42 MLogServOperationManager& aOperationManager,
43 MLogServDatabaseChangeInterface& aChangeInterface,
44 MLogServDatabaseTransactionInterface& aDatabase) :
45 iSessionId(aSessionId),
47 iBackupInterface(aBackupInterface),
48 iTaskInterface(aTaskInterface),
49 iOperationManager(aOperationManager),
50 iChangeInterface(aChangeInterface),
52 iViewList(KLogViewListGranuality),
53 iPendingGlobalChanges(KLogServPendingGlobalChangesArrayGranularity)
55 iObserver.SLOHandleEvent(Id(), MLogServSessionLifetimeObserver::ELogServSessionEventCreated);
58 CLogServSession::~CLogServSession()
60 LOGTEXT3("CLogServSession::~CLogServSession() - client logging off: %S, %d", &iClientThreadName, iSessionId);
62 // Set second parameter to not complete the message, otherwise if the client has died a KERN-EXEC 44 will be generated.
63 iOperationManager.OMCancel(iSessionId, EFalse);
68 iChangeInterface.DCIRequestChangeNotificationsCancel(*this);
70 iViewList.ResetAndDestroy();
72 iPendingGlobalChanges.Close();
74 iObserver.SLOHandleEvent(Id(), MLogServSessionLifetimeObserver::ELogServSessionEventDestroyed);
76 LOGTEXT2("CLogServSession::~CLogServSession() - client dead %d", iSessionId);
80 /////////////////////////////////////////////////////////////////////////////////////////
81 /////////////////////////////////////////////////////////////////////////////////////////
82 /////////////////////////////////////////////////////////////////////////////////////////
84 void CLogServSession::DCOHandleGlobalChangeEventL(const TLogServDatabaseChangeDefinition& aChange)
86 if (iExtendedNotificationRequested)
87 User::LeaveIfError(iPendingGlobalChanges.Append(aChange));
88 ExtendedNotifyCompleteL(KErrNone);
91 /////////////////////////////////////////////////////////////////////////////////////////
92 /////////////////////////////////////////////////////////////////////////////////////////
93 /////////////////////////////////////////////////////////////////////////////////////////
94 void CLogServSession::CreateL()
96 iPackage = CLogPackage::NewL();
98 // Request change notifications
99 iChangeInterface.DCIRequestChangeNotificationsL(*this);
103 // Handle a client request.
105 // Leaving is handled by CLogServ::RunError() which reports the error code to the client
106 // Note: operation add themselves to the server active queue in their constructor
107 // The server active object owns them and deletes them when necessary
108 // So the iffy looking code below won't actually leak memory
110 void CLogServSession::ServiceL(const RMessage2& aMessage)
112 LOGTEXT3("CLogServSession::ServiceL(%S, %d)", &iClientThreadName, aMessage.Function());
114 switch(aMessage.Function())
117 * Overall operation management
119 case ELogOperationGetResult:
120 case ELogOperationCancel:
121 case ELogOperationInitiate:
122 ServiceOperationFunctionL(aMessage);
126 * Notification related
132 iNotify = CLogNotify::NewL(iBackupInterface, iChangeInterface, Server().Priority());
134 #ifdef LOGGING_ENABLED
135 iNotify->SetClientThreadName(iClientThreadName);
139 if (!iNotify->IsActive())
141 const TTimeIntervalMicroSeconds32 delayTime = reinterpret_cast<TInt>(aMessage.Ptr0());
143 //Validate time value
144 if(delayTime.Int() < 0)
146 User::Leave(KErrArgument);
148 iNotify->Notify(delayTime, aMessage);
151 ::PanicClientL(aMessage, ELogAlreadyActive19);
154 case ELogNotifyCancel:
158 aMessage.Complete(KErrCancel);
161 case ELogNotifyExtended:
163 if (iExtendedNotificationMessage == RMessage2())
165 iExtendedNotificationMessage = aMessage;
166 iExtendedNotificationRequested = ETrue;
169 ::PanicClientL(aMessage, ELogExtendedMessageAlreadyActive);
172 case ELogNotifyExtendedCancel:
174 if (iExtendedNotificationMessage != RMessage2())
175 ExtendedNotifyCompleteL(KErrCancel);
177 iExtendedNotificationRequested = EFalse;
178 iPendingGlobalChanges.Reset();
179 iPendingGlobalChanges.GranularCompress();
181 aMessage.Complete(KErrCancel);
191 case ELogViewOperationInitiate:
192 case ELogViewChangeNotificationsRequest:
193 case ELogViewChangeNotificationsCancel:
194 case ELogViewFetchChanges:
195 case ELogViewNotifyLockStatusChange:
196 case ELogViewNotifyLockStatusChangeCancel:
197 ServiceViewFunctionL(aMessage);
201 * Misc. (debug) functionality
204 case ELogMakeTransient:
206 Server().MakeTransient((TBool)aMessage.Ptr0());
207 aMessage.Complete(KErrNone);
210 case ELogIsServerReady:
212 const TBool serverReady = (iBackupInterface.BIErrorValueForCurrentState() == KErrNone);
213 aMessage.Complete(serverReady);
216 case ELogSetHeapFail:
218 User::__DbgSetAllocFail(RHeap::EUser, RHeap::TAllocFail(aMessage.Int0()),aMessage.Int1());
219 aMessage.Complete(KErrNone);
227 ::PanicClientL(aMessage, ELogIllegalFunction);
233 If aError is KErrBadDescriptor, then panic the client, else - default error handling.
234 KErrBadDescriptor error may be thrown from "message write" operations, if the client supplied a bad
235 descriptor to the server.
237 void CLogServSession::ServiceError(const RMessage2& aMessage,TInt aError)
239 if(aError == KErrBadDescriptor)
241 //The __LOGPANIC_CLIENT() macro cannot be used here because it calls a leaving function. A leaving call
242 //from a leaving call will terminate the server.
243 aMessage.Panic(KLogServ, ELogBadDescriptor);
245 CSession2::ServiceError(aMessage, aError);
248 /////////////////////////////////////////////////////////////////////////////////////////
249 /////////////////////////////////////////////////////////////////////////////////////////
250 /////////////////////////////////////////////////////////////////////////////////////////
252 CLogServServer& CLogServSession::Server() const
254 return *static_cast<CLogServServer*>(const_cast<CServer2*>(CSession2::Server()));
257 /////////////////////////////////////////////////////////////////////////////////////////
258 /////////////////////////////////////////////////////////////////////////////////////////
259 /////////////////////////////////////////////////////////////////////////////////////////
262 CLogServViewBase& CLogServSession::ViewByIdL(TUint32 aViewId)
264 const TInt index = ViewPositionById(aViewId);
265 User::LeaveIfError(index);
266 return *iViewList[index];
269 TInt CLogServSession::ViewPositionById(TUint32 aViewId) const
271 const TInt count = iViewList.Count();
272 for(TInt i=0; i<count; i++)
274 const CLogServViewBase& view = *iViewList[i];
275 if (view.ViewId() == aViewId)
282 void CLogServSession::ReadClientServerDataL(TLogClientServerData& aClientServerData,
283 const RMessage2 &aMessage, TInt aMinOperation, TInt aMaxOperation)
286 TInt length = aMessage.GetDesLengthL(0);
287 if(length != sizeof(TLogClientServerData))
289 User::Leave(KErrBadDescriptor);
292 TPckg<TLogClientServerData> pData(aClientServerData);
293 aMessage.ReadL(0, pData);
295 //Validate Operation Type
296 if((aClientServerData.iOperationType < aMinOperation) ||
297 (aClientServerData.iOperationType > aMaxOperation))
299 User::Leave(KErrArgument);
303 void CLogServSession::ServiceViewFunctionL(const RMessage2& aMessage)
305 switch(aMessage.Function())
309 iViewList.ReserveL(iViewList.Count() + 1);
310 // Type is first parameter, view id is second
311 const TLogViewId id = static_cast<TLogViewId>(aMessage.Int0());
312 const TLogViewType type = static_cast<TLogViewType>(aMessage.Int1());
314 //Validate type value
315 if((type < ELogViewTypeEvent)||(type > ELogViewTypeDuplicate))
317 User::Leave(KErrArgument);
320 // Ask the factory to create it
321 CLogServViewBase* view = LogServFactory::NewViewL(type, id, iDatabase, iBackupInterface, *iPackage, aMessage);
322 TInt err = iViewList.Append(view);
323 __ASSERT_ALWAYS(err == KErrNone, Panic(ELogArrayReserved));
324 aMessage.Complete(err);
329 const TLogViewId id = static_cast<TLogViewId>(aMessage.Int0());
330 TInt indexAndError = ViewPositionById(id);
331 if (indexAndError >= 0)
333 delete iViewList[indexAndError];
334 iViewList.Remove(indexAndError);
335 indexAndError = KErrNone;
337 aMessage.Complete(indexAndError);
342 const TLogViewId id = static_cast<TLogViewId>(aMessage.Int0());
343 CLogServViewBase& view = ViewByIdL(id);
344 const TInt count = view.Count();
345 aMessage.Complete(count);
348 case ELogViewOperationInitiate:
350 // We don't allow any operations during a backup
351 iBackupInterface.BIValidateStateForDatabaseOperationL();
353 TLogClientServerData clientServerData;
354 ReadClientServerDataL(clientServerData,aMessage,
355 ELogOperationViewSetup, ELogOperationViewWindowFetch);
358 const TLogViewId id = static_cast<TLogViewId>(aMessage.Int1());
359 CLogServViewBase& view = ViewByIdL(id);
361 // Create operation. Operations are owned by the operation manager (they are added to a queue)
362 // when the objects are created, so this does not leak any memory.
363 CLogServOperationBase* operation = LogServFactory::NewViewOperationL(clientServerData, iTaskInterface, iOperationManager, aMessage, *iPackage, iSessionId, view);
367 case ELogViewChangeNotificationsRequest:
369 const TLogViewId id = static_cast<TLogViewId>(aMessage.Int0());
370 CLogServViewBase& view = ViewByIdL(id);
371 view.RequestChangeNotifications(aMessage);
374 case ELogViewChangeNotificationsCancel:
376 const TLogViewId id = static_cast<TLogViewId>(aMessage.Int0());
377 CLogServViewBase& view = ViewByIdL(id);
378 view.RequestChangeNotificationsCancel();
379 aMessage.Complete(KErrNone);
382 case ELogViewFetchChanges:
384 const TLogViewId id = static_cast<TLogViewId>(aMessage.Int0());
385 CLogServViewBase& view = ViewByIdL(id);
386 view.RequestChangesL(aMessage);
387 aMessage.Complete(KErrNone);
390 case ELogViewNotifyLockStatusChange:
392 const TLogViewId id = static_cast<TLogViewId>(aMessage.Int0());
393 CLogServViewBase& view = ViewByIdL(id);
394 view.RequestLockStatusChanges(aMessage);
397 case ELogViewNotifyLockStatusChangeCancel:
399 const TLogViewId id = static_cast<TLogViewId>(aMessage.Int0());
400 CLogServViewBase& view = ViewByIdL(id);
401 view.RequestLockStatusChangesCancel();
402 aMessage.Complete(KErrNone);
408 void CLogServSession::ServiceOperationFunctionL(const RMessage2& aMessage)
410 // We don't allow any operations during a backup
411 iBackupInterface.BIValidateStateForDatabaseOperationL();
413 TLogClientServerData clientServerData;
414 ReadClientServerDataL(clientServerData,aMessage, ELogOperationEventAdd,ELogOperationMaintain);
416 const TInt function = aMessage.Function();
418 const TLogOperationId& operationId = clientServerData.iOperationId;
419 #ifdef LOGGING_ENABLED
420 const TLogOperationType& operationType = clientServerData.iOperationType;
422 LOGTEXT4("CLogServSession::ServiceOperationFunctionL() - Operation function for client %S: Id: %d, Type: %d", &iClientThreadName, operationId, operationType);
426 case ELogOperationGetResult:
427 LOGTEXT("CLogServSession::ServiceOperationFunctionL() - getting result");
428 iOperationManager.OMGetResultL(operationId, iSessionId, aMessage);
429 aMessage.Complete(KErrNone);
431 case ELogOperationCancel:
432 LOGTEXT("CLogServSession::ServiceOperationFunctionL() - cancelling");
433 iOperationManager.OMCancel(operationId, iSessionId, ETrue);
434 aMessage.Complete(KErrCancel);
436 case ELogOperationInitiate:
437 LOGTEXT("CLogServSession::ServiceOperationFunctionL() - initiating");
438 // Create operation. Operations are owned by the operation manager (they are added to a queue)
439 // when the objects are created, so this does not leak any memory.
440 CLogServOperationBase* operation = LogServFactory::NewOperationL(clientServerData, iTaskInterface, iOperationManager, aMessage, *iPackage, iSessionId);
444 LOGTEXT("CLogServSession::ServiceOperationFunctionL() - end");
447 void CLogServSession::ExtendedNotifyCompleteL(TInt aCompletionCode)
449 const TInt count = iPendingGlobalChanges.Count();
450 if (iExtendedNotificationMessage != RMessage2() && (count || aCompletionCode < KErrNone))
452 if (aCompletionCode >= KErrNone && count)
454 const TLogServDatabaseChangeDefinition& change = iPendingGlobalChanges[0];
456 const TPckgBuf<TInt> pContext(change.iChangeType.iUid);
457 const TPckg<TInt> pParam1(change.iChangeParam1);
458 const TPckg<TInt> pParam2(change.iChangeParam2);
459 const TPckg<TInt> pParam3(change.iChangeParam3);
461 iExtendedNotificationMessage.WriteL(0, pContext);
462 iExtendedNotificationMessage.WriteL(1, pParam1);
463 iExtendedNotificationMessage.WriteL(2, pParam2);
464 iExtendedNotificationMessage.WriteL(3, pParam3);
466 iPendingGlobalChanges.Remove(0);
469 iExtendedNotificationMessage.Complete(aCompletionCode);