|
1 /* |
|
2 * Copyright (c) 2003-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: This module defines the API to EventMediator. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32std.h> |
|
20 #include "eventmediator.h" |
|
21 #include "eventmediatorapi.h" |
|
22 #include "eventlogger.h" |
|
23 #include "clistatic.h" |
|
24 #include "log.h" |
|
25 |
|
26 /**--------------------------------------------------------- |
|
27 * |
|
28 * REventMediator class constructor |
|
29 * |
|
30 *----------------------------------------------------------*/ |
|
31 EXPORT_C REventMediator::REventMediator() : iListenedEvents(NULL) |
|
32 { |
|
33 } |
|
34 |
|
35 /**--------------------------------------------------------- |
|
36 * |
|
37 * Connect() |
|
38 * |
|
39 * Opens a session to EventMediator server and starts the server if it |
|
40 * not yet started |
|
41 * |
|
42 * Returns: KErrNone: OK |
|
43 * value: error |
|
44 * |
|
45 *----------------------------------------------------------*/ |
|
46 EXPORT_C TInt REventMediator::Connect(void) |
|
47 { |
|
48 TInt ret = KErrNone; |
|
49 TRAP(ret, CreateListenedEventsListL()); |
|
50 if (ret != KErrNone) |
|
51 { |
|
52 return ret; |
|
53 } |
|
54 |
|
55 TInt retry=2; |
|
56 for (;;) |
|
57 { |
|
58 TInt r=CreateSession(KEventMediatorServer, |
|
59 TVersion(KEventMediatorMajorVersionNumber, |
|
60 KEventMediatorMinorVersionNumber, |
|
61 KEventMediatorBuildVersionNumber), |
|
62 2 * KDefaultMessageSlots); |
|
63 |
|
64 if (r!=KErrNotFound && r!=KErrServerTerminated) |
|
65 return r; |
|
66 if (--retry==0) |
|
67 return r; |
|
68 r = Launcher::LaunchServer(KEventMediatorServer, KEventMediatorFile, |
|
69 KEventMediatorUid3); |
|
70 |
|
71 if (r!=KErrNone && r!=KErrAlreadyExists) |
|
72 return r; |
|
73 } |
|
74 } |
|
75 |
|
76 void REventMediator::CreateListenedEventsListL() |
|
77 { |
|
78 iListenedEvents = new (ELeave) CArrayFixFlat<CEventListener*>(1); |
|
79 } |
|
80 |
|
81 // --------------------------------------------------------------------------- |
|
82 // Closes a session to EventMediator server |
|
83 // --------------------------------------------------------------------------- |
|
84 // |
|
85 EXPORT_C void REventMediator::Close() |
|
86 { |
|
87 if ( iListenedEvents ) |
|
88 { |
|
89 TInt nEvents( iListenedEvents->Count() ); |
|
90 for (TInt i = 0; i < nEvents; i++) |
|
91 delete iListenedEvents->At(i); |
|
92 iListenedEvents->Delete(0,iListenedEvents->Count()); |
|
93 delete iListenedEvents; |
|
94 iListenedEvents = NULL; |
|
95 } |
|
96 RSessionBase::Close(); |
|
97 } |
|
98 |
|
99 EXPORT_C void REventMediator::ListenToEvent(TEventType aType, MEventObserver& aObserver) |
|
100 { |
|
101 LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, MEventObserver& aObserver)\n"))); |
|
102 |
|
103 TInt status=KErrNone; |
|
104 CEventListener* listener=NULL; |
|
105 TRAP(status, listener=NewEventListenerL(aType,aObserver);) |
|
106 |
|
107 if(status==KErrNone) |
|
108 { |
|
109 LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, MEventObserver& aObserver) - calling SendReceive\n"))); |
|
110 |
|
111 SendReceive(CEventMediatorSession::KEventMediatorListen, |
|
112 TIpcArgs(aType, |
|
113 &(listener->iDataLengthPckg), |
|
114 &(listener->iSrvDataPtrPckg)), |
|
115 listener->iStatus); |
|
116 |
|
117 LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, MEventObserver& aObserver) - SendReceive called\n"))); |
|
118 |
|
119 listener->SetActive(); |
|
120 } |
|
121 else |
|
122 aObserver.EventOccured(status, aType, NULL); |
|
123 } |
|
124 |
|
125 EXPORT_C void REventMediator::ListenToEvent(TEventType aType, TDesC8& aEventSpec, MEventObserver& aObserver) |
|
126 { |
|
127 LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, TDesC8& aEventSpec, MEventObserver& aObserver)\n"))); |
|
128 |
|
129 TInt status=KErrNone; |
|
130 CEventListener* listener=NULL; |
|
131 TRAP(status, listener=NewEventListenerL(aType,aObserver);) |
|
132 |
|
133 if(status==KErrNone) |
|
134 { |
|
135 listener->iSpecBuf = aEventSpec.Alloc(); |
|
136 if (listener->iSpecBuf==NULL) |
|
137 status = KErrNoMemory; |
|
138 } |
|
139 |
|
140 if(status==KErrNone) |
|
141 { |
|
142 LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, TDesC8& aEventSpec, MEventObserver& aObserver) - calling SendReceive\n"))); |
|
143 |
|
144 SendReceive(CEventMediatorSession::KEventMediatorListenWithSpec, |
|
145 TIpcArgs(aType, |
|
146 &(listener->iDataLengthPckg), |
|
147 &(listener->iSrvDataPtrPckg), |
|
148 listener->iSpecBuf), |
|
149 listener->iStatus); |
|
150 |
|
151 LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, TDesC8& aEventSpec, MEventObserver& aObserver) - SendReceive called\n"))); |
|
152 |
|
153 listener->SetActive(); |
|
154 } |
|
155 else |
|
156 aObserver.EventOccured(status, aType, NULL); |
|
157 } |
|
158 |
|
159 EXPORT_C void REventMediator::CancelListening(TEventType aType) |
|
160 { |
|
161 LOG(Log::Printf(_L("REventMediator::CancelListening(TEventType aType)\n"))); |
|
162 |
|
163 TInt index = -1; |
|
164 while ( FindEventListener( aType, index ) ) |
|
165 { |
|
166 CEventListener* listener = iListenedEvents->At( index ); |
|
167 listener->Cancel(); |
|
168 RemoveListener( listener ); |
|
169 } |
|
170 } |
|
171 |
|
172 EXPORT_C TInt REventMediator::CancelListening(TEventType aType, TDesC8& aEventSpec) |
|
173 { |
|
174 LOG(Log::Printf(_L("REventMediator::CancelListening(TEventType aType, TDesC8& aEventSpec)\n"))); |
|
175 |
|
176 TInt index = -1; |
|
177 while ( FindEventListener( aType, aEventSpec, index ) ) |
|
178 { |
|
179 CEventListener* listener = iListenedEvents->At( index ); |
|
180 listener->Cancel(); |
|
181 RemoveListener( listener ); |
|
182 } |
|
183 |
|
184 return KErrNone; |
|
185 } |
|
186 |
|
187 EXPORT_C void REventMediator::CancelAllListening() |
|
188 { |
|
189 LOG(Log::Printf(_L("REventMediator::CancelAllListening()\n"))); |
|
190 |
|
191 while ( iListenedEvents->Count() ) |
|
192 { |
|
193 CEventListener* listener = iListenedEvents->At( 0 ); |
|
194 listener->Cancel(); |
|
195 RemoveListener( listener ); |
|
196 } |
|
197 } |
|
198 |
|
199 EXPORT_C TInt REventMediator::ReportEvent(TEventType aType) |
|
200 { |
|
201 return SendReceive(CEventMediatorSession::KEventMediatorReportEvent, TIpcArgs(aType, 0, NULL)); |
|
202 } |
|
203 |
|
204 EXPORT_C TInt REventMediator::ReportEvent(TEventType aType, TDesC8& aData) |
|
205 { |
|
206 return SendReceive(CEventMediatorSession::KEventMediatorReportEvent, TIpcArgs(aType, aData.Length(), &aData)); |
|
207 } |
|
208 |
|
209 EXPORT_C TInt REventMediator::ReportEvent(TEventType aType, TDesC8& aEventSpec, TDesC8& aData) |
|
210 { |
|
211 return SendReceive(CEventMediatorSession::KEventMediatorReportEventWithSpec, TIpcArgs(aType, aData.Length(), &aData, &aEventSpec)); |
|
212 } |
|
213 |
|
214 EXPORT_C TInt REventMediator::ReportLogEvent(TUid& aSrc, TLogCategory aCategory, TUint aMsgId, TInt aDesCount,...) |
|
215 { |
|
216 VA_LIST list; |
|
217 TInt err; |
|
218 TLogEvent event(aSrc, aCategory, aMsgId,aDesCount); |
|
219 TPckg<TLogEvent> eventPckg(event); |
|
220 HBufC8* desBuf=NULL; |
|
221 TInt desBufLength; |
|
222 // alloc array for descripor pointers |
|
223 TDesC8** pointers = new TDesC8*[aDesCount]; |
|
224 TInt* lengths = new TInt[aDesCount]; |
|
225 TInt lengthsDesLth = aDesCount*sizeof(TInt); // length of a descriptor containing lengths array. |
|
226 |
|
227 // read arguments to array |
|
228 VA_START(list, aDesCount); |
|
229 err = ReadLogArguments( aDesCount, list, pointers,lengths, desBufLength); |
|
230 VA_END(list); |
|
231 |
|
232 if(err==KErrNone) |
|
233 { |
|
234 // Read arguments to one descriptor |
|
235 desBuf = HBufC8::New(eventPckg.Length()+lengthsDesLth+desBufLength); |
|
236 if(desBuf==NULL) |
|
237 err=KErrNoMemory; |
|
238 else |
|
239 { |
|
240 TPtr8 desPtr= desBuf->Des(); |
|
241 desPtr.Append(eventPckg); |
|
242 desPtr.Append((TUint8*)lengths,lengthsDesLth); |
|
243 for(TInt i=0; i < aDesCount; i++) |
|
244 { |
|
245 desPtr.Append(*(pointers[i])); |
|
246 TInt fillerLth = 4 -(lengths[i] % 4); |
|
247 TChar filler(0); |
|
248 if (fillerLth > 0 && fillerLth < 4) |
|
249 { |
|
250 desPtr.AppendFill(filler , fillerLth); |
|
251 } |
|
252 } |
|
253 err=ReportEvent(ELogEvent,desPtr); |
|
254 } |
|
255 } |
|
256 delete[] pointers; |
|
257 delete[] lengths; |
|
258 delete desBuf; |
|
259 return err; |
|
260 } |
|
261 |
|
262 EXPORT_C TInt REventMediator::NewEventSpecId() |
|
263 { |
|
264 TInt specId = 0; |
|
265 TPckg<TInt> specIdDes(specId); |
|
266 |
|
267 SendReceive(CEventMediatorSession::KEventMediatorNewEventSpecId, TIpcArgs(&specIdDes)); |
|
268 |
|
269 return specId; |
|
270 } |
|
271 |
|
272 void REventMediator::CancelListenToEvent(TEventType aType) |
|
273 { |
|
274 LOG(Log::Printf(_L("REventMediator::CancelListenToEvent(TEventType aType)\n"))); |
|
275 |
|
276 SendReceive(CEventMediatorSession::KEventMediatorCancel, TIpcArgs(aType)); |
|
277 } |
|
278 |
|
279 TInt REventMediator::CancelListenToEvent(TEventType aType, TDesC8& aEventSpec) |
|
280 { |
|
281 LOG(Log::Printf(_L("REventMediator::CancelListenToEvent(TEventType aType, TDesC8& aEventSpec)\n"))); |
|
282 |
|
283 return SendReceive(CEventMediatorSession::KEventMediatorCancelWithSpec, TIpcArgs(aType, NULL, NULL, &aEventSpec)); |
|
284 } |
|
285 |
|
286 TInt REventMediator::FetchData(TAny* aSrvPtr, TDes8& aDataPtr) |
|
287 { |
|
288 LOG(Log::Printf(_L("REventMediator::FetchData()\n"))); |
|
289 |
|
290 TRequestStatus status; |
|
291 SendReceive(CEventMediatorSession::KEventMediatorFetchData, |
|
292 TIpcArgs(aSrvPtr, &aDataPtr), status); |
|
293 User::WaitForRequest(status); |
|
294 |
|
295 LOG_1("REventMediator::FetchData() - SendReceive called, status: %d\n",status.Int()); |
|
296 return status.Int(); |
|
297 } |
|
298 |
|
299 CEventListener* REventMediator::NewEventListenerL(TEventType aType, MEventObserver& aObserver) |
|
300 { |
|
301 CEventListener* listener=NULL; |
|
302 |
|
303 listener = new (ELeave) CEventListener(aType, aObserver,this); |
|
304 CleanupStack::PushL(listener); |
|
305 iListenedEvents->AppendL(listener); |
|
306 CleanupStack::Pop(); |
|
307 return listener; |
|
308 } |
|
309 |
|
310 void REventMediator::RemoveListener(CEventListener* aListener) |
|
311 { |
|
312 TInt index=-1; |
|
313 for(TInt i=0; i<iListenedEvents->Count(); i++) |
|
314 { |
|
315 if(iListenedEvents->At(i)==aListener) |
|
316 { |
|
317 index=i; |
|
318 break; |
|
319 } |
|
320 } |
|
321 if (index >=0) |
|
322 { |
|
323 delete iListenedEvents->At(index); |
|
324 iListenedEvents->Delete(index); |
|
325 } |
|
326 } |
|
327 |
|
328 TBool REventMediator::FindEventListener(const TEventType aType, TInt& aIndex) |
|
329 { |
|
330 for( TInt i=0; i<iListenedEvents->Count(); i++ ) |
|
331 { |
|
332 if( iListenedEvents->At(i)->iType == aType ) |
|
333 { |
|
334 aIndex = i; |
|
335 return ETrue; |
|
336 } |
|
337 } |
|
338 return EFalse; |
|
339 } |
|
340 |
|
341 TBool REventMediator::FindEventListener(const TEventType aType, TDesC8& aEventSpec, TInt& aIndex) |
|
342 { |
|
343 for( TInt i=0; i<iListenedEvents->Count(); i++ ) |
|
344 { |
|
345 if( iListenedEvents->At(i)->iType == aType && |
|
346 iListenedEvents->At(i)->iSpecBuf && |
|
347 iListenedEvents->At(i)->iSpecBuf->Des().Compare( aEventSpec ) == 0 ) |
|
348 { |
|
349 aIndex = i; |
|
350 return ETrue; |
|
351 } |
|
352 } |
|
353 return EFalse; |
|
354 } |
|
355 |
|
356 TInt REventMediator::ReadLogArguments(TInt aCount, VA_LIST aList, TDesC8** aPointers, TInt* aLengths, TInt& aOverAllLength) |
|
357 { |
|
358 if(aPointers==NULL || aLengths==NULL) |
|
359 return KErrNoMemory; |
|
360 aOverAllLength=0; |
|
361 for (TInt i=0; i<aCount; i++) |
|
362 { |
|
363 aPointers[i] = (TDesC8*) VA_ARG(aList, TDesC8*); |
|
364 aLengths[i] = aPointers[i]->Length(); |
|
365 aOverAllLength += aLengths[i]; |
|
366 TInt fillerLth = 4 - (aLengths[i] % 4); |
|
367 if (fillerLth > 0 && fillerLth < 4) |
|
368 { |
|
369 aOverAllLength += fillerLth; |
|
370 } |
|
371 |
|
372 } |
|
373 return KErrNone; |
|
374 } |
|
375 |
|
376 EXPORT_C TInt REventMediator::DeletePrivateFiles() |
|
377 { |
|
378 return SendReceive (CEventMediatorSession::KEventMediatorDeletePrivateFiles, TIpcArgs()); |
|
379 } |
|
380 |
|
381 |
|
382 EXPORT_C TInt REventMediator::GetEventLogSize(TInt& aEventLogSize) |
|
383 { |
|
384 TPckg<TInt> eventLogSizePckg(aEventLogSize); |
|
385 |
|
386 return SendReceive (CEventMediatorSession::KEventMediatorGetEventLogSize, |
|
387 TIpcArgs(&eventLogSizePckg)); |
|
388 } |
|
389 |
|
390 EXPORT_C TInt REventMediator::GetEventLogHeader(TDes8& aEventLogHeader) |
|
391 { |
|
392 return SendReceive (CEventMediatorSession::KEventMediatorGetEventLogHeader, |
|
393 TIpcArgs(&aEventLogHeader)); |
|
394 } |
|
395 |
|
396 EXPORT_C TInt REventMediator::GetEventLogData(TDes8& aEventLogData) |
|
397 { |
|
398 return SendReceive (CEventMediatorSession::KEventMediatorGetEventLogData, |
|
399 TIpcArgs(&aEventLogData)); |
|
400 } |
|
401 |
|
402 EXPORT_C TInt REventMediator::ClearEventLog() |
|
403 { |
|
404 return SendReceive (CEventMediatorSession::KEventMediatorClearEventLog, TIpcArgs()); |
|
405 } |
|
406 |
|
407 |
|
408 void CEventListener::DoCancel() |
|
409 { |
|
410 if (iSpecBuf) |
|
411 iSession->CancelListenToEvent(iType, *iSpecBuf); |
|
412 else |
|
413 iSession->CancelListenToEvent(iType); |
|
414 } |
|
415 |
|
416 void CEventListener::RunL() // Should it leave? no |
|
417 { |
|
418 LOG(Log::Printf(_L("REventMediator::RunL()\n"))); |
|
419 |
|
420 if (iState == EStateListening) |
|
421 { |
|
422 HandleListeningComplete(); |
|
423 } |
|
424 } |
|
425 |
|
426 void CEventListener::HandleListeningComplete() |
|
427 { |
|
428 LOG(Log::Printf(_L("REventMediator::HandleListeningComplete()\n"))); |
|
429 |
|
430 // Event has occured, iSpecBuf is useless. |
|
431 delete iSpecBuf; |
|
432 iSpecBuf = NULL; |
|
433 |
|
434 TInt status=iStatus.Int(); |
|
435 |
|
436 LOG(Log::Printf(_L("REventMediator::HandleListeningComplete() - status = %d\n"), status)); |
|
437 |
|
438 if (status==KErrNone) |
|
439 { |
|
440 TInt dataLength = iDataLengthPckg(); |
|
441 // Some events might not have data |
|
442 if (dataLength) |
|
443 { |
|
444 iDataBuf = HBufC8::New(dataLength); |
|
445 if (iDataBuf) |
|
446 { |
|
447 LOG(Log::Printf(_L("REventMediator::HandleListeningComplete() - going to call FetchData()\n"))); |
|
448 |
|
449 iDataPtr.Set(iDataBuf->Des()); |
|
450 TInt err = iSession->FetchData(iSrvDataPtrPckg(), iDataPtr); |
|
451 iState = EStateFetchingData; |
|
452 // Event reporting to the observer and listener |
|
453 // cleanup are handled in HandleFetchingComplete |
|
454 HandleFetchingComplete(err); |
|
455 return; |
|
456 } |
|
457 else |
|
458 status = KErrNoMemory; |
|
459 } |
|
460 iObserver.EventOccured(status, iType, NULL); |
|
461 } |
|
462 else if (status!=KErrCancel) // Cancels are not reported |
|
463 { |
|
464 iObserver.EventOccured(status, iType, NULL); |
|
465 } |
|
466 |
|
467 // Listened event has occured, so this listener is done |
|
468 iSession->RemoveListener(this); |
|
469 } |
|
470 |
|
471 void CEventListener::HandleFetchingComplete(TInt aError) |
|
472 { |
|
473 LOG(Log::Printf(_L("REventMediator::HandleFetchingComplete()\n"))); |
|
474 |
|
475 LOG(Log::Printf(_L("REventMediator::HandleFetchingComplete() - status = %d\n"), aError)); |
|
476 |
|
477 if (aError==KErrNone) |
|
478 { |
|
479 iObserver.EventOccured(aError, iType, iDataBuf); |
|
480 } |
|
481 else if (aError!=KErrCancel) // Cancels are not reported |
|
482 { |
|
483 iObserver.EventOccured(aError, iType, NULL); |
|
484 } |
|
485 |
|
486 // Listened event has occured, so this listener is done |
|
487 iSession->RemoveListener(this); |
|
488 } |
|
489 |
|
490 CEventListener::CEventListener(TEventType aType,MEventObserver& aObserver, REventMediator* aSession) : |
|
491 CActive(0), iType(aType), iObserver(aObserver), iSession(aSession), |
|
492 iDataPtr(NULL, 0), iState(EStateListening) |
|
493 { |
|
494 CActiveScheduler::Add(this); |
|
495 } |
|
496 |
|
497 CEventListener::~CEventListener() |
|
498 { |
|
499 Cancel(); |
|
500 delete iSpecBuf; |
|
501 iSpecBuf = NULL; |
|
502 delete iDataBuf; |
|
503 iDataBuf = NULL; |
|
504 } |
|
505 |