|
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 "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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "EIKNFYSV.H" |
|
17 #include <barsread.h> |
|
18 #include <coemain.h> |
|
19 #include <eikenv.h> |
|
20 #include <eikmsg.h> |
|
21 #include <e32uid.h> |
|
22 #include "EIKSRV.PAN" |
|
23 #include "eiknotapi.h" |
|
24 #include <bafindf.h> |
|
25 #include <uiklaf/private/lafenv.h> |
|
26 #include "EIKDEBUG.H" |
|
27 #include <uiklaf/private/pluginuid.hrh> |
|
28 #include "eikscchange.h" |
|
29 |
|
30 _LIT(KPanicClient_CEikServNotifySession,"Eiksrv Cli(Nfy)"); |
|
31 |
|
32 const TInt KQueued = 1; |
|
33 const TInt KNullClientId = 0; |
|
34 const TUid KNonExistentUid = {KNullUidValue}; |
|
35 |
|
36 /** |
|
37 @internalComponent |
|
38 */ |
|
39 _LIT8(KEikNotifierPaused,"Eik_Notifier_Paused"); |
|
40 |
|
41 /** |
|
42 @internalComponent |
|
43 */ |
|
44 _LIT8(KEikNotifierResumed,"Eik_Notifier_Resumed"); |
|
45 |
|
46 #include <ecom/publicregistry.h> |
|
47 #include <uikon.hrh> |
|
48 static const TUid KUidPluginInterfaceNotifiers = {KUikonUidPluginInterfaceNotifiers}; |
|
49 |
|
50 |
|
51 const TUint KNotifierMessageOpCodeLast = 10; |
|
52 const TUint KRangeCount = 5; |
|
53 |
|
54 const TInt KOpCodeRanges[KRangeCount] = |
|
55 { |
|
56 ENotifierNotify, |
|
57 ECancelNotifier, |
|
58 EStartNotifierAndGetResponse, |
|
59 EUpdateNotifierAndGetResponse, |
|
60 KNotifierMessageOpCodeLast, |
|
61 }; |
|
62 |
|
63 const TUint8 KElementsIndex[KRangeCount] = |
|
64 { |
|
65 CPolicyServer::EAlwaysPass, //Allways passing no capability required [0-2] |
|
66 CPolicyServer::ECustomCheck, //Custom check for the Notifier Client's SID (ECancelNotifier and EUpdateNotifier) [3-4] |
|
67 CPolicyServer::EAlwaysPass, //Allways passing no capability required [5-8] |
|
68 CPolicyServer::ECustomCheck,//Custom check for the Notifier Client's SID (EUpdateNotifierAndGetResponse)[9-(KNotifierMessageOpCodeLast-1)] |
|
69 CPolicyServer::ENotSupported, //Not Supported [KNotifierMessageOpCodeLast-End] |
|
70 }; |
|
71 |
|
72 const CPolicyServer::TPolicy KEikServNotifyServerPolicy = |
|
73 { |
|
74 CPolicyServer::EAlwaysPass, |
|
75 KRangeCount, |
|
76 KOpCodeRanges, |
|
77 KElementsIndex, |
|
78 }; |
|
79 |
|
80 /** |
|
81 @internalComponent |
|
82 */ |
|
83 NONSHARABLE_CLASS(CDiscoverNewImplementation) : public CActive |
|
84 { |
|
85 public: |
|
86 static CDiscoverNewImplementation* NewL(CEikSrvNotifierManager& aManager); |
|
87 void Start(); |
|
88 ~CDiscoverNewImplementation(); |
|
89 private: |
|
90 CDiscoverNewImplementation(CEikSrvNotifierManager& aManager); |
|
91 void ConstructL(); |
|
92 void RunL(); |
|
93 void DoCancel(); |
|
94 private: |
|
95 CEikSrvNotifierManager& iManager; |
|
96 REComSession* iEComSession; |
|
97 CActiveScheduler* iScheduler; |
|
98 }; |
|
99 |
|
100 /** |
|
101 @internalComponent |
|
102 */ |
|
103 NONSHARABLE_CLASS(CPluginTrack) : public CBase |
|
104 { |
|
105 public: |
|
106 NONSHARABLE_CLASS(TNotifierInfo) |
|
107 { |
|
108 public: |
|
109 TNotifierInfo(TUid aNotifierPluginUid, TUid aNotifierPluginChannelUid); |
|
110 public: |
|
111 TUid iNotifierPluginUid; |
|
112 TUid iNotifierPluginChannelUid; |
|
113 }; |
|
114 public: |
|
115 CPluginTrack(); |
|
116 ~CPluginTrack(); |
|
117 public: |
|
118 TUid iDllUid; |
|
119 TUid iPluginImplementationUid; |
|
120 TUid iDtr_key; |
|
121 RArray<TNotifierInfo> iNotifierInfo; |
|
122 }; |
|
123 |
|
124 |
|
125 // |
|
126 // class CEikServNotifyServer |
|
127 // |
|
128 |
|
129 CEikServNotifyServer::CEikServNotifyServer(TInt aPriority, MEikServNotifyAlert* aAlert) |
|
130 : CPolicyServer(aPriority, KEikServNotifyServerPolicy), iAlert(aAlert) |
|
131 // |
|
132 // private c'tor - initialize using NewL() |
|
133 // |
|
134 { |
|
135 } |
|
136 |
|
137 EXPORT_C CEikServNotifyServer::~CEikServNotifyServer() |
|
138 { |
|
139 SetIsExiting(); |
|
140 |
|
141 if (iAlert) |
|
142 iAlert->Release(); |
|
143 |
|
144 if (iInfoMsg) |
|
145 iInfoMsg->Release(); |
|
146 |
|
147 iInfoMsgGroupWin.Close(); |
|
148 delete iManager; |
|
149 } |
|
150 |
|
151 EXPORT_C CEikServNotifyServer* CEikServNotifyServer::NewL(MEikServNotifyAlert* aAlert) |
|
152 // |
|
153 // static - Create and start the server |
|
154 { |
|
155 CEikServNotifyServer* server = new (ELeave) CEikServNotifyServer(EActivePriorityIpcEventsHigh, aAlert); |
|
156 CleanupStack::PushL(server); |
|
157 server->ConstructL(); |
|
158 CleanupStack::Pop(); // server |
|
159 return server; |
|
160 } |
|
161 |
|
162 EXPORT_C void CEikServNotifyServer::StartL() |
|
163 { |
|
164 CServer2::StartL(__NOTIFIER_NAME); |
|
165 } |
|
166 |
|
167 void CEikServNotifyServer::SetIsExiting() |
|
168 { |
|
169 iExiting = ETrue; |
|
170 } |
|
171 |
|
172 TBool CEikServNotifyServer::IsExiting() const |
|
173 { |
|
174 return iExiting; |
|
175 } |
|
176 |
|
177 void CEikServNotifyServer::ConstructL() |
|
178 // |
|
179 // private second phase construction - initialise using NewL() |
|
180 // |
|
181 { |
|
182 // notifier info print |
|
183 CEikonEnv* env = CEikonEnv::Static(); |
|
184 RWsSession& wsSession = env->WsSession(); |
|
185 iInfoMsgGroupWin = RWindowGroup(wsSession); |
|
186 User::LeaveIfError(iInfoMsgGroupWin.Construct((TUint32)this, EFalse)); // EFalse disables key events |
|
187 iInfoMsgGroupWin.SetOrdinalPosition(0, ECoeWinPriorityAlwaysAtFront-1); |
|
188 |
|
189 iInfoMsg = LafEnv::NewInfoMsgWinL(*env, iInfoMsgGroupWin); |
|
190 |
|
191 // notifier manager |
|
192 iManager = CEikSrvNotifierManager::NewL(); |
|
193 iManager->RegisterL(); |
|
194 } |
|
195 |
|
196 EXPORT_C void CEikServNotifyServer::DisplayNotifier(const TDesC& aTitle,const TDesC& aLabel, const TDesC& aBut1, const TDesC& aBut2, MEikNotifyAlertCompletionObserver* aObserver) |
|
197 { |
|
198 if(iAlert) |
|
199 iAlert->DisplayNotifier(aTitle, aLabel, aBut1, aBut2, aObserver); |
|
200 } |
|
201 |
|
202 EXPORT_C void CEikServNotifyServer::DisplayInfoPrint(const TDesC& aDes) |
|
203 { |
|
204 if(iInfoMsg) |
|
205 iInfoMsg->StartDisplay(aDes, EHRightVTop); |
|
206 } |
|
207 |
|
208 CSession2* CEikServNotifyServer::NewSessionL(const TVersion &aVersion,const RMessage2&) const |
|
209 { |
|
210 const TVersion version(1,0,0); // !! liaise with RNotify client-side class in E32 |
|
211 if (!User::QueryVersionSupported(version,aVersion)) |
|
212 User::Leave(KErrNotSupported); |
|
213 |
|
214 return CEikServNotifySession::NewL(); |
|
215 } |
|
216 |
|
217 CPolicyServer::TCustomResult CEikServNotifyServer::CustomSecurityCheckL(const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/) |
|
218 //aAction is not set because default value to it is already set(CPolicyServer::EFailClient) |
|
219 //aMissing is not set because it is not needed as we aren't overriding CheckFailedL |
|
220 { |
|
221 const TUid notifierUid = TUid::Uid(aMsg.Int0()); |
|
222 const TSecureId clientSid = aMsg.SecureId(); |
|
223 |
|
224 const TInt count = iAsyncSecureInfoQueue.Count(); |
|
225 for(int i = 0; i < count; i++) |
|
226 { |
|
227 if(iAsyncSecureInfoQueue[i].iSecureId == clientSid) |
|
228 return CPolicyServer::EPass; |
|
229 } |
|
230 |
|
231 return CPolicyServer::EFail; |
|
232 } |
|
233 |
|
234 // |
|
235 // class TNotifierMessageInfo |
|
236 // |
|
237 |
|
238 TNotifierMessageInfo::TNotifierMessageInfo(const RMessage2& aMessage, CEikServNotifySession& aEikServNotifySession) |
|
239 : iMessage(aMessage), iEikServNotifySession(aEikServNotifySession) |
|
240 { |
|
241 } |
|
242 |
|
243 // |
|
244 // class CEikServNotifySession |
|
245 // |
|
246 |
|
247 CEikServNotifySession* CEikServNotifySession::NewL() |
|
248 { |
|
249 CEikServNotifySession* const notifySession = new(ELeave) CEikServNotifySession; |
|
250 CleanupStack::PushL(notifySession); |
|
251 notifySession->ConstructL(); |
|
252 CleanupStack::Pop(notifySession); |
|
253 return notifySession; |
|
254 } |
|
255 |
|
256 CEikServNotifySession::~CEikServNotifySession() |
|
257 { |
|
258 const CEikServNotifyServer& server = Server(); |
|
259 if (!server.IsExiting()) |
|
260 server.Manager()->HandleClientExit(iClientId); |
|
261 |
|
262 iServer = NULL; |
|
263 delete iEikSrvPendingAlert; |
|
264 delete iBuffer; |
|
265 } |
|
266 |
|
267 CEikServNotifySession::CEikServNotifySession() : iClientId(reinterpret_cast<TInt>(this)) |
|
268 { |
|
269 } |
|
270 |
|
271 void CEikServNotifySession::ConstructL() |
|
272 { |
|
273 iEikSrvPendingAlert = new(ELeave) CEikSrvPendingAlert(*this); |
|
274 } |
|
275 |
|
276 void CEikServNotifySession::ServiceL(const RMessage2 &aMessage) |
|
277 // |
|
278 // Service requests |
|
279 // |
|
280 { |
|
281 DEBUGPRINT3(_L("CEikServNotifySession::ServiceL(), UID: 0x%X op:%D"),aMessage.Int0(),aMessage.Function()); |
|
282 |
|
283 TBool completeMessage = ETrue; |
|
284 switch (aMessage.Function()) |
|
285 { |
|
286 case ENotifierNotify: |
|
287 DisplayAlert(aMessage); |
|
288 completeMessage = EFalse; // Completed in HandleAlertCompletion |
|
289 break; |
|
290 case ENotifierInfoPrint: |
|
291 DisplayInfoMsg(aMessage); |
|
292 break; |
|
293 case EStartNotifier: |
|
294 StartNotifierL(aMessage); |
|
295 break; |
|
296 case ECancelNotifier: |
|
297 { |
|
298 TInt result = NotifierCancel(aMessage); |
|
299 if(result == KErrNone) |
|
300 { |
|
301 result = Server().Manager()->NotifierCancel(TUid::Uid(aMessage.Int0())); |
|
302 } |
|
303 aMessage.Complete(result); |
|
304 completeMessage = EFalse; |
|
305 } |
|
306 break; |
|
307 case EUpdateNotifier: |
|
308 { |
|
309 UpdateNotifierL(aMessage); |
|
310 completeMessage = EFalse; // Completed in UpdateNotifierL |
|
311 } |
|
312 break; |
|
313 case EStartNotifierAndGetResponse: |
|
314 { |
|
315 TBool cleanupComplete = ETrue; |
|
316 StartNotifierAndGetResponseL(aMessage, cleanupComplete); |
|
317 completeMessage = EFalse; // the plug-in has responsibility for completing the message (either synchronously or asynchronously) |
|
318 } |
|
319 break; |
|
320 case EUpdateNotifierAndGetResponse: |
|
321 UpdateNotifierAndGetResponseL(aMessage); |
|
322 completeMessage = EFalse; |
|
323 break; |
|
324 default: |
|
325 aMessage.Complete(KErrNotSupported); |
|
326 break; |
|
327 } |
|
328 |
|
329 if (completeMessage && !aMessage.IsNull()) |
|
330 aMessage.Complete(KErrNone); |
|
331 |
|
332 DEBUGPRINT3(_L("CEikServNotifySession::ServiceL() finished, UID: 0x%X Message completed: %U"),aMessage.Int0(),completeMessage); |
|
333 } |
|
334 |
|
335 void CEikServNotifySession::DisplayAlert(const RMessage2& aMessage) |
|
336 // |
|
337 // Display an alert |
|
338 // |
|
339 { |
|
340 iLengthOfCombinedBuffer = aMessage.GetDesLength(1); |
|
341 if (iLengthOfCombinedBuffer < 0) |
|
342 return; |
|
343 |
|
344 iLengthOfFirstLineOfMessage = (static_cast<TUint>(aMessage.Int2())>>16); |
|
345 iLengthOfSecondLineOfMessage = (aMessage.Int2()&KMaxTUint16); |
|
346 iLengthOfFirstButtonOfMessage = (static_cast<TUint>(aMessage.Int3())>>16); |
|
347 iLengthOfSecondButtonOfMessage = (aMessage.Int3()&KMaxTUint16); |
|
348 |
|
349 if (iLengthOfCombinedBuffer != iLengthOfFirstLineOfMessage + iLengthOfSecondLineOfMessage + |
|
350 iLengthOfFirstButtonOfMessage + iLengthOfSecondButtonOfMessage) |
|
351 { |
|
352 aMessage.Panic(KPanicClient_CEikServNotifySession,EEikSrvClientPanicInconsistentMessageParameters); |
|
353 return; |
|
354 } |
|
355 |
|
356 HBufC* const combinedBuffer = HBufC::New(iLengthOfCombinedBuffer); |
|
357 if(!combinedBuffer) |
|
358 return; |
|
359 |
|
360 TPtr combinedBuffer_asWritable(combinedBuffer->Des()); |
|
361 const TInt error = aMessage.Read(1, combinedBuffer_asWritable); |
|
362 if (error) |
|
363 { |
|
364 delete combinedBuffer; |
|
365 return; |
|
366 } |
|
367 |
|
368 __ASSERT_DEBUG(iBuffer == NULL, User::Invariant()); |
|
369 iBuffer = combinedBuffer; |
|
370 |
|
371 RNotifierMessageInfoQueue& queue = Server().AsyncMessageQueue(); |
|
372 const TInt err = queue.Append(TNotifierMessageInfo(aMessage,*this)); |
|
373 if (!err && queue.Count() == 1) // if the only thing in the queue is what we've just put in it... |
|
374 PrepareDisplayAlert(); |
|
375 } |
|
376 |
|
377 void CEikServNotifySession::PrepareDisplayAlert() |
|
378 { |
|
379 const RNotifierMessageInfoQueue& queue = Server().AsyncMessageQueue(); |
|
380 //Getting the first element from the queue |
|
381 ASSERT(queue.Count()); |
|
382 const TNotifierMessageInfo& firstInQueue = queue[0]; |
|
383 |
|
384 //Getting the parameters for the notifier message to display |
|
385 const TInt lengthOfFirstLine = firstInQueue.iEikServNotifySession.iLengthOfFirstLineOfMessage; |
|
386 const TInt lengthOfSecondLine = firstInQueue.iEikServNotifySession.iLengthOfSecondLineOfMessage; |
|
387 const TInt lengthOfFirstButton = firstInQueue.iEikServNotifySession.iLengthOfFirstButtonOfMessage; |
|
388 const TInt lengthOfSecondButton = firstInQueue.iEikServNotifySession.iLengthOfSecondButtonOfMessage; |
|
389 |
|
390 const TPtrC firstLineOfMessage(firstInQueue.iEikServNotifySession.iBuffer->Left(lengthOfFirstLine)); |
|
391 const TPtrC secondLineOfMessage(firstInQueue.iEikServNotifySession.iBuffer->Mid(lengthOfFirstLine,lengthOfSecondLine)); |
|
392 const TPtrC firstButtonOfMessage(firstInQueue.iEikServNotifySession.iBuffer->Mid(lengthOfFirstLine+lengthOfSecondLine,lengthOfFirstButton)); |
|
393 const TPtrC secondButtonOfMessage(firstInQueue.iEikServNotifySession.iBuffer->Mid(lengthOfFirstLine+lengthOfSecondLine+lengthOfFirstButton,lengthOfSecondButton)); |
|
394 |
|
395 // after this line we can guarantee that HandleAlertCompletion will be called (assuming that the call to MEikServNotifyAlert's virtual function DisplayNotifier (which is called inside the DisplayNotifier call below) is well-behaved) |
|
396 Server().DisplayNotifier(firstLineOfMessage, secondLineOfMessage, firstButtonOfMessage, secondButtonOfMessage, &firstInQueue.iEikServNotifySession); |
|
397 } |
|
398 |
|
399 void CEikServNotifySession::HandleAlertCompletion(const TInt aButtonVal) |
|
400 { |
|
401 RNotifierMessageInfoQueue& queue = Server().AsyncMessageQueue(); |
|
402 __ASSERT_ALWAYS(queue.Count() > 0,Panic(EEikServPanicNotifyAlertQueueEmpty)); |
|
403 |
|
404 const TNotifierMessageInfo& firstInQueue = queue[0]; |
|
405 firstInQueue.iMessage.Complete(firstInQueue.iMessage.Write(0, TPckgC<TInt>(aButtonVal == EEikBidCancel ? 0 : 1))); |
|
406 if (firstInQueue.iEikServNotifySession.iBuffer) |
|
407 { |
|
408 delete firstInQueue.iEikServNotifySession.iBuffer; |
|
409 firstInQueue.iEikServNotifySession.iBuffer = NULL; |
|
410 } |
|
411 |
|
412 queue.Remove(0); |
|
413 if (queue.Count()) |
|
414 iEikSrvPendingAlert->TriggerNext(); |
|
415 } |
|
416 |
|
417 void CEikServNotifySession::DisplayNextPendingAlert() |
|
418 { |
|
419 if (Server().AsyncMessageQueue().Count() >= 1) |
|
420 PrepareDisplayAlert(); |
|
421 } |
|
422 |
|
423 void CEikServNotifySession::DisplayInfoMsg(const RMessage2& aMessage) |
|
424 // |
|
425 // Display an info message |
|
426 // |
|
427 { |
|
428 TBuf<400> msg; |
|
429 const TInt err = aMessage.Read(0, msg); |
|
430 aMessage.Complete(err); |
|
431 if(!err) |
|
432 Server().DisplayInfoPrint(msg); |
|
433 } |
|
434 |
|
435 HBufC8* CEikServNotifySession::GetRemoteInputBufferLC(const RMessage2& aMessage, TInt aSlot) |
|
436 { |
|
437 HBufC8* const inputBuffer = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(aSlot))); |
|
438 TPtr8 input(inputBuffer->Des()); |
|
439 aMessage.ReadL(aSlot, input); |
|
440 return inputBuffer; |
|
441 } |
|
442 |
|
443 |
|
444 void CEikServNotifySession::StartNotifierL(const RMessage2& aMessage) |
|
445 { |
|
446 HBufC8* const inputBuffer = GetRemoteInputBufferLC(aMessage, 1); |
|
447 const TUid notifierUid = TUid::Uid(aMessage.Int0()); |
|
448 const TSecureId secureId = aMessage.SecureId(); |
|
449 RNotifierSecureInfoQueue& secureInfoQueue = Server().AsyncSecureInfoQueue(); |
|
450 secureInfoQueue.AppendL(TNotifierSecureInfo(notifierUid, secureId)); |
|
451 |
|
452 if (!aMessage.Int2()) // if the third parameter is null |
|
453 { |
|
454 TRAPD(err, Server().Manager()->NotifierStartL(TUid::Uid(aMessage.Int0()),*inputBuffer,NULL,iClientId)); |
|
455 if(err) |
|
456 { |
|
457 secureInfoQueue.Remove(secureInfoQueue.Count()-1); |
|
458 User::Leave(err); |
|
459 } |
|
460 } |
|
461 else |
|
462 { |
|
463 HBufC8* const responseBuffer = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesMaxLength(2))); |
|
464 TPtr8 response(responseBuffer->Des()); |
|
465 TRAPD(err, Server().Manager()->NotifierStartL(TUid::Uid(aMessage.Int0()), *inputBuffer, &response, iClientId)); |
|
466 if(err) |
|
467 { |
|
468 secureInfoQueue.Remove(secureInfoQueue.Count()-1); |
|
469 User::Leave(err); |
|
470 } |
|
471 |
|
472 aMessage.WriteL(2,response); |
|
473 CleanupStack::PopAndDestroy(responseBuffer); |
|
474 } |
|
475 |
|
476 CleanupStack::PopAndDestroy(inputBuffer); |
|
477 } |
|
478 |
|
479 void CEikServNotifySession::UpdateNotifierL(const RMessage2& aMessage) |
|
480 { |
|
481 const RNotifierSecureInfoQueue& secureInfoQueue=Server().AsyncSecureInfoQueue(); |
|
482 const TUid notifierUid = TUid::Uid(aMessage.Int0()); |
|
483 const TInt queueTotal = secureInfoQueue.Count(); |
|
484 TBool completeMessage = EFalse; |
|
485 for(TInt i = 0; i < queueTotal; i++) |
|
486 { |
|
487 if(secureInfoQueue[i].iNotifierUid == notifierUid && secureInfoQueue[i].iSecureId == aMessage.SecureId()) |
|
488 { |
|
489 HBufC8* const inputBuffer = GetRemoteInputBufferLC(aMessage, 1); |
|
490 if (!aMessage.Int2()) // if the third parameter is null |
|
491 { |
|
492 TRAPD(err, Server().Manager()->NotifierUpdateL(TUid::Uid(aMessage.Int0()), *inputBuffer, NULL, iClientId)); |
|
493 aMessage.Complete(err); |
|
494 } |
|
495 else |
|
496 { |
|
497 HBufC8* const outputBuffer = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesMaxLength(2))); |
|
498 TPtr8 output(outputBuffer->Des()); |
|
499 TRAPD(err, Server().Manager()->NotifierUpdateL(notifierUid, *inputBuffer, &output, iClientId)); |
|
500 if(!err) |
|
501 aMessage.WriteL(2,*outputBuffer); |
|
502 |
|
503 CleanupStack::PopAndDestroy(outputBuffer); |
|
504 aMessage.Complete(err); |
|
505 } |
|
506 completeMessage = ETrue; |
|
507 CleanupStack::PopAndDestroy(inputBuffer); |
|
508 break; |
|
509 } |
|
510 } |
|
511 |
|
512 if (!completeMessage) |
|
513 aMessage.Complete(KErrNotFound); |
|
514 } |
|
515 |
|
516 void CEikServNotifySession::StartNotifierAndGetResponseL(const RMessage2& aMessage,TBool& aCleanupComplete) |
|
517 { |
|
518 HBufC8* const inputBuffer = GetRemoteInputBufferLC(aMessage, 1); |
|
519 const TUid notifierUid = TUid::Uid(aMessage.Int0()); |
|
520 const TSecureId secureId = aMessage.SecureId(); |
|
521 RNotifierSecureInfoQueue& secureInfoQueue = Server().AsyncSecureInfoQueue(); |
|
522 secureInfoQueue.AppendL(TNotifierSecureInfo(notifierUid,secureId)); |
|
523 |
|
524 TRAPD(err, Server().Manager()->NotifierStartAndGetResponseL(TUid::Uid(aMessage.Int0()), *inputBuffer, 2, aMessage, iClientId, aCleanupComplete)); |
|
525 if(err) |
|
526 { |
|
527 secureInfoQueue.Remove(secureInfoQueue.Count()-1); |
|
528 User::Leave(err); |
|
529 } |
|
530 |
|
531 CleanupStack::PopAndDestroy(inputBuffer); |
|
532 } |
|
533 |
|
534 void CEikServNotifySession::UpdateNotifierAndGetResponseL(const RMessage2& aMessage) |
|
535 { |
|
536 const RNotifierSecureInfoQueue& secureInfoQueue=Server().AsyncSecureInfoQueue(); |
|
537 const TUid notifierUid = TUid::Uid(aMessage.Int0()); |
|
538 const TInt queueTotal = secureInfoQueue.Count(); |
|
539 TBool completeMessage = ETrue; |
|
540 for(TInt i = 0; i < queueTotal; i++) |
|
541 { |
|
542 if(secureInfoQueue[i].iNotifierUid == notifierUid && secureInfoQueue[i].iSecureId == aMessage.SecureId()) |
|
543 { |
|
544 HBufC8* const inputBuffer = GetRemoteInputBufferLC(aMessage, 1); |
|
545 Server().Manager()->NotifierUpdateAndGetResponseL(notifierUid, *inputBuffer, 2, aMessage, iClientId); |
|
546 CleanupStack::PopAndDestroy(inputBuffer); |
|
547 completeMessage = EFalse; |
|
548 break; |
|
549 } |
|
550 } |
|
551 |
|
552 if (completeMessage) |
|
553 aMessage.Complete(KErrNotSupported); // The client that initially created or connected to the notifier was not found |
|
554 } |
|
555 |
|
556 |
|
557 TInt CEikServNotifySession::NotifierCancel(const RMessage2& aMessage) |
|
558 { |
|
559 RNotifierSecureInfoQueue& secureInfoQueue = Server().AsyncSecureInfoQueue(); |
|
560 const TUid notifierUid = TUid::Uid(aMessage.Int0()); |
|
561 const TSecureId secureId = aMessage.SecureId(); |
|
562 TInt queueTotal = secureInfoQueue.Count(); |
|
563 |
|
564 for(TInt i = 0; i < queueTotal; i++) |
|
565 { |
|
566 if(secureInfoQueue[i].iNotifierUid == notifierUid && secureInfoQueue[i].iSecureId == secureId) |
|
567 { |
|
568 secureInfoQueue.Remove(i); |
|
569 return KErrNone; |
|
570 } |
|
571 } |
|
572 return KErrNotFound; |
|
573 } |
|
574 |
|
575 CEikServNotifySession::CEikSrvPendingAlert::CEikSrvPendingAlert(CEikServNotifySession& aEikServNotifySession) |
|
576 : CActive(EActivePriorityClockTimer), iEikServNotifySession(aEikServNotifySession) |
|
577 { |
|
578 CActiveScheduler::Add(this); |
|
579 } |
|
580 |
|
581 CEikServNotifySession::CEikSrvPendingAlert::~CEikSrvPendingAlert() |
|
582 { |
|
583 Cancel(); |
|
584 } |
|
585 |
|
586 void CEikServNotifySession::CEikSrvPendingAlert::TriggerNext() |
|
587 { |
|
588 iStatus = KRequestPending; |
|
589 SetActive(); |
|
590 TRequestStatus* status = &iStatus; |
|
591 User::RequestComplete(status, KErrNone); |
|
592 } |
|
593 |
|
594 void CEikServNotifySession::CEikSrvPendingAlert::DoCancel() |
|
595 { |
|
596 } |
|
597 |
|
598 void CEikServNotifySession::CEikSrvPendingAlert::RunL() |
|
599 { |
|
600 iEikServNotifySession.DisplayNextPendingAlert(); |
|
601 } |
|
602 // |
|
603 //CEikSrvNotifierWrapper |
|
604 // |
|
605 |
|
606 CEikSrvNotifierWrapper::CEikSrvNotifierWrapper(MEikSrvNotifierBase2* aNotifier) |
|
607 : iNotifier(aNotifier) |
|
608 { |
|
609 } |
|
610 |
|
611 CEikSrvNotifierWrapper::~CEikSrvNotifierWrapper() |
|
612 { |
|
613 if(iNotifier) |
|
614 iNotifier->Release(); |
|
615 } |
|
616 |
|
617 void CEikSrvNotifierWrapper::RegisterNotifierL() |
|
618 { |
|
619 iInfo = iNotifier->RegisterL(); |
|
620 } |
|
621 |
|
622 // |
|
623 //CEikSrvNotifierRemover |
|
624 // |
|
625 |
|
626 CEikSrvNotifierRemover* CEikSrvNotifierRemover::NewL() |
|
627 {//static |
|
628 CEikSrvNotifierRemover* self = new(ELeave) CEikSrvNotifierRemover(); |
|
629 CActiveScheduler::Add(self); |
|
630 return self; |
|
631 } |
|
632 |
|
633 CEikSrvNotifierRemover::CEikSrvNotifierRemover() |
|
634 : CActive(EPriorityHigh) // high priority active object, s.t. it gets run before any more requests to cservers in the eiksrv thread. |
|
635 { |
|
636 } |
|
637 |
|
638 CEikSrvNotifierRemover::~CEikSrvNotifierRemover() |
|
639 { |
|
640 Cancel(); |
|
641 } |
|
642 |
|
643 void CEikSrvNotifierRemover::Start(CEikSrvNotifierManager* aManager, CArrayPtr<CEikSrvNotifierWrapper>* aObservedList) |
|
644 { |
|
645 __ASSERT_ALWAYS(aObservedList, Panic(EEikServPanicNullObservedList)); |
|
646 iManager = aManager; |
|
647 iObservedList = aObservedList; |
|
648 SetActive(); |
|
649 iStatus = KRequestPending; |
|
650 TRequestStatus* status = &iStatus; |
|
651 User::RequestComplete(status, KErrNone); |
|
652 } |
|
653 |
|
654 void CEikSrvNotifierRemover::RunL() |
|
655 { |
|
656 const TInt maxIndex = iObservedList->Count() - 1; |
|
657 for(TInt ii = maxIndex; ii >= 0; ii--) |
|
658 { |
|
659 CEikSrvNotifierWrapper* notifierWrapper = iObservedList->At(ii); |
|
660 const MEikSrvNotifierBase2::TNotifierInfo info = notifierWrapper->iNotifier->Info(); |
|
661 const TUid plugInDllUid = notifierWrapper->iPlugInDllUid; |
|
662 if(notifierWrapper->iIsReadyForRemoval) |
|
663 { |
|
664 if(plugInDllUid != KNullUid) // only cancel if it comes from one of the transient dlls ! |
|
665 { |
|
666 delete notifierWrapper; |
|
667 iObservedList->Delete(ii); // resize the CEikSrvNotifierWrapper array |
|
668 } |
|
669 } |
|
670 } |
|
671 } |
|
672 |
|
673 void CEikSrvNotifierRemover::DoCancel() |
|
674 { |
|
675 } |
|
676 |
|
677 // |
|
678 //CEikSrvNotifierManager |
|
679 // |
|
680 |
|
681 CEikSrvNotifierManager* CEikSrvNotifierManager::NewL() |
|
682 { |
|
683 CEikSrvNotifierManager* self = new (ELeave) CEikSrvNotifierManager; |
|
684 CleanupStack::PushL(self); |
|
685 self->ConstructL(); |
|
686 CleanupStack::Pop(); // self |
|
687 return self; |
|
688 } |
|
689 |
|
690 CEikSrvNotifierManager::~CEikSrvNotifierManager() |
|
691 { |
|
692 if (iObservedList) |
|
693 { |
|
694 iObservedList->ResetAndDestroy(); |
|
695 delete iObservedList; |
|
696 } |
|
697 |
|
698 // This calls REComSession::DestroyedImplementation which closes plug-in libraries, |
|
699 // hence must be called *after* the virtual Release function is called on the |
|
700 // plug-ins (inside the iObservedList->ResetAndDestroy() call above) |
|
701 iPluginUidList.ResetAndDestroy(); |
|
702 iPluginUidList.Close(); |
|
703 |
|
704 delete iChannelMonitor; |
|
705 delete iActivityMonitor; |
|
706 delete iQueue; |
|
707 delete iNotifierRemover; |
|
708 delete iDiscoverNewImplementation; |
|
709 } |
|
710 |
|
711 LOCAL_C void DeleteTempMArray(TAny* aPtr) |
|
712 { |
|
713 CArrayPtr<MEikSrvNotifierBase2>* array = reinterpret_cast<CArrayPtr<MEikSrvNotifierBase2>*>(aPtr); |
|
714 const TInt count = array->Count(); |
|
715 for(TInt ii = 0; ii < count; ii++) |
|
716 (*array)[ii]->Release(); |
|
717 |
|
718 delete array; |
|
719 } |
|
720 |
|
721 LOCAL_C void DeleteTempCArray(TAny* aPtr) |
|
722 { |
|
723 CArrayPtr<CEikSrvNotifierWrapper>* const array = reinterpret_cast<CArrayPtr<CEikSrvNotifierWrapper>*>(aPtr); |
|
724 array->ResetAndDestroy(); |
|
725 delete array; |
|
726 } |
|
727 |
|
728 |
|
729 CArrayPtr<CEikSrvNotifierWrapper>* CEikSrvNotifierManager::CreateNotifierArrayFromPlugInArrayL(CArrayPtr<MEikSrvNotifierBase2>* aPlugInArray, const TUidType& /*aUidType*/) |
|
730 { |
|
731 User::LeaveIfNull(aPlugInArray); |
|
732 const TInt count = aPlugInArray->Count(); |
|
733 CleanupStack::PushL(TCleanupItem(DeleteTempMArray,aPlugInArray)); |
|
734 const TInt arrayIncrement = Max(1, count); // at least one |
|
735 |
|
736 CArrayPtrFlat<CEikSrvNotifierWrapper>* retArray = new (ELeave)CArrayPtrFlat<CEikSrvNotifierWrapper>(arrayIncrement); |
|
737 CleanupStack::PushL(TCleanupItem(DeleteTempCArray,retArray)); |
|
738 for(TInt ii = 0; ii < count; ii++) |
|
739 { |
|
740 MEikSrvNotifierBase2* notif = aPlugInArray->At(0); |
|
741 notif->SetManager(this); |
|
742 CEikSrvNotifierWrapper* notifier = new (ELeave) CEikSrvNotifierWrapper(notif); |
|
743 aPlugInArray->Delete(0); // remove notif from aPlugInArray |
|
744 CleanupStack::PushL(notifier); |
|
745 retArray->AppendL(notifier); |
|
746 CleanupStack::Pop(notifier); |
|
747 } |
|
748 |
|
749 CleanupStack::Pop(retArray); |
|
750 CleanupStack::PopAndDestroy(aPlugInArray); |
|
751 return retArray; |
|
752 } |
|
753 |
|
754 void CEikSrvNotifierManager::UpdateHighestPriorityNotifiersOnThisChannelOfTheirPausingOrResuming(TUid aChannelUid, TUid aHighestPriorityNotifierOnThisChannelUid, const TDesC8& aBuffer) |
|
755 { |
|
756 const TInt count = iObservedList->Count(); |
|
757 for (TInt jj = 0; jj < count; jj++) |
|
758 { |
|
759 MEikSrvNotifierBase2* notifForUpdate = ((*iObservedList)[jj])->iNotifier; |
|
760 const MEikSrvNotifierBase2::TNotifierInfo infoForUpdate = notifForUpdate->Info(); |
|
761 if (infoForUpdate.iUid == aHighestPriorityNotifierOnThisChannelUid && infoForUpdate.iChannel == aChannelUid) |
|
762 { |
|
763 TRAP_IGNORE(notifForUpdate->UpdateL(aBuffer)); |
|
764 } |
|
765 } |
|
766 } |
|
767 |
|
768 void CEikSrvNotifierManager::TryAddNotifiersFromNotifierArrayL(CArrayPtr<CEikSrvNotifierWrapper>* aNotifierArray, TInt& aRollBackChannels) |
|
769 { |
|
770 const TInt maxIndex = aNotifierArray->Count() - 1; |
|
771 for(TInt ii = maxIndex; ii >= 0; ii--) |
|
772 { |
|
773 CEikSrvNotifierWrapper* notifier = aNotifierArray->At(ii); |
|
774 iObservedList->AppendL(notifier); // notifier is owned by aNotifierArray, so should this fail, everything is ok. |
|
775 aNotifierArray->Delete(ii); // wan't to get this pointer out of aNotifierArray asap to avoid double deletion from cleanup stack. |
|
776 const MEikSrvNotifierBase2::TNotifierInfo& info = notifier->iInfo; |
|
777 DEBUGPRINT4(_L("CEikSrvNotifierManager::TryAddNotifiersFromNotifierArrayL; Adding notifier: UID 0x%X, priority %d, channel 0x%X"),info.iUid,info.iPriority,info.iChannel); |
|
778 |
|
779 if (!iChannelMonitor->AlreadyHasChannel(info.iChannel)) |
|
780 { |
|
781 iChannelMonitor->AddNewChannelL(info.iChannel); |
|
782 ++aRollBackChannels; |
|
783 } |
|
784 } |
|
785 } |
|
786 |
|
787 CEikSrvNotifierManager::CEikSrvNotifierManager() |
|
788 { |
|
789 } |
|
790 |
|
791 void CEikSrvNotifierManager::ConstructL() |
|
792 { |
|
793 iObservedList = new(ELeave) CArrayPtrSeg<CEikSrvNotifierWrapper>(6); |
|
794 iChannelMonitor = CChannelMonitor::NewL(); |
|
795 iActivityMonitor = CActivityMonitor::NewL(); |
|
796 iQueue = CEikNotifierQueue::NewL(); |
|
797 iNotifierRemover = CEikSrvNotifierRemover::NewL(); |
|
798 iDiscoverNewImplementation = CDiscoverNewImplementation::NewL(*this); |
|
799 } |
|
800 |
|
801 struct SActivityCleanup |
|
802 { |
|
803 CActivityMonitor* iMonitor; |
|
804 TUid iNotifier; |
|
805 TInt iClientId; |
|
806 }; |
|
807 |
|
808 LOCAL_C void CleanupActivityMonitor(TAny* aPtr) |
|
809 { |
|
810 SActivityCleanup& cleanup = *reinterpret_cast<SActivityCleanup*>(aPtr); |
|
811 cleanup.iMonitor->Remove(cleanup.iNotifier, cleanup.iClientId); |
|
812 } |
|
813 |
|
814 class MNotifierStarter |
|
815 { |
|
816 public: |
|
817 virtual TInt StartAlreadyActiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer) = 0; |
|
818 virtual void StartInactiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer, TDes8* aResponse) = 0; |
|
819 virtual CEikNotifierQueue::CQueueItem* NewQueueItemLC(const MEikSrvNotifierBase2::TNotifierInfo& aInfo, TInt aClientId, const TDesC8& aBuffer) = 0; |
|
820 }; |
|
821 |
|
822 class MNotifierUpdater |
|
823 { |
|
824 public: |
|
825 virtual void UpdateActiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer, TDes8* aResponse) = 0; |
|
826 }; |
|
827 |
|
828 // |
|
829 // class TSynchronousNotifierUpdater |
|
830 // |
|
831 |
|
832 NONSHARABLE_CLASS(TSynchronousNotifierUpdater) : public MNotifierUpdater |
|
833 { |
|
834 public: |
|
835 inline TSynchronousNotifierUpdater() {} |
|
836 private: |
|
837 virtual void UpdateActiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer, TDes8* aResponse); |
|
838 }; |
|
839 |
|
840 void TSynchronousNotifierUpdater::UpdateActiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer, TDes8* aResponse) |
|
841 { |
|
842 if (aResponse) |
|
843 aResponse->Copy(aNotifier.UpdateL(aBuffer)); |
|
844 else |
|
845 aNotifier.UpdateL(aBuffer); |
|
846 } |
|
847 |
|
848 NONSHARABLE_CLASS(TAsynchronousNotifierUpdater) : public MNotifierUpdater |
|
849 { |
|
850 public: |
|
851 TAsynchronousNotifierUpdater(TInt aReplySlot, const RMessage2& aMessage); |
|
852 private: // from TSynchronousNotifierUpdater |
|
853 void UpdateActiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer, TDes8* aResponse); |
|
854 private: |
|
855 TInt iReplySlot; |
|
856 const RMessage2& iMessage; |
|
857 }; |
|
858 |
|
859 TAsynchronousNotifierUpdater::TAsynchronousNotifierUpdater(TInt aReplySlot, const RMessage2& aMessage) |
|
860 :iReplySlot(aReplySlot), iMessage(aMessage) |
|
861 { |
|
862 } |
|
863 |
|
864 void TAsynchronousNotifierUpdater::UpdateActiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer, TDes8* /*aResponse*/) |
|
865 { |
|
866 aNotifier.UpdateL(aBuffer, iReplySlot, iMessage); |
|
867 } |
|
868 |
|
869 // |
|
870 // class CEikSrvNotifierManager |
|
871 // |
|
872 |
|
873 void CEikSrvNotifierManager::DoNotifierStartL(MNotifierStarter& aNotifierStarter,TBool& aCleanupComplete,TUid aNotifierUid,TUid aChannelUid,const TDesC8& aBuffer,TDes8* aResponse, TInt aClientId) |
|
874 { |
|
875 TInt result = KErrNotFound; |
|
876 RArray<TInt> notifierPositions; |
|
877 CleanupClosePushL(notifierPositions); |
|
878 |
|
879 LookForNotifierInObservedListL(aNotifierUid, aChannelUid, notifierPositions); |
|
880 |
|
881 for (TInt ii = 0; ii < notifierPositions.Count(); ii++) |
|
882 { |
|
883 MEikSrvNotifierBase2* notif = ((*iObservedList)[notifierPositions[ii]])->iNotifier; |
|
884 const MEikSrvNotifierBase2::TNotifierInfo info = notif->Info(); |
|
885 if(!NotifierHandlesScreenMode(notif)) |
|
886 User::Leave(KErrNotSupported); |
|
887 |
|
888 if (iActivityMonitor->IsNotifierActive(aNotifierUid, info.iChannel)) |
|
889 result = aNotifierStarter.StartAlreadyActiveNotifierL(*notif, aBuffer); |
|
890 else if (info.iPriority > iChannelMonitor->ActivityLevel(info.iChannel)) |
|
891 { |
|
892 TUid notifier; |
|
893 MEikSrvNotifierBase2::TNotifierPriority priority; |
|
894 const TBool channelWasActive = iActivityMonitor->IsChannelActive(info.iChannel, notifier, priority); |
|
895 iActivityMonitor->AddL(info, aClientId); |
|
896 |
|
897 SActivityCleanup cleanup; |
|
898 cleanup.iMonitor = iActivityMonitor; |
|
899 cleanup.iNotifier = aNotifierUid; |
|
900 cleanup.iClientId = aClientId; |
|
901 CleanupStack::PushL(TCleanupItem(CleanupActivityMonitor,&cleanup)); |
|
902 |
|
903 aCleanupComplete = EFalse; |
|
904 aNotifierStarter.StartInactiveNotifierL(*notif,aBuffer,aResponse); |
|
905 CleanupStack::Pop(&cleanup); |
|
906 |
|
907 if (channelWasActive) |
|
908 UpdateHighestPriorityNotifiersOnThisChannelOfTheirPausingOrResuming(info.iChannel, notifier, KEikNotifierPaused); |
|
909 |
|
910 iChannelMonitor->UpdateChannel(info.iChannel, info.iPriority); |
|
911 if (result != KQueued) |
|
912 result = KErrNone; |
|
913 } |
|
914 else |
|
915 { |
|
916 if (iQueue->IsAlreadyQueued(info.iUid, info.iChannel)) |
|
917 result = KErrAlreadyExists; |
|
918 else |
|
919 { |
|
920 CEikNotifierQueue::CQueueItem* const queueCopy = aNotifierStarter.NewQueueItemLC(info,aClientId,aBuffer); |
|
921 iQueue->QueueItemL(queueCopy); |
|
922 CleanupStack::Pop(queueCopy); |
|
923 result = KQueued; |
|
924 } |
|
925 } |
|
926 } |
|
927 |
|
928 User::LeaveIfError(result); |
|
929 CleanupStack::PopAndDestroy(¬ifierPositions); |
|
930 } |
|
931 |
|
932 class TSynchronousNotifierStarter : public MNotifierStarter |
|
933 { |
|
934 public: |
|
935 inline TSynchronousNotifierStarter() {} |
|
936 private: // from MNotifierStarter |
|
937 TInt StartAlreadyActiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer); |
|
938 void StartInactiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer, TDes8* aResponse); |
|
939 CEikNotifierQueue::CQueueItem* NewQueueItemLC(const MEikSrvNotifierBase2::TNotifierInfo& aInfo, TInt aClientId, const TDesC8& aBuffer); |
|
940 private: |
|
941 }; |
|
942 |
|
943 TInt TSynchronousNotifierStarter::StartAlreadyActiveNotifierL(MEikSrvNotifierBase2&,const TDesC8&) |
|
944 { |
|
945 return KErrAlreadyExists; |
|
946 } |
|
947 |
|
948 void TSynchronousNotifierStarter::StartInactiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer, TDes8* aResponse) |
|
949 { |
|
950 if(aResponse) |
|
951 aResponse->Copy(aNotifier.StartL(aBuffer)); |
|
952 else |
|
953 aNotifier.StartL(aBuffer); |
|
954 } |
|
955 |
|
956 CEikNotifierQueue::CQueueItem* TSynchronousNotifierStarter::NewQueueItemLC(const MEikSrvNotifierBase2::TNotifierInfo& aInfo, |
|
957 TInt aClientId, const TDesC8& aBuffer) |
|
958 { |
|
959 return CEikNotifierQueue::CQueueItem::NewLC(aInfo, aClientId, aBuffer, RMessage2(), -1); |
|
960 } |
|
961 |
|
962 void CEikSrvNotifierManager::NotifierStartL(TUid aNotifierUid, const TDesC8& aBuffer, TDes8* aResponse, TInt aClientId) |
|
963 { |
|
964 TBool notUsed = ETrue; |
|
965 TSynchronousNotifierStarter notifierStarter; |
|
966 DoNotifierStartL(notifierStarter, notUsed, aNotifierUid, KNonExistentUid, aBuffer, aResponse, aClientId); |
|
967 } |
|
968 |
|
969 TInt CEikSrvNotifierManager::NotifierUpdateL(TUid aNotifierUid, const TDesC8& aBuffer, TDes8* aResponse, TInt aClientId) |
|
970 { |
|
971 TSynchronousNotifierUpdater notifierUpdater; |
|
972 return DoNotifierUpdateL(notifierUpdater, aNotifierUid, aBuffer, aResponse, aClientId); |
|
973 } |
|
974 |
|
975 TBool CEikSrvNotifierManager::NotifierHandlesScreenMode(MEikSrvNotifierBase2* aNotifier) |
|
976 { |
|
977 const TInt screenMode = CEikonEnv::Static()->ScreenDevice()->CurrentScreenMode(); |
|
978 if(screenMode != 0) |
|
979 { |
|
980 const TInt notifierCapabilities = aNotifier->NotifierCapabilites(); |
|
981 if(notifierCapabilities == ENoSpecialCapabilities) |
|
982 return EFalse; |
|
983 } |
|
984 |
|
985 return ETrue; |
|
986 } |
|
987 |
|
988 void CEikSrvNotifierManager::LookForNotifierInObservedListL(TUid aNotifierUid, TUid aChannelUid, RArray<TInt>& aNotifierPositions) |
|
989 { |
|
990 const TInt count = iObservedList->Count(); |
|
991 for (TInt ii = 0; ii < count; ii++) |
|
992 { |
|
993 MEikSrvNotifierBase2* notif = ((*iObservedList)[ii])->iNotifier; |
|
994 const MEikSrvNotifierBase2::TNotifierInfo info = notif->Info(); |
|
995 if (info.iUid == aNotifierUid && (aChannelUid == KNonExistentUid || info.iChannel == aChannelUid)) |
|
996 User::LeaveIfError(aNotifierPositions.Append(ii)); |
|
997 } |
|
998 } |
|
999 |
|
1000 void CEikSrvNotifierManager::NotifierStartAndGetResponseL(TUid aNotifierUid, const TDesC8& aBuffer, TInt aReplySlot, |
|
1001 const RMessage2& aMessage, TInt aClientId, TBool& aCleanupComplete) |
|
1002 { |
|
1003 NotifierStartAndGetResponseL(aNotifierUid, KNonExistentUid, aBuffer, aReplySlot, aMessage, aClientId, aCleanupComplete); |
|
1004 } |
|
1005 |
|
1006 // |
|
1007 // class TAsynchronousNotifierStarter |
|
1008 // |
|
1009 |
|
1010 NONSHARABLE_CLASS(TAsynchronousNotifierStarter) : public MNotifierStarter |
|
1011 { |
|
1012 public: |
|
1013 TAsynchronousNotifierStarter(TInt aReplySlot,const RMessage2& aMessage); |
|
1014 private: // from MNotifierStarter |
|
1015 TInt StartAlreadyActiveNotifierL(MEikSrvNotifierBase2& aNotifier,const TDesC8& aBuffer); |
|
1016 void StartInactiveNotifierL(MEikSrvNotifierBase2& aNotifier,const TDesC8& aBuffer,TDes8* aResponse); |
|
1017 CEikNotifierQueue::CQueueItem* NewQueueItemLC(const MEikSrvNotifierBase2::TNotifierInfo& aInfo,TInt aClientId,const TDesC8& aBuffer); |
|
1018 private: |
|
1019 TInt iReplySlot; |
|
1020 const RMessage2& iMessage; |
|
1021 }; |
|
1022 |
|
1023 TAsynchronousNotifierStarter::TAsynchronousNotifierStarter(TInt aReplySlot, const RMessage2& aMessage) |
|
1024 :iReplySlot(aReplySlot), iMessage(aMessage) |
|
1025 { |
|
1026 } |
|
1027 |
|
1028 TInt TAsynchronousNotifierStarter::StartAlreadyActiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer) |
|
1029 { |
|
1030 aNotifier.StartL(aBuffer, iReplySlot, iMessage); // asynch notifier can decide whether to support multiple clients |
|
1031 return KErrNone; |
|
1032 } |
|
1033 |
|
1034 void TAsynchronousNotifierStarter::StartInactiveNotifierL(MEikSrvNotifierBase2& aNotifier, const TDesC8& aBuffer, TDes8* /*aResponse*/) |
|
1035 { |
|
1036 aNotifier.StartL(aBuffer, iReplySlot, iMessage); |
|
1037 } |
|
1038 |
|
1039 CEikNotifierQueue::CQueueItem* TAsynchronousNotifierStarter::NewQueueItemLC(const MEikSrvNotifierBase2::TNotifierInfo& aInfo, |
|
1040 TInt aClientId, const TDesC8& aBuffer) |
|
1041 { |
|
1042 __ASSERT_DEBUG(!iMessage.IsNull(), User::Invariant()); |
|
1043 return CEikNotifierQueue::CQueueItem::NewLC(aInfo, aClientId, aBuffer, iMessage, iReplySlot); |
|
1044 } |
|
1045 |
|
1046 // |
|
1047 // class CEikSrvNotifierManager |
|
1048 // |
|
1049 |
|
1050 void CEikSrvNotifierManager::NotifierStartAndGetResponseL(TUid aNotifierUid, TUid aChannelUid, const TDesC8& aBuffer, TInt aReplySlot, |
|
1051 const RMessage2& aMessage, TInt aClientId, TBool& aCleanupComplete) |
|
1052 { |
|
1053 TAsynchronousNotifierStarter notifierStarter(aReplySlot, aMessage); |
|
1054 TBuf8<1> notUsed; |
|
1055 DoNotifierStartL(notifierStarter, aCleanupComplete, aNotifierUid, aChannelUid, aBuffer, ¬Used, aClientId); |
|
1056 } |
|
1057 |
|
1058 void CEikSrvNotifierManager::NotifierUpdateAndGetResponseL(TUid aNotifierUid, const TDesC8& aBuffer, TInt aReplySlot, |
|
1059 const RMessage2& aMessage, TInt aClientId) |
|
1060 { |
|
1061 TAsynchronousNotifierUpdater notifierUpdater(aReplySlot, aMessage); |
|
1062 TBuf8<1> notUsed; |
|
1063 DoNotifierUpdateL(notifierUpdater, aNotifierUid, aBuffer, ¬Used, aClientId); |
|
1064 } |
|
1065 |
|
1066 TInt CEikSrvNotifierManager::DoNotifierUpdateL(MNotifierUpdater& aNotifierUpdater, TUid aNotifierUid, const TDesC8& aBuffer, TDes8* aResponse, TInt aClientId) |
|
1067 { |
|
1068 TInt result = KErrNotFound; |
|
1069 TInt foundNotifs = 0; |
|
1070 const TInt count = iObservedList->Count(); |
|
1071 for (TInt ii = 0; ii < count; ii++) |
|
1072 { |
|
1073 MEikSrvNotifierBase2* notif=((*iObservedList)[ii])->iNotifier; |
|
1074 const MEikSrvNotifierBase2::TNotifierInfo info=notif->Info(); |
|
1075 if(info.iUid == aNotifierUid) |
|
1076 { |
|
1077 if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel)) |
|
1078 { |
|
1079 if (!iActivityMonitor->IsClientPresent(aNotifierUid,info.iChannel,aClientId)) |
|
1080 iActivityMonitor->AddL(info,aClientId); |
|
1081 |
|
1082 aNotifierUpdater.UpdateActiveNotifierL(*notif,aBuffer,aResponse); |
|
1083 foundNotifs++; |
|
1084 } |
|
1085 else |
|
1086 { |
|
1087 ; // not all channels have been started yet so update the queue |
|
1088 } |
|
1089 |
|
1090 result = KErrNone; |
|
1091 } |
|
1092 } |
|
1093 |
|
1094 if (!foundNotifs && !result) // No active notifs found |
|
1095 result = KErrNotReady; |
|
1096 |
|
1097 User::LeaveIfError(result); //leave because return code is not handled |
|
1098 return result; |
|
1099 } |
|
1100 |
|
1101 TInt CEikSrvNotifierManager::NotifierCancel(TUid aNotifierUid) |
|
1102 { |
|
1103 /* |
|
1104 1. Old notif always gets cancelled. |
|
1105 2. fetch next item from each channel. If non-NULL, start these items now |
|
1106 3. if item fails to start call NotifierCancel for that uid, cancelling all |
|
1107 channels regardless of whether they were already running |
|
1108 */ |
|
1109 TInt result = KErrNotFound; |
|
1110 const TInt count = iObservedList->Count(); |
|
1111 for (TInt ii = 0; ii < count; ii++) |
|
1112 { |
|
1113 MEikSrvNotifierBase2* notif = ((*iObservedList)[ii])->iNotifier; |
|
1114 const MEikSrvNotifierBase2::TNotifierInfo info = notif->Info(); |
|
1115 if (info.iUid == aNotifierUid) |
|
1116 { |
|
1117 // This will cause the client request to be set to complete by the notifier's Cancel |
|
1118 // (if it has been implemented properly) unless the notifier has never been started |
|
1119 // (the notifier's StartL function has never been called). |
|
1120 // If the notifier has never been started it is in the queue and |
|
1121 // CEikNotifierQueue::RemoveNotifier will complete the client request instead of the notifier. |
|
1122 notif->Cancel(); |
|
1123 ((*iObservedList)[ii])->iIsReadyForRemoval = ETrue; // record that this notifier will be removed if it's from a transient type dll. |
|
1124 if(iNotifierRemover) |
|
1125 { |
|
1126 iNotifierRemover->Cancel(); |
|
1127 iNotifierRemover->Start(this, iObservedList); |
|
1128 } |
|
1129 |
|
1130 iActivityMonitor->RemoveNotifier(aNotifierUid,info.iChannel); |
|
1131 iQueue->RemoveNotifier(aNotifierUid); |
|
1132 |
|
1133 //check channel activity and get highest priority on channnel |
|
1134 TUid notifier; |
|
1135 MEikSrvNotifierBase2::TNotifierPriority priority; |
|
1136 if (iActivityMonitor->IsChannelActive(info.iChannel, notifier, priority)) |
|
1137 { |
|
1138 // Check if priority of a queued item on the same channel is greater |
|
1139 const MEikSrvNotifierBase2::TNotifierPriority queuePriority = |
|
1140 (MEikSrvNotifierBase2::TNotifierPriority)iQueue->GetHighestQueuePriority(info.iChannel); |
|
1141 |
|
1142 if (queuePriority > priority) |
|
1143 { |
|
1144 iChannelMonitor->UpdateChannel(info.iChannel, MEikSrvNotifierBase2::ENotifierPriorityLowest); |
|
1145 StartNextFromQueue(info.iChannel); |
|
1146 } |
|
1147 else |
|
1148 { |
|
1149 UpdateHighestPriorityNotifiersOnThisChannelOfTheirPausingOrResuming(info.iChannel, notifier, KEikNotifierResumed); |
|
1150 iChannelMonitor->UpdateChannel(info.iChannel, priority); |
|
1151 } |
|
1152 } |
|
1153 else |
|
1154 { |
|
1155 iChannelMonitor->UpdateChannel(info.iChannel, MEikSrvNotifierBase2::ENotifierPriorityLowest); |
|
1156 StartNextFromQueue(info.iChannel); |
|
1157 } |
|
1158 |
|
1159 result = KErrNone; |
|
1160 } |
|
1161 } |
|
1162 |
|
1163 return result; |
|
1164 } |
|
1165 |
|
1166 struct SCleanupMessage |
|
1167 { |
|
1168 TBool* iDoCleanup; |
|
1169 const RMessage2* iMessage; |
|
1170 }; |
|
1171 |
|
1172 LOCAL_C void CleanupStartAndGetResponse(TAny* aPtr) |
|
1173 { |
|
1174 SCleanupMessage& cleanup = *reinterpret_cast<SCleanupMessage*>(aPtr); |
|
1175 if (cleanup.iDoCleanup) |
|
1176 cleanup.iMessage->Complete(KErrNoMemory); |
|
1177 } |
|
1178 |
|
1179 void CEikSrvNotifierManager::StartNextFromQueue(TUid aChannel) |
|
1180 { |
|
1181 CEikNotifierQueue::CQueueItem* next = iQueue->FetchItem(aChannel); // Transfer ownership of CQueueItem from the queue |
|
1182 if (next) |
|
1183 { |
|
1184 const TUid notif = next->iInfo.iUid; |
|
1185 TRAPD(err, DoStartQueuedItemLD(next)); // Safely consumes CQueueItem "next" |
|
1186 if (err) |
|
1187 NotifierCancel(notif); |
|
1188 } |
|
1189 } |
|
1190 |
|
1191 void CEikSrvNotifierManager::DoStartQueuedItemLD(CEikNotifierQueue::CQueueItem* aItem) |
|
1192 { |
|
1193 CleanupStack::PushL(aItem); |
|
1194 |
|
1195 if (aItem->iMessage.IsNull()) |
|
1196 NotifierStartL(aItem->iInfo.iUid, aItem->Buffer(), NULL, aItem->iClientId); |
|
1197 else |
|
1198 { |
|
1199 TBool doCleanup = ETrue; |
|
1200 SCleanupMessage cleanup; |
|
1201 cleanup.iDoCleanup = &doCleanup; |
|
1202 cleanup.iMessage = &aItem->iMessage; |
|
1203 CleanupStack::PushL(TCleanupItem(CleanupStartAndGetResponse, &cleanup)); |
|
1204 NotifierStartAndGetResponseL(aItem->iInfo.iUid, aItem->iInfo.iChannel, aItem->Buffer(), |
|
1205 aItem->iReplySlot, aItem->iMessage, aItem->iClientId, doCleanup); |
|
1206 CleanupStack::Pop(&cleanup); |
|
1207 } |
|
1208 |
|
1209 CleanupStack::PopAndDestroy(aItem); |
|
1210 } |
|
1211 |
|
1212 void CEikSrvNotifierManager::HandleClientExit(TInt aClientId) |
|
1213 { |
|
1214 TUid notifier = KNullUid; |
|
1215 while (iActivityMonitor->NotifierForClient(notifier, aClientId)) |
|
1216 { |
|
1217 const TInt count = iObservedList->Count(); |
|
1218 for (TInt ii = 0; ii < count; ii++) |
|
1219 { |
|
1220 MEikSrvNotifierBase2* notif = ((*iObservedList)[ii])->iNotifier; |
|
1221 if (notif->Info().iUid == notifier) |
|
1222 NotifierCancel(notifier); |
|
1223 } |
|
1224 |
|
1225 iActivityMonitor->Remove(notifier,aClientId); |
|
1226 } |
|
1227 |
|
1228 iActivityMonitor->RemoveClient(aClientId); |
|
1229 iQueue->RemoveClient(aClientId); |
|
1230 } |
|
1231 |
|
1232 void CEikSrvNotifierManager::StartNotifierL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse) |
|
1233 { |
|
1234 NotifierStartL(aNotifierUid,aBuffer,&aResponse,KNullClientId); |
|
1235 } |
|
1236 |
|
1237 void CEikSrvNotifierManager::CancelNotifier(TUid aNotifierUid) |
|
1238 { |
|
1239 NotifierCancel(aNotifierUid); |
|
1240 } |
|
1241 |
|
1242 void CEikSrvNotifierManager::UpdateNotifierL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse) |
|
1243 { |
|
1244 NotifierUpdateL(aNotifierUid,aBuffer,&aResponse,KNullClientId); |
|
1245 } |
|
1246 |
|
1247 void CEikSrvNotifierManager::HandleScreenDeviceChangedL() |
|
1248 { |
|
1249 //notify any active notifiers of a screen changed event, if they don't support a screen mode change. |
|
1250 //they are cancelled and the list of notifiers is iterated through again to check for any |
|
1251 //queued notifiers that may have been made active. |
|
1252 const TInt count = iObservedList->Count(); |
|
1253 MEikSrvNotifierBase2::TNotifierInfo notifierInfo; |
|
1254 for (TInt ii = 0; ii < count; ii++) |
|
1255 { |
|
1256 MEikSrvNotifierBase2* notifier = (*iObservedList)[ii]->iNotifier; |
|
1257 notifierInfo = notifier->Info(); |
|
1258 if(iActivityMonitor->IsNotifierActive(notifierInfo.iUid, notifierInfo.iChannel)) |
|
1259 { |
|
1260 const TInt notifierCapabilities = notifier->NotifierCapabilites(); |
|
1261 if(notifierCapabilities == ENoSpecialCapabilities) |
|
1262 { |
|
1263 //Notifier does not support flip events so cancel it. |
|
1264 NotifierCancel(notifierInfo.iUid); |
|
1265 } |
|
1266 else if(notifierCapabilities&EScreenDeviceChangeSupported) |
|
1267 { |
|
1268 notifier->HandleSystemEventL(KUidEventScreenModeChanged); |
|
1269 } |
|
1270 } |
|
1271 } |
|
1272 } |
|
1273 |
|
1274 // |
|
1275 // CChannelMonitor |
|
1276 // |
|
1277 |
|
1278 CChannelMonitor* CChannelMonitor::NewL() |
|
1279 { |
|
1280 CChannelMonitor* self = new(ELeave) CChannelMonitor; |
|
1281 return self; |
|
1282 } |
|
1283 |
|
1284 TInt CChannelMonitor::NumberOfChannels() const |
|
1285 { |
|
1286 return iMonitor.Count(); |
|
1287 } |
|
1288 |
|
1289 void CChannelMonitor::DeleteChannel(TInt aIndex) |
|
1290 { |
|
1291 __ASSERT_ALWAYS((aIndex >= 0) && (aIndex < iMonitor.Count()), Panic(EEikServPanicChannelIndexOutOfRange)); |
|
1292 iMonitor.Delete(aIndex); |
|
1293 } |
|
1294 |
|
1295 TBool CChannelMonitor::AlreadyHasChannel(TUid aChannel) const |
|
1296 { |
|
1297 const TInt count = iMonitor.Count(); |
|
1298 for (TInt ii = 0; ii < count; ii++) |
|
1299 { |
|
1300 if (iMonitor[ii].iChannel == aChannel) |
|
1301 return ETrue; |
|
1302 } |
|
1303 |
|
1304 return EFalse; |
|
1305 } |
|
1306 |
|
1307 TInt CChannelMonitor::ActivityLevel(TUid aChannel) const |
|
1308 { |
|
1309 const TInt count = iMonitor.Count(); |
|
1310 for (TInt ii = 0; ii < count; ii++) |
|
1311 { |
|
1312 const TChannelActivity activity = iMonitor[ii]; |
|
1313 if (activity.iChannel == aChannel) |
|
1314 return activity.iHighestPriorityRunning; |
|
1315 } |
|
1316 |
|
1317 return 0; |
|
1318 } |
|
1319 |
|
1320 void CChannelMonitor::UpdateChannel(TUid aChannel, TInt aLevel) |
|
1321 { |
|
1322 const TInt count = iMonitor.Count(); |
|
1323 for (TInt ii = 0; ii < count; ii++) |
|
1324 { |
|
1325 TChannelActivity& activity = iMonitor[ii]; |
|
1326 if (activity.iChannel == aChannel) |
|
1327 { |
|
1328 activity.iHighestPriorityRunning = aLevel; |
|
1329 break; |
|
1330 } |
|
1331 } |
|
1332 } |
|
1333 |
|
1334 CChannelMonitor::CChannelMonitor() |
|
1335 :iMonitor(3) |
|
1336 {} |
|
1337 |
|
1338 // |
|
1339 // class CNotifierActivity |
|
1340 // |
|
1341 |
|
1342 CActivityMonitor::CNotifierActivity* CActivityMonitor::CNotifierActivity::NewLC(const MEikSrvNotifierBase2::TNotifierInfo& aInfo,TInt aClientId) |
|
1343 { // static |
|
1344 CNotifierActivity* self=new(ELeave) CNotifierActivity(aInfo); |
|
1345 CleanupStack::PushL(self); |
|
1346 self->ConstructL(aClientId); |
|
1347 return self; |
|
1348 } |
|
1349 |
|
1350 CActivityMonitor::CNotifierActivity::~CNotifierActivity() |
|
1351 { |
|
1352 iClientArray.Reset(); |
|
1353 } |
|
1354 |
|
1355 TInt CActivityMonitor::CNotifierActivity::Find(TInt aClientId) const |
|
1356 { |
|
1357 TInt index=KErrNotFound; |
|
1358 const TInt count=iClientArray.Count(); |
|
1359 for (TInt ii=0;ii<count;ii++) |
|
1360 { |
|
1361 TInt clientId=iClientArray[ii]; |
|
1362 if (clientId==aClientId) |
|
1363 { |
|
1364 index=ii; |
|
1365 break; |
|
1366 } |
|
1367 } |
|
1368 |
|
1369 return index; |
|
1370 } |
|
1371 |
|
1372 CActivityMonitor::CNotifierActivity::CNotifierActivity(const MEikSrvNotifierBase2::TNotifierInfo& aInfo) |
|
1373 : iInfo(aInfo), iClientArray(1) |
|
1374 {} |
|
1375 |
|
1376 void CActivityMonitor::CNotifierActivity::ConstructL(TInt aClientId) |
|
1377 { |
|
1378 iClientArray.AppendL(aClientId); |
|
1379 } |
|
1380 |
|
1381 // |
|
1382 // class CActivityMonitor |
|
1383 // |
|
1384 |
|
1385 CActivityMonitor* CActivityMonitor::NewL() |
|
1386 { // static |
|
1387 CActivityMonitor* self=new(ELeave) CActivityMonitor(); |
|
1388 return self; |
|
1389 } |
|
1390 |
|
1391 CActivityMonitor::~CActivityMonitor() |
|
1392 { |
|
1393 iMonitor.ResetAndDestroy(); |
|
1394 } |
|
1395 |
|
1396 void CActivityMonitor::AddL(const MEikSrvNotifierBase2::TNotifierInfo& aInfo,TInt aClientId) |
|
1397 { |
|
1398 const TInt index = Find(aInfo.iUid,aInfo.iChannel); |
|
1399 if (index == KErrNotFound) |
|
1400 { |
|
1401 CNotifierActivity* activity = CNotifierActivity::NewLC(aInfo,aClientId); |
|
1402 iMonitor.AppendL(activity); |
|
1403 CleanupStack::Pop(); // activity |
|
1404 } |
|
1405 else |
|
1406 iMonitor[index]->iClientArray.AppendL(aClientId); |
|
1407 } |
|
1408 |
|
1409 void CActivityMonitor::Remove(TUid aNotifierUid,TInt aClientId) |
|
1410 { |
|
1411 const TInt index = Find(aNotifierUid); |
|
1412 if (index != KErrNotFound) |
|
1413 { |
|
1414 CNotifierActivity* activity=iMonitor[index]; |
|
1415 const TInt clientIndex=activity->Find(aClientId); |
|
1416 if (clientIndex != KErrNotFound) |
|
1417 { |
|
1418 if (activity->iClientArray.Count()==1) |
|
1419 { |
|
1420 delete activity; |
|
1421 iMonitor.Delete(index); |
|
1422 } |
|
1423 else |
|
1424 activity->iClientArray.Delete(index); |
|
1425 } |
|
1426 } |
|
1427 } |
|
1428 |
|
1429 void CActivityMonitor::RemoveNotifier(TUid aNotifierUid,TUid aChannel) |
|
1430 { |
|
1431 const TInt index = Find(aNotifierUid,aChannel); |
|
1432 if (index != KErrNotFound) |
|
1433 { |
|
1434 delete iMonitor[index]; |
|
1435 iMonitor.Delete(index); |
|
1436 } |
|
1437 } |
|
1438 |
|
1439 void CActivityMonitor::RemoveClient(TInt aClientId) |
|
1440 { |
|
1441 TInt ii = 0; |
|
1442 while (ii < iMonitor.Count()) |
|
1443 { |
|
1444 CNotifierActivity* ptr = iMonitor[ii]; |
|
1445 const TInt index = ptr->Find(aClientId); |
|
1446 if (index != KErrNotFound) |
|
1447 ptr->iClientArray.Delete(index); |
|
1448 |
|
1449 if (ptr->iClientArray.Count()==0) |
|
1450 { |
|
1451 iMonitor.Delete(ii); |
|
1452 delete ptr; |
|
1453 } |
|
1454 else |
|
1455 ++ii; |
|
1456 } |
|
1457 } |
|
1458 |
|
1459 TBool CActivityMonitor::IsNotifierActive(TUid aNotifierUid,TUid aChannel) const |
|
1460 { |
|
1461 const TInt index = Find(aNotifierUid,aChannel); |
|
1462 return (index != KErrNotFound); |
|
1463 } |
|
1464 |
|
1465 TBool CActivityMonitor::IsClientPresent(TUid aNotifierUid,TUid aChannel,TInt aClientId) const |
|
1466 { |
|
1467 TBool found = EFalse; |
|
1468 const TInt index = Find(aNotifierUid,aChannel); |
|
1469 if (index != KErrNotFound) |
|
1470 found = (iMonitor[index]->Find(aClientId) != KErrNotFound); |
|
1471 |
|
1472 return found; |
|
1473 } |
|
1474 |
|
1475 TBool CActivityMonitor::IsChannelActive(TUid aChannel,TUid& aNotifier,MEikSrvNotifierBase2::TNotifierPriority& aHighestPriority) const |
|
1476 { |
|
1477 TBool isChannelActive = EFalse; |
|
1478 const TInt count = iMonitor.Count(); |
|
1479 for (TInt ii = 0; ii < count; ii++) |
|
1480 { |
|
1481 const MEikSrvNotifierBase2::TNotifierInfo info=iMonitor[ii]->iInfo; |
|
1482 if (info.iChannel == aChannel) |
|
1483 { |
|
1484 if ((!isChannelActive) || (aHighestPriority < (MEikSrvNotifierBase2::TNotifierPriority)info.iPriority)) |
|
1485 { |
|
1486 isChannelActive = ETrue; |
|
1487 aNotifier = info.iUid; |
|
1488 aHighestPriority = (MEikSrvNotifierBase2::TNotifierPriority)info.iPriority; |
|
1489 } |
|
1490 } |
|
1491 } |
|
1492 |
|
1493 return isChannelActive; |
|
1494 } |
|
1495 |
|
1496 TBool CActivityMonitor::NotifierForClient(TUid& aNotifierUid, TInt aClientId) const |
|
1497 { |
|
1498 TBool isOnlyClient = EFalse; |
|
1499 aNotifierUid = KNullUid; |
|
1500 const TInt count = iMonitor.Count(); |
|
1501 for (TInt ii = 0; ii < count; ii++) |
|
1502 { |
|
1503 CNotifierActivity* ptr = iMonitor[ii]; |
|
1504 if (ptr->Find(aClientId) != KErrNotFound) |
|
1505 { |
|
1506 aNotifierUid = ptr->iInfo.iUid; |
|
1507 isOnlyClient = ptr->iClientArray.Count()==1; |
|
1508 break; |
|
1509 } |
|
1510 } |
|
1511 |
|
1512 return isOnlyClient; |
|
1513 } |
|
1514 |
|
1515 CActivityMonitor::CActivityMonitor() |
|
1516 : iMonitor(1) |
|
1517 {} |
|
1518 |
|
1519 TInt CActivityMonitor::Find(TUid aNotifierUid) const |
|
1520 { |
|
1521 const TInt count = iMonitor.Count(); |
|
1522 for (TInt ii = 0; ii < count; ii++) |
|
1523 { |
|
1524 if (iMonitor[ii]->iInfo.iUid == aNotifierUid) |
|
1525 return ii; |
|
1526 } |
|
1527 |
|
1528 return KErrNotFound; |
|
1529 } |
|
1530 |
|
1531 TInt CActivityMonitor::Find(TUid aNotifierUid, TUid aChannel) const |
|
1532 { |
|
1533 const TInt count = iMonitor.Count(); |
|
1534 for (TInt ii = 0; ii < count; ii++) |
|
1535 { |
|
1536 const CNotifierActivity* ptr = iMonitor[ii]; |
|
1537 if (ptr->iInfo.iUid == aNotifierUid && ptr->iInfo.iChannel == aChannel) |
|
1538 return ii; |
|
1539 } |
|
1540 |
|
1541 return KErrNotFound; |
|
1542 } |
|
1543 |
|
1544 // |
|
1545 // class CQueueItem |
|
1546 // |
|
1547 |
|
1548 CEikNotifierQueue::CQueueItem* CEikNotifierQueue::CQueueItem::NewLC(const MEikSrvNotifierBase2::TNotifierInfo& aInfo, TInt aClientId, |
|
1549 const TDesC8& aBuffer, const RMessage2& aMessage,TInt aReplySlot) |
|
1550 { |
|
1551 CQueueItem* self=new(ELeave) CQueueItem(aInfo,aClientId,aMessage,aReplySlot); |
|
1552 CleanupStack::PushL(self); |
|
1553 self->ConstructL(aBuffer); |
|
1554 return self; |
|
1555 } |
|
1556 |
|
1557 CEikNotifierQueue::CQueueItem::~CQueueItem() |
|
1558 { |
|
1559 delete iBuffer; |
|
1560 } |
|
1561 |
|
1562 CEikNotifierQueue::CQueueItem::CQueueItem(const MEikSrvNotifierBase2::TNotifierInfo& aInfo, TInt aClientId, |
|
1563 const RMessage2& aMessage, TInt aReplySlot) |
|
1564 :iInfo(aInfo), |
|
1565 iClientId(aClientId), |
|
1566 iMessage(aMessage), |
|
1567 iReplySlot(aReplySlot), |
|
1568 iBuffer(NULL) |
|
1569 { |
|
1570 } |
|
1571 |
|
1572 void CEikNotifierQueue::CQueueItem::ConstructL(const TDesC8& aBuffer) |
|
1573 { |
|
1574 iBuffer=aBuffer.AllocL(); |
|
1575 } |
|
1576 |
|
1577 // |
|
1578 // class CEikNotifierQueue |
|
1579 // |
|
1580 |
|
1581 CEikNotifierQueue* CEikNotifierQueue::NewL() |
|
1582 { |
|
1583 CEikNotifierQueue* self = new (ELeave) CEikNotifierQueue; |
|
1584 return self; |
|
1585 } |
|
1586 |
|
1587 /** |
|
1588 Get the queue item from the notifier queue. CQueueItem ownership is transfered from |
|
1589 the queue to the caller. |
|
1590 */ |
|
1591 CEikNotifierQueue::CQueueItem* CEikNotifierQueue::FetchItem(TUid aChannel) |
|
1592 { |
|
1593 CEikNotifierQueue::CQueueItem* result = NULL; |
|
1594 TInt priority = MEikSrvNotifierBase2::ENotifierPriorityLowest-1; |
|
1595 TInt index = KErrNotFound; |
|
1596 |
|
1597 const TInt count = iQueue.Count(); |
|
1598 for (TInt ii = 0; ii < count; ii++) |
|
1599 { |
|
1600 CEikNotifierQueue::CQueueItem* item = iQueue[ii]; |
|
1601 if (item->iInfo.iChannel == aChannel && item->iInfo.iPriority > priority) |
|
1602 { |
|
1603 index = ii; |
|
1604 priority = item->iInfo.iPriority; |
|
1605 result = item; |
|
1606 } |
|
1607 } |
|
1608 |
|
1609 if (index != KErrNotFound) |
|
1610 iQueue.Delete(index); |
|
1611 |
|
1612 return result; |
|
1613 } |
|
1614 |
|
1615 TBool CEikNotifierQueue::IsAlreadyQueued(TUid aNotifier,TUid aChannel) const |
|
1616 { |
|
1617 const TInt count = iQueue.Count(); |
|
1618 for (TInt ii = 0; ii < count; ii++) |
|
1619 { |
|
1620 CEikNotifierQueue::CQueueItem* item = iQueue[ii]; |
|
1621 if (item->iInfo.iUid == aNotifier && item->iInfo.iChannel == aChannel) |
|
1622 return ETrue; |
|
1623 } |
|
1624 |
|
1625 return EFalse; |
|
1626 } |
|
1627 |
|
1628 void CEikNotifierQueue::RemoveClient(TInt aClientId) |
|
1629 { |
|
1630 const TInt count = iQueue.Count(); |
|
1631 for (TInt ii = count-1; ii >= 0; ii--) |
|
1632 { |
|
1633 CEikNotifierQueue::CQueueItem* item = iQueue[ii]; |
|
1634 TInt clientId = item->iClientId; |
|
1635 if (clientId == aClientId) |
|
1636 { |
|
1637 delete item; |
|
1638 iQueue.Delete(ii); |
|
1639 } |
|
1640 } |
|
1641 } |
|
1642 |
|
1643 |
|
1644 TInt CEikNotifierQueue::GetHighestQueuePriority(TUid aChannel) |
|
1645 { |
|
1646 TInt priority = MEikSrvNotifierBase2::ENotifierPriorityLowest-1; |
|
1647 |
|
1648 const TInt count = iQueue.Count(); |
|
1649 for (TInt ii = 0; ii < count; ii++) |
|
1650 { |
|
1651 CEikNotifierQueue::CQueueItem* item=iQueue[ii]; |
|
1652 if (item->iInfo.iChannel == aChannel && item->iInfo.iPriority>priority) |
|
1653 priority = item->iInfo.iPriority; |
|
1654 } |
|
1655 |
|
1656 return priority; |
|
1657 } |
|
1658 |
|
1659 const CEikNotifierQueue::CQueueItem& CEikNotifierQueue::At(TInt aIndex) const |
|
1660 { |
|
1661 __ASSERT_DEBUG((aIndex>=0) && (aIndex < iQueue.Count()),Panic(EEikServPanicQueueIndexOutOfRange)); |
|
1662 return *(iQueue.At(aIndex)); |
|
1663 } |
|
1664 |
|
1665 void CEikNotifierQueue::RemoveNotifier(TUid aNotifierUid) |
|
1666 { |
|
1667 const TInt count=iQueue.Count(); |
|
1668 for(TInt ii = count -1; ii >= 0; --ii) |
|
1669 { |
|
1670 if(iQueue[ii]->iInfo.iUid==aNotifierUid) |
|
1671 { |
|
1672 if (!iQueue[ii]->iMessage.IsNull()) |
|
1673 { |
|
1674 // The notifiers in the queue have never been started and so |
|
1675 // they have no pointer to the RMessage2 (it is passed in as argument |
|
1676 // to the StartL function but it has never been called). The framework |
|
1677 // has to complete the request. |
|
1678 iQueue[ii]->iMessage.Complete(KErrCancel); |
|
1679 } |
|
1680 iQueue.Delete(ii); |
|
1681 } |
|
1682 } |
|
1683 } |
|
1684 |
|
1685 |
|
1686 |
|
1687 // |
|
1688 |
|
1689 LOCAL_C void ReleaseOnCleanup(TAny* aObject) |
|
1690 // |
|
1691 // Used for cleanup of objects on stack if a function leaves. |
|
1692 // |
|
1693 { |
|
1694 REINTERPRET_CAST(RImplInfoPtrArray*,(aObject))->ResetAndDestroy(); |
|
1695 REINTERPRET_CAST(RImplInfoPtrArray*,(aObject))->Close(); |
|
1696 } |
|
1697 |
|
1698 TInt FindInOrderFunction(const CPluginTrack& aPluginTrack1,const CPluginTrack& aPluginTrack2) |
|
1699 // |
|
1700 // This function is used to find a plugin with specific implementation uid in the list. |
|
1701 // It is internally called by RPointerArray function FindInOrder. |
|
1702 // |
|
1703 { |
|
1704 return (aPluginTrack1.iPluginImplementationUid.iUid - aPluginTrack2.iPluginImplementationUid.iUid); |
|
1705 } |
|
1706 |
|
1707 void CEikSrvNotifierManager::RegisterL() |
|
1708 // |
|
1709 // Register the plugins at bootup |
|
1710 // |
|
1711 { |
|
1712 //This is the list where we have the information of all the ECOM plugin i,e |
|
1713 // 1. The plugin implementatiuon UID |
|
1714 // 2. The Number of instances of recognizer in an single implementation |
|
1715 // 3. The Plugin Destructor Key |
|
1716 iPluginUidList.Reset(); |
|
1717 |
|
1718 // Array to return all implementations in an interface |
|
1719 RImplInfoPtrArray plugInArray; |
|
1720 |
|
1721 // ListImplementationsL leaves if it cannot find anything so trap the error and ignore it. |
|
1722 REComSession::ListImplementationsL(KUidPluginInterfaceNotifiers, plugInArray); |
|
1723 |
|
1724 // Push the plugin array on the stack |
|
1725 CleanupStack::PushL(TCleanupItem(ReleaseOnCleanup,&plugInArray)); |
|
1726 |
|
1727 // it the plugin count is zero dont load any thing |
|
1728 for(TInt i=plugInArray.Count()-1; i>=0; --i) |
|
1729 { |
|
1730 TUid chosenUid = {0}; |
|
1731 chosenUid = plugInArray[i]->ImplementationUid(); |
|
1732 TRAPD(err, DoAddPlugInL(chosenUid)); |
|
1733 if(err) |
|
1734 { |
|
1735 DEBUGPRINT3(_L("CEikSrvNotifierManager::RegisterL() DoAddPlugInL leaved with error:%d for plugin:0x%x"), err, chosenUid); |
|
1736 } |
|
1737 } |
|
1738 |
|
1739 CleanupStack::Pop(&plugInArray); |
|
1740 plugInArray.ResetAndDestroy(); |
|
1741 plugInArray.Close(); |
|
1742 |
|
1743 //Sort the Pluginlist array |
|
1744 TLinearOrder<CPluginTrack> linearOrder (&FindInOrderFunction); |
|
1745 iPluginUidList.Sort(linearOrder); |
|
1746 |
|
1747 //Start the discovery of newly added plugins so that we can detect a runtime installation |
|
1748 iDiscoverNewImplementation->Start(); |
|
1749 |
|
1750 } |
|
1751 |
|
1752 CArrayPtr<CEikSrvNotifierWrapper>* CEikSrvNotifierManager::LoadPlugInAndPopulateNotifierArrayL(TUid aUid) |
|
1753 // |
|
1754 // Loads the notifier plugins depending on the chosen implementation uid. |
|
1755 // |
|
1756 { |
|
1757 DEBUGPRINT2(_L("CEikSrvNotifierManager:: LoadPlugInAndPopulateNotifierArrayL: Loading Plugin: Uid 0x%X"), aUid ); |
|
1758 |
|
1759 TUid destructorKey; |
|
1760 // Tells that its a dll & simulating a Notifier for Type V2. |
|
1761 TUidType aUidType(KDynamicLibraryUid, KUidNotifierPlugInV2, aUid); |
|
1762 destructorKey.iUid = 0; |
|
1763 |
|
1764 //Create implementation for the choosen UID. |
|
1765 CArrayPtr<MEikSrvNotifierBase2>* array = reinterpret_cast<CArrayPtr<MEikSrvNotifierBase2>*>( |
|
1766 REComSession::CreateImplementationL(aUid, destructorKey)); |
|
1767 |
|
1768 // passes ownership of 'array'. Array is internally destroyed. |
|
1769 CArrayPtr<CEikSrvNotifierWrapper>* retArray = CreateNotifierArrayFromPlugInArrayL(array,aUidType); |
|
1770 |
|
1771 // Copys the destructor key to the destructorKey variable in CEikSrvNotifierWrapper class. |
|
1772 // Also construct the wrapper class which gets the notifier registration information in the member |
|
1773 // variables. |
|
1774 const TInt retArrayCount = retArray->Count(); |
|
1775 for (TInt i = 0; i < retArrayCount; i++) |
|
1776 { |
|
1777 CEikSrvNotifierWrapper* const notifier = retArray->At(i); |
|
1778 notifier->RegisterNotifierL(); |
|
1779 notifier->iDestructorKey = destructorKey; |
|
1780 } |
|
1781 |
|
1782 return retArray; |
|
1783 } |
|
1784 |
|
1785 |
|
1786 TBool CEikSrvNotifierManager::IsImplementationRemoved(TUid aImplementationUid, RImplInfoPtrArray& aPlugInArray) |
|
1787 // |
|
1788 // Finds if a particular implementation is present in the ecom registry returned data |
|
1789 // |
|
1790 { |
|
1791 for (TInt i=aPlugInArray.Count()-1; i>=0; --i) |
|
1792 { |
|
1793 if(aImplementationUid == aPlugInArray[i]->ImplementationUid()) |
|
1794 return EFalse; |
|
1795 } |
|
1796 |
|
1797 return ETrue; |
|
1798 } |
|
1799 |
|
1800 // |
|
1801 // Finds if a particular implementation is newly added in the ecom registry returned data |
|
1802 // |
|
1803 TBool CEikSrvNotifierManager::IsImplementationAdded(TUid aImplementationUid) |
|
1804 { |
|
1805 for (TInt i=iPluginUidList.Count()-1; i>=0; --i) |
|
1806 { |
|
1807 if(aImplementationUid==(iPluginUidList[i])->iPluginImplementationUid) |
|
1808 return EFalse; |
|
1809 } |
|
1810 |
|
1811 return ETrue; |
|
1812 } |
|
1813 |
|
1814 void CEikSrvNotifierManager::CheckForEcomPluginInstallUninstall() |
|
1815 // |
|
1816 // This function finds out the whether an ecom notifier has been installed or removed |
|
1817 // |
|
1818 { |
|
1819 // Array to return all implementations in an interface) |
|
1820 RImplInfoPtrArray plugInArray; |
|
1821 |
|
1822 // ListImplementationsL leaves if it cannot find anything so trap the error and ignore it. |
|
1823 TRAP_IGNORE(REComSession::ListImplementationsL(KUidPluginInterfaceNotifiers, plugInArray)); |
|
1824 CleanupStack::PushL(TCleanupItem(ReleaseOnCleanup, &plugInArray)); |
|
1825 |
|
1826 TBool doUpdate = EFalse; |
|
1827 |
|
1828 // If an implementation is not present in the iPluginUidList then its added. |
|
1829 for(TInt i = plugInArray.Count()-1; i>=0; --i) |
|
1830 { |
|
1831 TUid uid = plugInArray[i]->ImplementationUid(); |
|
1832 if(IsImplementationAdded(uid)) |
|
1833 { |
|
1834 // Add the implementation which is not present in the plugin array and also |
|
1835 // update the plugintrack with new implementation and its dll uid. |
|
1836 TRAPD(err,DoAddPlugInL(uid)); |
|
1837 if(err) |
|
1838 { |
|
1839 DEBUGPRINT3(_L("CEikSrvNotifierManager::CheckForEcomPluginInstallUninstall() DoAddPlugInL leaved with error:%d for plugin:0x%x"), err, uid); |
|
1840 } |
|
1841 |
|
1842 doUpdate = ETrue; |
|
1843 } |
|
1844 } |
|
1845 |
|
1846 // If a implementation is not present in present in the plugInArray then its removed. |
|
1847 for(TInt j = iPluginUidList.Count()-1; j >= 0; --j) |
|
1848 { |
|
1849 if(IsImplementationRemoved((iPluginUidList[j])->iPluginImplementationUid, plugInArray)) |
|
1850 UnloadEComPlugInImplementation(j); //Remove the implementation |
|
1851 } |
|
1852 |
|
1853 if(doUpdate) |
|
1854 {//Sort the Pluginlist array |
|
1855 TLinearOrder<CPluginTrack> linearOrder(&FindInOrderFunction); |
|
1856 iPluginUidList.Sort(linearOrder); |
|
1857 } |
|
1858 |
|
1859 CleanupStack::Pop(&plugInArray); |
|
1860 plugInArray.ResetAndDestroy(); |
|
1861 plugInArray.Close(); |
|
1862 } |
|
1863 |
|
1864 void CEikSrvNotifierManager::UnloadEComPlugInImplementation(TInt aIndex) |
|
1865 // |
|
1866 // Remove the Ecom notifier plugins from the particular implementation |
|
1867 // |
|
1868 { |
|
1869 //Remove the Ecom notifier plugins from the particular implementation |
|
1870 for (TInt i = (iPluginUidList[aIndex])->iNotifierInfo.Count()-1 ; i >=0 ; --i) |
|
1871 { |
|
1872 //find in the observed global list the notifier with same Notifier UID, channel UID & destruction key |
|
1873 for (TInt j = iObservedList->Count()-1; j >=0 ; --j) |
|
1874 { |
|
1875 CEikSrvNotifierWrapper* notifier = iObservedList->At(j); |
|
1876 MEikSrvNotifierBase2::TNotifierInfo info = notifier->iInfo; |
|
1877 const CPluginTrack& pluginTrack = *iPluginUidList[aIndex]; |
|
1878 const CPluginTrack::TNotifierInfo& info2 = pluginTrack.iNotifierInfo[i]; |
|
1879 if ((info2.iNotifierPluginUid == info.iUid) && |
|
1880 (info2.iNotifierPluginChannelUid == info.iChannel) && |
|
1881 (pluginTrack.iDtr_key == notifier->iDestructorKey)) |
|
1882 { |
|
1883 //Delete the notifier |
|
1884 iObservedList->Delete(j); |
|
1885 } |
|
1886 } |
|
1887 } |
|
1888 |
|
1889 //Remove the implementation |
|
1890 delete iPluginUidList[aIndex]; |
|
1891 iPluginUidList.Remove(aIndex); |
|
1892 } |
|
1893 |
|
1894 void CEikSrvNotifierManager::DoAddPlugInL(TUid aUid) |
|
1895 // |
|
1896 // Add plugins depending on the implementation UID |
|
1897 // |
|
1898 { |
|
1899 CArrayPtr<CEikSrvNotifierWrapper>* array = LoadPlugInAndPopulateNotifierArrayL(aUid); |
|
1900 User::LeaveIfNull(array); |
|
1901 CleanupStack::PushL(TCleanupItem(DeleteTempCArray,array)); |
|
1902 TInt rollBackChannels = 0; // required for removing any added channels should this function fail part way through |
|
1903 |
|
1904 const TInt currentObsListIndx = iObservedList->Count(); |
|
1905 TRAPD(error, TryAddNotifiersFromNotifierArrayL(array, rollBackChannels)); |
|
1906 if(error) |
|
1907 { |
|
1908 TInt indexToDelete; |
|
1909 for(TInt jj = 0; jj < rollBackChannels; jj++) |
|
1910 { |
|
1911 indexToDelete = iChannelMonitor->NumberOfChannels() - 1; |
|
1912 iChannelMonitor->DeleteChannel(indexToDelete); |
|
1913 } |
|
1914 User::Leave(error); |
|
1915 } |
|
1916 CleanupStack::PopAndDestroy(array); |
|
1917 |
|
1918 //Add the new added plugin to the track list |
|
1919 CPluginTrack* pluginTrack = new(ELeave) CPluginTrack; |
|
1920 CleanupStack::PushL(pluginTrack); |
|
1921 pluginTrack->iPluginImplementationUid = aUid; |
|
1922 //Add the notifier info to the track pluginlist after successful loading and roll back |
|
1923 const TInt obsListCount = iObservedList->Count(); |
|
1924 for (TInt i = currentObsListIndx; i < obsListCount; i++) |
|
1925 { |
|
1926 CEikSrvNotifierWrapper* notifier = iObservedList->At(i); |
|
1927 pluginTrack->iDtr_key = notifier->iDestructorKey; |
|
1928 CPluginTrack::TNotifierInfo notifInfo(notifier->iInfo.iUid,notifier->iInfo.iChannel); |
|
1929 User::LeaveIfError(pluginTrack->iNotifierInfo.Append(notifInfo)); |
|
1930 } |
|
1931 |
|
1932 User::LeaveIfError(iPluginUidList.Append(pluginTrack)); |
|
1933 CleanupStack::Pop(pluginTrack); |
|
1934 } |
|
1935 |
|
1936 // |
|
1937 // class CDiscoverNewImplementation |
|
1938 // |
|
1939 |
|
1940 CDiscoverNewImplementation::CDiscoverNewImplementation(CEikSrvNotifierManager& aManager): CActive(EActivePriorityDefault) , iManager(aManager) |
|
1941 // |
|
1942 // Constructor. |
|
1943 // |
|
1944 { |
|
1945 // make and install the active scheduler |
|
1946 CActiveScheduler::Add(this); // install as active scheduler |
|
1947 } |
|
1948 |
|
1949 void CDiscoverNewImplementation::ConstructL() |
|
1950 // |
|
1951 // 2 phase construction. opens a econ server session. |
|
1952 // |
|
1953 { |
|
1954 iEComSession = &REComSession::OpenL(); |
|
1955 } |
|
1956 |
|
1957 CDiscoverNewImplementation::~CDiscoverNewImplementation() |
|
1958 // |
|
1959 // Destructor. Closes ecom file server session and cancels the active object itself. |
|
1960 // |
|
1961 { |
|
1962 Cancel(); |
|
1963 iEComSession->Close(); |
|
1964 } |
|
1965 |
|
1966 CDiscoverNewImplementation *CDiscoverNewImplementation::NewL(CEikSrvNotifierManager& aManager) |
|
1967 // |
|
1968 // Static method to instantiate the class. Notifier manager class pointer is passed as a |
|
1969 // argument. |
|
1970 // |
|
1971 { |
|
1972 CDiscoverNewImplementation* self = new (ELeave) CDiscoverNewImplementation(aManager); |
|
1973 CleanupStack::PushL(self); |
|
1974 self->ConstructL(); |
|
1975 CleanupStack::Pop(self); |
|
1976 return self; |
|
1977 } |
|
1978 |
|
1979 void CDiscoverNewImplementation::Start() |
|
1980 // |
|
1981 // Places an outstanding request to active schedular for asynchronous event by ecom server. |
|
1982 // Mostly it will be an installation or unstallation of the ecom based sis files. |
|
1983 // |
|
1984 { |
|
1985 iEComSession->NotifyOnChange(iStatus); |
|
1986 SetActive(); |
|
1987 } |
|
1988 |
|
1989 void CDiscoverNewImplementation::RunL() |
|
1990 // |
|
1991 // Called when an asynchronous request from ecom server is invoked. |
|
1992 // |
|
1993 { |
|
1994 _LIT(KCDiscoverNewImplementationPanic,"CDiscoverNewImplementation Paniced"); |
|
1995 __ASSERT_ALWAYS(!IsActive(),User::Panic(KCDiscoverNewImplementationPanic,KErrCompletion)); |
|
1996 |
|
1997 //Check wether plugin was installed or removed |
|
1998 iManager.CheckForEcomPluginInstallUninstall(); |
|
1999 //Restart the active Object |
|
2000 Start(); |
|
2001 } |
|
2002 |
|
2003 void CDiscoverNewImplementation::DoCancel() |
|
2004 // |
|
2005 // If user want to cancel the active object request. The ecom server outstanding request will |
|
2006 // also get cancelled. |
|
2007 // |
|
2008 { |
|
2009 iEComSession->CancelNotifyOnChange(iStatus); |
|
2010 } |
|
2011 |
|
2012 // |
|
2013 // class CPluginTrack::TNotifierInfo |
|
2014 // |
|
2015 |
|
2016 CPluginTrack::TNotifierInfo::TNotifierInfo(TUid aNotifierPluginUid, TUid aNotifierPluginChannelUid) |
|
2017 // |
|
2018 // Constructor. |
|
2019 // |
|
2020 { |
|
2021 iNotifierPluginUid = aNotifierPluginUid; |
|
2022 iNotifierPluginChannelUid = aNotifierPluginChannelUid; |
|
2023 } |
|
2024 |
|
2025 // |
|
2026 // class CPluginTrack |
|
2027 // |
|
2028 |
|
2029 CPluginTrack::CPluginTrack() |
|
2030 // |
|
2031 // Constructor |
|
2032 // |
|
2033 { |
|
2034 iPluginImplementationUid.iUid = 0; |
|
2035 iDtr_key.iUid = 0; |
|
2036 } |
|
2037 |
|
2038 CPluginTrack::~CPluginTrack() |
|
2039 // |
|
2040 // Destructor. |
|
2041 // |
|
2042 { |
|
2043 iNotifierInfo.Reset(); |
|
2044 iNotifierInfo.Close(); |
|
2045 if(iDtr_key.iUid) |
|
2046 { |
|
2047 REComSession::DestroyedImplementation(iDtr_key); |
|
2048 } |
|
2049 } |
|
2050 // |
|
2051 |
|
2052 // |
|
2053 // class TNotifierSecureInfo |
|
2054 // |
|
2055 |
|
2056 TNotifierSecureInfo::TNotifierSecureInfo(const TUid aNotifierUid, const TSecureId aSecureId) |
|
2057 : iNotifierUid(aNotifierUid), iSecureId(aSecureId) |
|
2058 { |
|
2059 } |
|
2060 |