|
1 /* |
|
2 * Copyright (c) 2006-2008 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: Sensor server plugin proxy implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <ecom/ecom.h> |
|
20 #include "sensrvdefines.h" |
|
21 #include "sensrvpluginproxy.h" |
|
22 #include "sensrvproxymanager.h" |
|
23 #include "sensrvtransaction.h" |
|
24 #include "sensrvtransactionqueue.h" |
|
25 #include "sensrvtransactionmonitor.h" |
|
26 #include "senserverchannel.h" |
|
27 #include "sensrvssymediator.h" |
|
28 #include "sensrvservermediator.h" |
|
29 #include "sensrvssyactivescheduler.h" |
|
30 #include "sensrvclientserver.h" |
|
31 #include "sensrvthreadmonitor.h" |
|
32 #include "sensrvchanneldatareader.h" |
|
33 |
|
34 // --------------------------------------------------------------------------- |
|
35 // 2-phase constructor |
|
36 // --------------------------------------------------------------------------- |
|
37 // |
|
38 CSensrvPluginProxy* CSensrvPluginProxy::NewL(CSensrvProxyManager& aParent, |
|
39 TUid aImplementationUid) |
|
40 { |
|
41 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::NewL(<proxymanager>, aImplementationUid: 0x%x)" ), aImplementationUid.iUid ) ); |
|
42 |
|
43 CSensrvPluginProxy* self = new( ELeave ) CSensrvPluginProxy(aParent, aImplementationUid); |
|
44 |
|
45 CleanupStack::PushL( self ); |
|
46 self->ConstructL(); |
|
47 CleanupStack::Pop( self ); |
|
48 |
|
49 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::NewL - return 0x%x" ), self ) ); |
|
50 |
|
51 return self; |
|
52 } |
|
53 |
|
54 // --------------------------------------------------------------------------- |
|
55 // C++ constructor |
|
56 // --------------------------------------------------------------------------- |
|
57 // |
|
58 CSensrvPluginProxy::CSensrvPluginProxy(CSensrvProxyManager& aParent, |
|
59 TUid aImplementationUid) |
|
60 : iPluginState( EPluginStateUninitialized ), |
|
61 iProxyManager(aParent), |
|
62 iImplementationUid(aImplementationUid) |
|
63 { |
|
64 // Nothing to do |
|
65 } |
|
66 |
|
67 // --------------------------------------------------------------------------- |
|
68 // 2nd phase of construction |
|
69 // --------------------------------------------------------------------------- |
|
70 // |
|
71 void CSensrvPluginProxy::ConstructL() |
|
72 { |
|
73 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::ConstructL()" ) ) ); |
|
74 |
|
75 // Init mutex |
|
76 User::LeaveIfError(iMutex.CreateLocal()); |
|
77 |
|
78 iMutex.Wait(); |
|
79 |
|
80 iLoadWaitQueue = CSensrvTransactionQueue::NewL(ETrue); |
|
81 |
|
82 iTransactionMonitor = CSensrvTransactionMonitor::NewL(*this); |
|
83 |
|
84 // Note: Slight memory savings are possible if iThreadMonitor and iUnloadTimer |
|
85 // are created and deleted alongside SSY thread. However, since the timer events |
|
86 // in these classes initiate cleanup, it is not trivial. Maybe server mediator |
|
87 // could be utilized for delayed cleanup of these classes? |
|
88 |
|
89 iThreadMonitor = CSensrvThreadMonitor::NewL(*this); |
|
90 |
|
91 iUnloadTimer = CSensrvTimer::NewL(*this, |
|
92 iProxyManager.SsyInactivityPeriod(), |
|
93 CSensrvTimer::ETimerIdSsyInactivityTimer); |
|
94 |
|
95 iMutex.Signal(); |
|
96 |
|
97 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::ConstructL - return" ) ) ); |
|
98 } |
|
99 |
|
100 // --------------------------------------------------------------------------- |
|
101 // Destructor |
|
102 // --------------------------------------------------------------------------- |
|
103 // |
|
104 CSensrvPluginProxy::~CSensrvPluginProxy() |
|
105 { |
|
106 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::~CSensrvPluginProxy()" ) ) ); |
|
107 |
|
108 iMutex.Wait(); |
|
109 |
|
110 delete iThreadMonitor; |
|
111 delete iTransactionMonitor; |
|
112 |
|
113 delete iServerMediator; |
|
114 delete iSsyMediator; |
|
115 |
|
116 // Cleanup channels |
|
117 TInt count = iChannelList.Count(); |
|
118 for(TInt i = 0; i < count; i ++) |
|
119 { |
|
120 delete iChannelList[i]; |
|
121 } |
|
122 |
|
123 iChannelList.Reset(); |
|
124 iChannelInfoList.Reset(); |
|
125 iRemovedChannelsInfoList.Reset(); |
|
126 iDynamicChannelInfoList.Reset(); |
|
127 |
|
128 delete iLoadWaitQueue; |
|
129 delete iUnloadTimer; |
|
130 |
|
131 iMutex.Signal(); |
|
132 |
|
133 iMutex.Close(); |
|
134 |
|
135 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::~CSensrvPluginProxy - return" ) ) ); |
|
136 } |
|
137 |
|
138 |
|
139 |
|
140 // --------------------------------------------------------------------------- |
|
141 // Completes the transaction and calls handling for next one in queue. |
|
142 // --------------------------------------------------------------------------- |
|
143 // |
|
144 void CSensrvPluginProxy::TransactionHandledAtSsy(CSensrvTransaction* aTransaction) |
|
145 { |
|
146 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy(aTransaction: 0x%x)" ), aTransaction ) ); |
|
147 |
|
148 // Handle transaction according to transaction type |
|
149 if (aTransaction) |
|
150 { |
|
151 // Route transaction finalization according to transaction type |
|
152 switch(aTransaction->Type()) |
|
153 { |
|
154 // Proxy level transactions handled here |
|
155 case CSensrvTransaction::ETransTypeLoadSsy: |
|
156 case CSensrvTransaction::ETransTypeMediatorChannelsChanged: |
|
157 { |
|
158 CompleteTransaction(aTransaction); |
|
159 } |
|
160 break; |
|
161 |
|
162 // Channel level transactions handled in corresponding channel object. |
|
163 case CSensrvTransaction::ETransTypeOpenChannel: |
|
164 case CSensrvTransaction::ETransTypeCloseChannel: |
|
165 case CSensrvTransaction::ETransTypeStartListening: |
|
166 case CSensrvTransaction::ETransTypeStopListening: |
|
167 case CSensrvTransaction::ETransTypeMediatorNewDataAvailable: |
|
168 case CSensrvTransaction::ETransTypeGetProperty: |
|
169 case CSensrvTransaction::ETransTypeGetAllProperties: |
|
170 case CSensrvTransaction::ETransTypeSetProperty: |
|
171 case CSensrvTransaction::ETransTypeStartConditionListening: |
|
172 case CSensrvTransaction::ETransTypeStopConditionListening: |
|
173 case CSensrvTransaction::ETransTypeMediatorPropertyChanged: |
|
174 case CSensrvTransaction::ETransTypeMediatorForceChannelClose: |
|
175 { |
|
176 // These transactions must always have valid channel object. |
|
177 __ASSERT_ALWAYS(aTransaction->Channel(), User::Panic(KSensrvPanicCategory, ESensrvPanicNullChannel)); |
|
178 |
|
179 aTransaction->Channel()->CompleteTransaction(aTransaction); |
|
180 } |
|
181 break; |
|
182 |
|
183 default: |
|
184 // Unexpected transaction type, so we do not know what to do with it |
|
185 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy - ERROR: Invalid transaction type" ) ) ); |
|
186 User::Panic(KSensrvPanicCategory, ESensrvPanicUnknownTransactionType); |
|
187 break; |
|
188 } |
|
189 } |
|
190 else |
|
191 { |
|
192 // NULL transaction used to trigger transaction handling. |
|
193 if ( iPluginState == EPluginStateThreadInitializing ) |
|
194 { |
|
195 // Initial notify from SSY thread. |
|
196 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy - SSY thread initialization completion detected." ) ) ); |
|
197 |
|
198 SetPluginState(EPluginStateThreadInitialized); |
|
199 |
|
200 // Start handling queued transactions |
|
201 HandleNextTransaction(); |
|
202 } |
|
203 else if (iPluginState == EPluginStateUnloaded) |
|
204 { |
|
205 // SSY unloading has finished, handle next transaction if any |
|
206 HandleNextTransaction(); |
|
207 } |
|
208 else |
|
209 { |
|
210 // Can get here if server mediator has been notified, |
|
211 // but before its RunL is executed, the only transaction in server mediator's queue |
|
212 // is deleted (because of client panic caused session termination, for example). |
|
213 // Highly unlikely case, but theoretically possible. |
|
214 // In that case we can just ignore the notification. |
|
215 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy - NULL transaction in an unexpected plugin state: %d" ), iPluginState ) ); |
|
216 } |
|
217 } |
|
218 |
|
219 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy - return" ) ) ); |
|
220 } |
|
221 |
|
222 |
|
223 // --------------------------------------------------------------------------- |
|
224 // Initializes plugin mediators and thread, |
|
225 // loads the plugin and queries for supported channels. |
|
226 // --------------------------------------------------------------------------- |
|
227 // |
|
228 void CSensrvPluginProxy::InitializePluginL() |
|
229 { |
|
230 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL()" ) ) ); |
|
231 |
|
232 iMutex.Wait(); |
|
233 |
|
234 iPreviousSsyLoadFailed = EFalse; // Reset SSY load fail indicator |
|
235 |
|
236 if (iPluginState != EPluginStateUnloading) |
|
237 { |
|
238 // Create mutex signaling cleanup item. |
|
239 CleanupStack::PushL( |
|
240 TCleanupItem( CleanupInitializePlugin, this ) ); |
|
241 |
|
242 // Create Ssy thread |
|
243 // Use unique identifier generated by proxy manager to name thread |
|
244 // so that name is guaranteed unique, yet recognizable. |
|
245 HBufC* buf = HBufC::NewLC(KSensrvSsyThreadNameMaxLen); |
|
246 buf->Des().Append(KSensrvSsyThreadNameBase); |
|
247 |
|
248 TInt err(KErrAlreadyExists); |
|
249 |
|
250 while (err == KErrAlreadyExists) |
|
251 { |
|
252 |
|
253 buf->Des().AppendNum(iProxyManager.GenerateUniqueId()); |
|
254 |
|
255 err = iSsyThread.Create(*buf, |
|
256 SsyThreadFunction, |
|
257 ProxyManager().SsyStackSize(), |
|
258 KSensrvSsyHeapInitialSize, |
|
259 ProxyManager().SsyHeapMaxSize(), |
|
260 (TAny*)this); |
|
261 |
|
262 if (err == KErrAlreadyExists) |
|
263 { |
|
264 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL - Thread name is already in use, recreating..." ) ) ); |
|
265 } |
|
266 |
|
267 buf->Des().Delete(KSensrvSsyThreadNameBaseLen, KSensrvSsyThreadNameMaxLen); |
|
268 } |
|
269 |
|
270 if (err != KErrNone) |
|
271 { |
|
272 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL - Error creating thread." ) ) ); |
|
273 User::Leave(err); |
|
274 } |
|
275 |
|
276 CleanupStack::PopAndDestroy(buf); |
|
277 |
|
278 // start monitoring the thread |
|
279 User::LeaveIfError(iThreadMonitor->StartMonitoring(iSsyThread)); |
|
280 |
|
281 // If InitializePluginL leaves, thread monitor triggered cleanup will set state again |
|
282 SetPluginState(EPluginStateThreadInitializing); |
|
283 |
|
284 // SSY mediator is created here but initialized by SSY thread as it needs current thread handle. |
|
285 iSsyMediator = CSensrvSsyMediator::NewL(this); |
|
286 |
|
287 // Create and initialize server mediator if not yet created |
|
288 if (!iServerMediator) |
|
289 { |
|
290 iServerMediator = CSensrvServerMediator::NewL(this); |
|
291 User::LeaveIfError(iServerMediator->Initialize()); |
|
292 // Note: SSY mediator is initialized by SSY thread |
|
293 } |
|
294 |
|
295 // Initially there are no channel change listeners concerning this proxy |
|
296 iChannelChangeListenerCount = 0; |
|
297 |
|
298 // Create transaction for loading plugin. |
|
299 CSensrvTransaction* loadTransaction = NULL; |
|
300 loadTransaction = CSensrvTransaction::NewL( |
|
301 NULL, |
|
302 this, |
|
303 NULL, |
|
304 CSensrvTransaction::ETransTypeLoadSsy); |
|
305 |
|
306 // Add transaction to the beginning of the queue |
|
307 err = QueueTransaction(loadTransaction, EFalse); |
|
308 |
|
309 if (err == KErrNone) |
|
310 { |
|
311 // Resume Ssy thread. Must be last thing to do in this method |
|
312 // so that nothing else can leave after this. |
|
313 iSsyThread.Resume(); |
|
314 } |
|
315 else |
|
316 { |
|
317 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL - ERROR: Failed to queue load transaction %d" ), err ) ); |
|
318 // Cleanup transaction |
|
319 loadTransaction->SetErrorCode(err); |
|
320 loadTransaction->Complete(); |
|
321 delete loadTransaction; |
|
322 User::Leave(err); |
|
323 } |
|
324 |
|
325 CleanupStack::Pop(); // CleanupInitializePlugin |
|
326 } |
|
327 else |
|
328 { |
|
329 TInt err = EnqueueDelayedInitializeTransaction(); |
|
330 if (err == KErrNone) |
|
331 { |
|
332 // Handle delayed initialize immediately, if already fully unloaded |
|
333 if (iPluginState == EPluginStateUnloaded) |
|
334 { |
|
335 HandleNextTransaction(); |
|
336 } |
|
337 } |
|
338 else |
|
339 { |
|
340 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL - ERROR: Failed to queue delayed initialize %d" ), err ) ); |
|
341 iPreviousSsyLoadFailed = ETrue; |
|
342 User::Leave(err); |
|
343 } |
|
344 } |
|
345 |
|
346 iMutex.Signal(); |
|
347 |
|
348 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializePluginL - return" ) ) ); |
|
349 } |
|
350 |
|
351 // --------------------------------------------------------------------------- |
|
352 // Initializes plugin channel data. |
|
353 // --------------------------------------------------------------------------- |
|
354 // |
|
355 TInt CSensrvPluginProxy::InitializeChannelData( const CImplementationInformation& aImplInfo ) |
|
356 { |
|
357 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializeChannelDataL" ) ) ); |
|
358 |
|
359 TSensrvChannelDataReader reader; |
|
360 TInt err = reader.ReadChannels( aImplInfo, iChannelInfoList, iDynamicChannelInfoList ); |
|
361 if ( err == KErrNone ) |
|
362 { |
|
363 // Generate unique IDs for static channels now. IDs for dynamic channels are handled by SSY channel registration. |
|
364 TInt count( iChannelInfoList.Count() ); |
|
365 for( TInt i = 0; i < count; i++) |
|
366 { |
|
367 TSensrvChannelId newId = static_cast<TSensrvChannelId>(ProxyManager().GenerateUniqueId()); |
|
368 |
|
369 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializeChannelDataL - plugin UID: 0x%x channel: %d" ), |
|
370 aImplInfo.ImplementationUid().iUid, newId ) ); |
|
371 |
|
372 iChannelInfoList[i].iChannelId = newId; |
|
373 } |
|
374 } |
|
375 iIsInitialized = ETrue; // even though thread not setup and plugin not laoded yet. |
|
376 |
|
377 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::InitializeChannelDataL - err %d, return" ), err ) ); |
|
378 |
|
379 return err; |
|
380 } |
|
381 |
|
382 // --------------------------------------------------------------------------- |
|
383 // Handles client message. |
|
384 // All messages coming from client to proxy target specific channel, |
|
385 // so pass the message to correct channel object. |
|
386 // Proxy manager makes sure that messages dispatched to each proxy |
|
387 // actually target a channel provided by that proxy, so no rechecking is done. |
|
388 // --------------------------------------------------------------------------- |
|
389 // |
|
390 void CSensrvPluginProxy::DispatchMessage(CSensrvMessage& aMessage, |
|
391 TSensrvChannelId aChannelId) |
|
392 { |
|
393 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage(aMessage.Function(): %d, aChannelId: %d)" ), aMessage.Function(), aChannelId ) ); |
|
394 |
|
395 iMutex.Wait(); |
|
396 |
|
397 TInt err(KErrNone); |
|
398 TBool completeMessageOnError(ETrue); |
|
399 |
|
400 // Check state |
|
401 if (iDeletionFlag) |
|
402 { |
|
403 // If proxy is marked for deletion, do not allow further messages |
|
404 err = KErrNotFound; |
|
405 } |
|
406 else |
|
407 { |
|
408 if (iPluginState == EPluginStateLoaded) |
|
409 { |
|
410 // Get channel and pass message there |
|
411 CSensrvChannel* channel = GetChannelForId(aChannelId); |
|
412 |
|
413 // Special case: When opening channel, create channel if it is not found |
|
414 if (aMessage.Function() == ESensrvSrvReqOpenChannel && !channel) |
|
415 { |
|
416 // Get channel info |
|
417 TSensrvChannelInfo* info = GetChannelInfoForId(aChannelId); |
|
418 |
|
419 if (info) |
|
420 { |
|
421 TRAPD(err, channel = CSensrvChannel::NewL(*info, *this)); |
|
422 if (err == KErrNone) |
|
423 { |
|
424 // Add channel to channel list |
|
425 err = iChannelList.Append(channel); |
|
426 |
|
427 if (err != KErrNone) |
|
428 { |
|
429 delete channel; // Deleting the channel that is allocated on the heap in case Append Failure. |
|
430 channel = NULL; |
|
431 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - ERROR: Failed to append channel to array: %d" ), err ) ); |
|
432 } |
|
433 } |
|
434 else |
|
435 { |
|
436 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - ERROR: Failed to create channel: %d" ), err ) ); |
|
437 } |
|
438 } |
|
439 else |
|
440 { |
|
441 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - ERROR: No channel info found" ) ) ); |
|
442 err = KErrNotFound; |
|
443 } |
|
444 } |
|
445 |
|
446 if (err == KErrNone) |
|
447 { |
|
448 if (channel) |
|
449 { |
|
450 channel->DispatchMessage(aMessage); |
|
451 } |
|
452 else |
|
453 { |
|
454 // If channel object doesn't exist, something is wrong. |
|
455 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - ERROR: No channel object" ) ) ); |
|
456 err = KErrNotFound; |
|
457 } |
|
458 } |
|
459 } |
|
460 else if ( aMessage.Function() == ESensrvSrvReqOpenChannel |
|
461 && iPluginState != EPluginStateUninitialized ) |
|
462 { |
|
463 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - Queuing open channel message" ) ) ); |
|
464 |
|
465 // If unloading/unloaded, queue initialization transaction. |
|
466 if (iPluginState == EPluginStateUnloading || iPluginState == EPluginStateUnloaded) |
|
467 { |
|
468 err = EnqueueDelayedInitializeTransaction(); |
|
469 } |
|
470 |
|
471 // Queue open transaction into wait queue until plugin can load itself. |
|
472 if (err == KErrNone) |
|
473 { |
|
474 completeMessageOnError = EFalse; |
|
475 |
|
476 CSensrvTransaction* transaction = NULL; |
|
477 |
|
478 TRAP(err, transaction = CSensrvTransaction::NewL( |
|
479 &aMessage, |
|
480 this, |
|
481 NULL, |
|
482 CSensrvTransaction::ETransTypeDelayedOpenChannel)); |
|
483 |
|
484 if (err == KErrNone) |
|
485 { |
|
486 err = QueueTransaction(transaction, ETrue); |
|
487 |
|
488 if(err == KErrNone) |
|
489 { |
|
490 // Add transaction to monitor for the duration of the wait. |
|
491 iTransactionMonitor->AddTransaction(transaction); |
|
492 } |
|
493 else |
|
494 { |
|
495 transaction->SetErrorCode(err); |
|
496 transaction->Complete(); |
|
497 delete transaction; |
|
498 transaction = NULL; |
|
499 } |
|
500 } |
|
501 } |
|
502 |
|
503 // Handle delayed initialize immediately, if already fully unloaded |
|
504 if (err == KErrNone && iPluginState == EPluginStateUnloaded) |
|
505 { |
|
506 HandleNextTransaction(); |
|
507 } |
|
508 } |
|
509 else |
|
510 { |
|
511 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - ERROR: Plugin in invalid state: %d" ), iPluginState ) ); |
|
512 err = KErrNotReady; |
|
513 } |
|
514 } |
|
515 |
|
516 if (err != KErrNone && completeMessageOnError) |
|
517 { |
|
518 aMessage.Complete(err); |
|
519 } |
|
520 |
|
521 iMutex.Signal(); |
|
522 |
|
523 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::DispatchMessage - return" ) ) ); |
|
524 } |
|
525 |
|
526 // --------------------------------------------------------------------------- |
|
527 // Checks if this proxy supports specified channel |
|
528 // --------------------------------------------------------------------------- |
|
529 // |
|
530 TBool CSensrvPluginProxy::IsChannelSupported(TSensrvChannelId aChannelId) |
|
531 { |
|
532 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::IsChannelSupported(aChannelId: %d)" ), aChannelId ) ); |
|
533 |
|
534 TBool isSupported(EFalse); |
|
535 |
|
536 iMutex.Wait(); |
|
537 |
|
538 if (iIsInitialized) |
|
539 { |
|
540 TInt channelCount = iChannelInfoList.Count(); |
|
541 if (channelCount > 0) |
|
542 { |
|
543 for(TInt j = 0; !isSupported && j < channelCount; j++) |
|
544 { |
|
545 if (iChannelInfoList[j].iChannelId == aChannelId) |
|
546 { |
|
547 isSupported = ETrue; |
|
548 } |
|
549 } |
|
550 } |
|
551 } |
|
552 else |
|
553 { |
|
554 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::IsChannelSupported - Proxy not yet initialized" ) ) ); |
|
555 } |
|
556 |
|
557 iMutex.Signal(); |
|
558 |
|
559 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::IsChannelSupported - return %d" ), isSupported) ); |
|
560 |
|
561 return isSupported; |
|
562 } |
|
563 |
|
564 // --------------------------------------------------------------------------- |
|
565 // Gets channel object handling specified channel. |
|
566 // --------------------------------------------------------------------------- |
|
567 // |
|
568 CSensrvChannel* CSensrvPluginProxy::GetChannelForId(TSensrvChannelId aChannelId) const |
|
569 { |
|
570 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetChannelForId(aChannelId: %d)" ), aChannelId ) ); |
|
571 |
|
572 CSensrvChannel* returnChannel = NULL; |
|
573 |
|
574 TInt channelCount = iChannelList.Count(); |
|
575 for(TInt i = 0; !returnChannel && i < channelCount; i++) |
|
576 { |
|
577 if (iChannelList[i]->Id() == aChannelId) |
|
578 { |
|
579 returnChannel = iChannelList[i]; |
|
580 } |
|
581 } |
|
582 |
|
583 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetChannelForId - return 0x%x" ), returnChannel ) ); |
|
584 |
|
585 return returnChannel; |
|
586 } |
|
587 |
|
588 |
|
589 // --------------------------------------------------------------------------- |
|
590 // Cleans up everything related to terminated session. |
|
591 // --------------------------------------------------------------------------- |
|
592 // |
|
593 void CSensrvPluginProxy::SessionTerminated( CSensrvSession* aSession ) |
|
594 { |
|
595 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SessionTerminated(aSession: 0x%x)"),aSession ) ); |
|
596 |
|
597 iMutex.Wait(); |
|
598 |
|
599 // Cleanup any waiting transactions for this session |
|
600 iLoadWaitQueue->Remove(aSession); |
|
601 iTransactionMonitor->RemoveSessionTransactions(aSession); |
|
602 |
|
603 // Clean up mediators |
|
604 if (iSsyMediator) |
|
605 { |
|
606 iSsyMediator->SessionTerminated(aSession); |
|
607 } |
|
608 |
|
609 if (iServerMediator) |
|
610 { |
|
611 iServerMediator->SessionTerminated(aSession); |
|
612 } |
|
613 |
|
614 |
|
615 // Call session cleanup on each channel |
|
616 TInt channelCount = iChannelList.Count(); |
|
617 for(TInt i = 0; i < channelCount; i++) |
|
618 { |
|
619 iChannelList[i]->SessionTerminated(aSession); |
|
620 } |
|
621 |
|
622 iMutex.Signal(); |
|
623 |
|
624 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SessionTerminated - return" )) ); |
|
625 } |
|
626 |
|
627 // --------------------------------------------------------------------------- |
|
628 // Handles SSY notification failure. |
|
629 // This means going through all channels checking where failure possibly |
|
630 // occurred, and of course any proxy level transactions. |
|
631 // Note that this can execute transactions out of original sequence they |
|
632 // have been notified to server mediator, but this should be no problem, |
|
633 // each single channel can only have single ongoing transaction at SSY. |
|
634 // Transactions of different channels do not interfere with each other. |
|
635 // --------------------------------------------------------------------------- |
|
636 // |
|
637 void CSensrvPluginProxy::HandleSsyNotifyFailure() |
|
638 { |
|
639 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleSsyNotifyFailure()" ) ) ); |
|
640 |
|
641 // Check queued transactions to determine if they are handled at SSY |
|
642 CSensrvTransaction* transaction = iLoadWaitQueue->First(); |
|
643 |
|
644 if (transaction && transaction->State() == CSensrvTransaction::ETransStateNotifyFailed) |
|
645 { |
|
646 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleSsyNotifyFailure - Notify failed transaction found" ) ) ); |
|
647 transaction->SetState(CSensrvTransaction::ETransStateHandledAtSsy); |
|
648 TransactionHandledAtSsy(transaction); |
|
649 } |
|
650 |
|
651 if ( iSsyMediator |
|
652 && iSsyMediator->ChannelChangeTransaction() |
|
653 && iSsyMediator->ChannelChangeTransaction()->State() == CSensrvTransaction::ETransStateNotifyFailed) |
|
654 { |
|
655 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleSsyNotifyFailure - Notify failed transaction found (ETransTypeMediatorChannelsChanged)" ) ) ); |
|
656 iSsyMediator->ChannelChangeTransaction()->SetState(CSensrvTransaction::ETransStateHandledAtSsy); |
|
657 TransactionHandledAtSsy(iSsyMediator->ChannelChangeTransaction()); |
|
658 } |
|
659 |
|
660 // Pass notification to each channel |
|
661 TInt channelCount = iChannelList.Count(); |
|
662 for(TInt i = 0; i < channelCount; i++) |
|
663 { |
|
664 iChannelList[i]->HandleSsyNotifyFailure(); |
|
665 } |
|
666 |
|
667 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleSsyNotifyFailure - return" ) ) ); |
|
668 } |
|
669 |
|
670 // --------------------------------------------------------------------------- |
|
671 // Unloads SSY as any timed out transactions probably mean that |
|
672 // SSY has either crashed or is deadlocked. |
|
673 // --------------------------------------------------------------------------- |
|
674 // |
|
675 void CSensrvPluginProxy::HandleTransactionTimeout() |
|
676 { |
|
677 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleTransactionTimeout()" ) ) ); |
|
678 |
|
679 // Any transaction timeout results in unloading of the SSY |
|
680 CleanupPlugin(); |
|
681 |
|
682 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleTransactionTimeout - return" ) ) ); |
|
683 } |
|
684 |
|
685 // --------------------------------------------------------------------------- |
|
686 // Deletes SSY mediator and closes thread. |
|
687 // --------------------------------------------------------------------------- |
|
688 // |
|
689 void CSensrvPluginProxy::SsyThreadTerminated() |
|
690 { |
|
691 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SsyThreadTerminated()" ) ) ); |
|
692 |
|
693 // Instead of delete, Free is used. |
|
694 // It means that destructor of the iSsyMediator is not called. |
|
695 // Calling the destructor causes KERN-EXEC 3 in servers main thread |
|
696 // if SSY thread is not anymore alive. |
|
697 // iSsyMediator inherit from CActive and calling ~CActive() while its |
|
698 // scheduler is dead causes KERN-EXEC 3 panic. |
|
699 iSsyMediator->Destruct(); |
|
700 iSsyMediator->BaseDestruct(); |
|
701 iProxyManager.ServerHeap()->Free( iSsyMediator ); |
|
702 iSsyMediator = NULL; |
|
703 |
|
704 // Note: Server mediator is not deleted until proxy is deleted, |
|
705 // as in some cases resulting in cleanup, its RunL-method is what initiated the sequence. |
|
706 |
|
707 iSsyThread.Close(); |
|
708 |
|
709 TPluginState previousState = iPluginState; |
|
710 SetPluginState(EPluginStateUnloaded); |
|
711 |
|
712 // Cleanup needed in case SSY thread termination was uncontrolled. |
|
713 if (previousState != EPluginStateUnloading) |
|
714 { |
|
715 CleanupPlugin(); |
|
716 } |
|
717 |
|
718 // Notify server mediator with null transaction to handle next transaction |
|
719 if (iLoadWaitQueue && iServerMediator && !iLoadWaitQueue->IsEmpty()) |
|
720 { |
|
721 iServerMediator->Notify(NULL); |
|
722 } |
|
723 |
|
724 // Notify proxy manager that thread has terminated |
|
725 iProxyManager.SsyThreadTerminated(); |
|
726 |
|
727 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SsyThreadTerminated - return" ) ) ); |
|
728 } |
|
729 |
|
730 // --------------------------------------------------------------------------- |
|
731 // Starts SSY unload timer if no clients |
|
732 // --------------------------------------------------------------------------- |
|
733 // |
|
734 void CSensrvPluginProxy::StartUnloadTimerIfNeeded() |
|
735 { |
|
736 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded()" ) ) ); |
|
737 |
|
738 if (!iUnloadTimer->IsActive() ) |
|
739 { |
|
740 if (GetTotalListenerCount()) |
|
741 { |
|
742 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded - Listener found, aborting" ) ) ); |
|
743 } |
|
744 else if (iChannelChangeListenerCount > 0) |
|
745 { |
|
746 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded - Change listener found, aborting" ) ) ); |
|
747 } |
|
748 else |
|
749 { |
|
750 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded - No listeners found, starting unload timer" ) ) ); |
|
751 iUnloadTimer->Set(iProxyManager.SsyInactivityPeriod()); |
|
752 } |
|
753 } |
|
754 else |
|
755 { |
|
756 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded - Unload timer already active or scheduler stopped" ) ) ); |
|
757 } |
|
758 |
|
759 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::StartUnloadTimerIfNeeded - return " ) ) ); |
|
760 } |
|
761 |
|
762 |
|
763 // --------------------------------------------------------------------------- |
|
764 // Kill threads if they are still active |
|
765 // --------------------------------------------------------------------------- |
|
766 // |
|
767 void CSensrvPluginProxy::TimerFired(TInt /*aTimerId*/) |
|
768 { |
|
769 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TimerFired()" ) ) ); |
|
770 |
|
771 iMutex.Wait(); |
|
772 |
|
773 // Doublecheck that there is still zero listeners, just in case |
|
774 if(!GetTotalListenerCount()) |
|
775 { |
|
776 CleanupPlugin(); |
|
777 } |
|
778 |
|
779 iMutex.Signal(); |
|
780 |
|
781 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TimerFired - return " ) ) ); |
|
782 } |
|
783 |
|
784 // --------------------------------------------------------------------------- |
|
785 // Cleans up the plugin and thread |
|
786 // --------------------------------------------------------------------------- |
|
787 // |
|
788 void CSensrvPluginProxy::CleanupPlugin() |
|
789 { |
|
790 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CleanupPlugin()" ) ) ); |
|
791 |
|
792 // Something has failed, so notify proxy manager that proxy initialization is complete, |
|
793 // if this happened during the first attempt to load plugin. |
|
794 // Note that this will leave proxy with zero channels |
|
795 // but there is not much we can do about it, as it is very unlikely that reload would be |
|
796 // successfull either. |
|
797 |
|
798 if (!iIsInitialized || |
|
799 iPluginState == EPluginStateUninitialized || |
|
800 iPluginState == EPluginStateThreadInitializing || |
|
801 iPluginState == EPluginStateThreadInitialized) |
|
802 { |
|
803 iPreviousSsyLoadFailed = ETrue; |
|
804 // If first fail, fake initialized and notify manager to continue pending activities |
|
805 // If proxy provides dynamic channels, notify manager to continue pending channel queries |
|
806 if (!iIsInitialized || iDynamicChannelInfoList.Count() > 0) |
|
807 { |
|
808 iIsInitialized = ETrue; |
|
809 iProxyManager.NotifyProxyInitialized(); |
|
810 } |
|
811 } |
|
812 |
|
813 // Cleanup channels |
|
814 iChannelList.ResetAndDestroy(); |
|
815 |
|
816 // Cleanup all ongoing transactions. |
|
817 if (iTransactionMonitor) |
|
818 { |
|
819 iTransactionMonitor->RemoveAllTransactions(); |
|
820 } |
|
821 |
|
822 |
|
823 if (iServerMediator) |
|
824 { |
|
825 |
|
826 iMutex.Wait(); |
|
827 iServerMediator->RemoveAllTransactions(); |
|
828 iMutex.Signal(); |
|
829 } |
|
830 |
|
831 if (iPluginState != EPluginStateUnloaded && iLoadWaitQueue) |
|
832 { |
|
833 // Load wait transactions are not cleared when cleanup is called from SsyThreadTerminated() |
|
834 iLoadWaitQueue->RemoveAll(); |
|
835 } |
|
836 |
|
837 // Clean up SSY mediator. Actual deletion of SSY mediator is done in SsyThreadTerminated() |
|
838 if (iSsyMediator) |
|
839 { |
|
840 SetPluginState(EPluginStateUnloading); |
|
841 iSsyMediator->Cleanup(); |
|
842 } |
|
843 else |
|
844 { |
|
845 SetPluginState(EPluginStateUnloaded); |
|
846 } |
|
847 |
|
848 // Thread monitor needs to ensure that SSY thread dies. |
|
849 // If cleanup was triggered by thread dying, this is not needed |
|
850 if (iThreadMonitor && iPluginState != EPluginStateUnloaded) |
|
851 { |
|
852 iThreadMonitor->DelayedTermination(); |
|
853 } |
|
854 |
|
855 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CleanupPlugin - return" ) ) ); |
|
856 } |
|
857 |
|
858 // --------------------------------------------------------------------------- |
|
859 // Queues transaction |
|
860 // --------------------------------------------------------------------------- |
|
861 // |
|
862 TInt CSensrvPluginProxy::QueueTransaction(CSensrvTransaction* aTransaction, TBool aLast) |
|
863 { |
|
864 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::QueueTransaction(aTransaction: 0x%x, aLast: %d)" ), aTransaction, aLast ) ); |
|
865 |
|
866 __ASSERT_ALWAYS(aTransaction, User::Panic(KSensrvPanicCategory, ESensrvPanicNullTransaction)); |
|
867 |
|
868 TInt err(KErrNone); |
|
869 |
|
870 aTransaction->SetState(CSensrvTransaction::ETransStateQueued); |
|
871 |
|
872 err = iLoadWaitQueue->Add(aTransaction, aLast); |
|
873 if (err != KErrNone) |
|
874 { |
|
875 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::QueueTransaction - ERROR: Failed to add transaction to queue" ) ) ); |
|
876 } |
|
877 |
|
878 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::QueueTransaction - return %d" ), err ) ); |
|
879 |
|
880 return err; |
|
881 } |
|
882 |
|
883 // --------------------------------------------------------------------------- |
|
884 // Executes the first transaction in given queue, unless it is already executing, |
|
885 // in which case nothing is done. |
|
886 // --------------------------------------------------------------------------- |
|
887 // |
|
888 void CSensrvPluginProxy::HandleNextTransaction() |
|
889 { |
|
890 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction()" ) ) ); |
|
891 |
|
892 CSensrvTransaction* transaction = iLoadWaitQueue->First(); |
|
893 |
|
894 if (transaction && !iDeletionFlag) |
|
895 { |
|
896 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - Handling transaction type: %d" ), transaction->Type() ) ); |
|
897 if (transaction->State() == CSensrvTransaction::ETransStateQueued) |
|
898 { |
|
899 switch (transaction->Type()) |
|
900 { |
|
901 case CSensrvTransaction::ETransTypeLoadSsy: |
|
902 { |
|
903 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ETransTypeLoadSsy" ) ) ); |
|
904 transaction->SetState(CSensrvTransaction::ETransStateExecuting); |
|
905 |
|
906 // If SSY mediator is not yet initialized, it is an error |
|
907 __ASSERT_ALWAYS(iSsyMediator, User::Panic(KSensrvPanicCategory, ESensrvPanicNullSsyMediator)); |
|
908 |
|
909 Mutex().Wait(); |
|
910 // Notify SSY mediator that transaction is ready to be handled. |
|
911 TInt err(iSsyMediator->Notify(transaction)); |
|
912 Mutex().Signal(); |
|
913 // If there was error, transaction needs to be removed from queue (which also completes it) |
|
914 if (err == KErrNone) |
|
915 { |
|
916 iTransactionMonitor->AddTransaction(transaction); |
|
917 } |
|
918 else |
|
919 { |
|
920 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ERROR: Failed to handle next transaction: %d" ), err ) ); |
|
921 transaction->SetErrorCode(err); |
|
922 iLoadWaitQueue->Remove(transaction, CSensrvTransactionQueue::ERemovalTypeComplete); |
|
923 transaction = NULL; |
|
924 |
|
925 // Since proxy only handles plugin level transactions (load), |
|
926 // failure on any of them means we need to clean up the plugin, |
|
927 // which will also clean up any pending transactions. |
|
928 CleanupPlugin(); |
|
929 } |
|
930 } |
|
931 break; |
|
932 case CSensrvTransaction::ETransTypeDelayedInitialize: |
|
933 { |
|
934 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ETransTypeDelayedInitialize" ) ) ); |
|
935 |
|
936 // Initialize only if state is unloaded |
|
937 if (iPluginState == EPluginStateUnloaded) |
|
938 { |
|
939 iLoadWaitQueue->Remove(transaction, CSensrvTransactionQueue::ERemovalTypeComplete); |
|
940 |
|
941 // Request initialize |
|
942 TRAPD(err, InitializePluginL()); |
|
943 |
|
944 if (err != KErrNone) |
|
945 { |
|
946 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ERROR: Failed to reinitialize plugin : %d" ), err ) ); |
|
947 } |
|
948 } |
|
949 else |
|
950 { |
|
951 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ERROR: Attempted to reinitialize in invalid state: %d" ), iPluginState ) ); |
|
952 } |
|
953 } |
|
954 break; |
|
955 case CSensrvTransaction::ETransTypeDelayedOpenChannel: |
|
956 { |
|
957 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ETransTypeDelayedOpenChannel" ) ) ); |
|
958 |
|
959 iTransactionMonitor->RemoveTransaction(transaction); |
|
960 |
|
961 // Extract message from transaction and call dispatch from proper handling |
|
962 CSensrvMessage* message = transaction->ExtractMessage(); |
|
963 |
|
964 iLoadWaitQueue->Remove(transaction, CSensrvTransactionQueue::ERemovalTypeComplete); |
|
965 |
|
966 // No need to check error value, we already know message type is correct. |
|
967 TSensrvChannelId channelId(0); |
|
968 message->GetChannelId(channelId); |
|
969 |
|
970 DispatchMessage(*message, channelId); |
|
971 |
|
972 // Recursively handle next transaction |
|
973 HandleNextTransaction(); |
|
974 } |
|
975 break; |
|
976 default: |
|
977 // Unexpected transaction type, so we do not know what to do with it |
|
978 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - ERROR: Invalid transaction type" ) ) ); |
|
979 User::Panic(KSensrvPanicCategory, ESensrvPanicUnknownTransactionType); |
|
980 break; |
|
981 } |
|
982 } |
|
983 else |
|
984 { |
|
985 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - Previous transaction still executing" ) ) ); |
|
986 } |
|
987 } |
|
988 else |
|
989 { |
|
990 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - No transaction to execute" ) ) ); |
|
991 } |
|
992 |
|
993 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::HandleNextTransaction - return" ) ) ); |
|
994 } |
|
995 |
|
996 // --------------------------------------------------------------------------- |
|
997 // Handles transaction finalization and completes transaction on proxy's queue. |
|
998 // --------------------------------------------------------------------------- |
|
999 // |
|
1000 void CSensrvPluginProxy::CompleteTransaction(CSensrvTransaction* aTransaction) |
|
1001 { |
|
1002 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CompleteTransaction(aTransaction: 0x%x)" ), aTransaction ) ); |
|
1003 |
|
1004 __ASSERT_ALWAYS(aTransaction, User::Panic(KSensrvPanicCategory, ESensrvPanicNullTransaction)); |
|
1005 |
|
1006 switch (aTransaction->Type()) |
|
1007 { |
|
1008 // Proxy level transactions handled here |
|
1009 case CSensrvTransaction::ETransTypeLoadSsy: |
|
1010 { |
|
1011 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CompleteTransaction - ETransTypeLoadSsy" ) ) ); |
|
1012 |
|
1013 TInt err = aTransaction->ErrorCode(); |
|
1014 |
|
1015 if ( err == KErrNone) |
|
1016 { |
|
1017 err = UpdateChannelInfoLists(); |
|
1018 |
|
1019 // Update plugin state |
|
1020 SetPluginState(EPluginStateLoaded); |
|
1021 } |
|
1022 else |
|
1023 { |
|
1024 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CompleteTransaction - ERROR: Load transaction failed %d" ), err ) ); |
|
1025 } |
|
1026 |
|
1027 if (err != KErrNone) |
|
1028 { |
|
1029 // Since there was an error, cleanup the plugin and thread |
|
1030 CleanupPlugin(); |
|
1031 } |
|
1032 else |
|
1033 { |
|
1034 // Proxy has been initialized, notify manager |
|
1035 // If proxy provides dynamic channels, notify manager to handle pending channel queries |
|
1036 if (!iIsInitialized || iDynamicChannelInfoList.Count() > 0) |
|
1037 { |
|
1038 iIsInitialized = ETrue; |
|
1039 iProxyManager.NotifyProxyInitialized(); |
|
1040 } |
|
1041 |
|
1042 // Initially there are no clients, so startup unload timer |
|
1043 StartUnloadTimerIfNeeded(); |
|
1044 } |
|
1045 } |
|
1046 break; |
|
1047 |
|
1048 case CSensrvTransaction::ETransTypeMediatorChannelsChanged: |
|
1049 { |
|
1050 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CompleteTransaction - ETransTypeMediatorChannelsChanged" ) ) ); |
|
1051 |
|
1052 // Error is irrelevant, as we can't do anything about it anyway, and UpdateChannelInfoLists() |
|
1053 // does its own tracing. |
|
1054 UpdateChannelInfoLists(); |
|
1055 } |
|
1056 break; |
|
1057 |
|
1058 default: |
|
1059 // Unexpected transaction type, so we do not know what to do with it |
|
1060 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::TransactionHandledAtSsy - ERROR: Invalid transaction type" ) ) ); |
|
1061 User::Panic(KSensrvPanicCategory, ESensrvPanicUnknownTransactionType); |
|
1062 break; |
|
1063 } |
|
1064 |
|
1065 // Complete the transaction |
|
1066 iTransactionMonitor->RemoveTransaction(aTransaction); |
|
1067 iLoadWaitQueue->Remove(aTransaction, CSensrvTransactionQueue::ERemovalTypeComplete); |
|
1068 |
|
1069 // Handle next transaction. |
|
1070 HandleNextTransaction(); |
|
1071 |
|
1072 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CompleteTransaction - return" ) ) ); |
|
1073 } |
|
1074 |
|
1075 // --------------------------------------------------------------------------- |
|
1076 // Goes through channel infos and returns pointer to one that matches given id. |
|
1077 // --------------------------------------------------------------------------- |
|
1078 // |
|
1079 TSensrvResourceChannelInfo* CSensrvPluginProxy::GetChannelInfoForId( TSensrvChannelId aChannelId ) |
|
1080 { |
|
1081 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetChannelInfoForId(aChannelId: %d)" ), aChannelId ) ); |
|
1082 |
|
1083 TSensrvResourceChannelInfo* info = NULL;; |
|
1084 |
|
1085 if (iIsInitialized) |
|
1086 { |
|
1087 TBool found(EFalse); |
|
1088 TInt channelCount = iChannelInfoList.Count(); |
|
1089 if (channelCount > 0) |
|
1090 { |
|
1091 for(TInt j = 0; !found && j < channelCount; j++) |
|
1092 { |
|
1093 if (iChannelInfoList[j].iChannelId == aChannelId) |
|
1094 { |
|
1095 info = &iChannelInfoList[j]; |
|
1096 found = ETrue; |
|
1097 } |
|
1098 } |
|
1099 } |
|
1100 } |
|
1101 else |
|
1102 { |
|
1103 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetChannelInfoForId - Proxy not yet initialized" ) ) ); |
|
1104 } |
|
1105 |
|
1106 |
|
1107 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetChannelInfoForId - return 0x%x" ), info ) ); |
|
1108 |
|
1109 return info; |
|
1110 } |
|
1111 |
|
1112 // --------------------------------------------------------------------------- |
|
1113 // Set plugin state |
|
1114 // --------------------------------------------------------------------------- |
|
1115 // |
|
1116 void CSensrvPluginProxy::SetPluginState(TPluginState aState) |
|
1117 { |
|
1118 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SetPluginState(aState: %d)" ), aState ) ); |
|
1119 |
|
1120 iPluginState = aState; |
|
1121 } |
|
1122 |
|
1123 // --------------------------------------------------------------------------- |
|
1124 // Gets total listener count from all channels |
|
1125 // --------------------------------------------------------------------------- |
|
1126 // |
|
1127 TInt CSensrvPluginProxy::GetTotalListenerCount() |
|
1128 { |
|
1129 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetTotalListenerCount()" ) ) ); |
|
1130 |
|
1131 TInt channelCount(iChannelList.Count()); |
|
1132 TInt listenerCount(0); |
|
1133 |
|
1134 for(TInt i = 0; i < channelCount; i ++) |
|
1135 { |
|
1136 listenerCount += iChannelList[i]->ListenerCount(); |
|
1137 } |
|
1138 |
|
1139 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::GetTotalListenerCount - return: %d" ), listenerCount ) ); |
|
1140 |
|
1141 return listenerCount; |
|
1142 } |
|
1143 |
|
1144 // --------------------------------------------------------------------------- |
|
1145 // Grabs raw channel info data from SSY mediator and |
|
1146 // Updates channel info and removed channel info lists. |
|
1147 // --------------------------------------------------------------------------- |
|
1148 // |
|
1149 TInt CSensrvPluginProxy::UpdateChannelInfoLists() |
|
1150 { |
|
1151 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists()" ) ) ); |
|
1152 |
|
1153 TInt err(KErrNone); |
|
1154 |
|
1155 // Get new info into a temporary array. |
|
1156 RSensrvChannelInfoList newInfos; |
|
1157 |
|
1158 TAny** rawDataPtr = iSsyMediator->RawInfos(); |
|
1159 |
|
1160 if (*rawDataPtr) |
|
1161 { |
|
1162 // First item in raw data is count |
|
1163 TInt* countPointer = reinterpret_cast<TInt*>(*rawDataPtr); |
|
1164 |
|
1165 if (*countPointer > 0) |
|
1166 { |
|
1167 err = newInfos.Reserve(*countPointer); |
|
1168 |
|
1169 // Data starts after count |
|
1170 TSensrvChannelInfo* info = reinterpret_cast<TSensrvChannelInfo*>(countPointer + 1); |
|
1171 |
|
1172 // Loop through raw data, appending datas to info list |
|
1173 for (TInt newLoop = 0; err == KErrNone && newLoop < *countPointer; newLoop++) |
|
1174 { |
|
1175 err = newInfos.Append(*info++); |
|
1176 if (err != KErrNone) |
|
1177 { |
|
1178 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - ERROR: newInfos.Append failure: %d, count: %d" ), err, newLoop ) ); |
|
1179 newInfos.Reset(); |
|
1180 } |
|
1181 } |
|
1182 } |
|
1183 |
|
1184 // Free memory allocated by SSY mediator and set mediator's pointer to raw data to NULL |
|
1185 iProxyManager.ServerHeap()->Free(*rawDataPtr); |
|
1186 *rawDataPtr = NULL; |
|
1187 } |
|
1188 else |
|
1189 { |
|
1190 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - No channels registered by SSY" ) ) ); |
|
1191 } |
|
1192 |
|
1193 #ifdef COMPONENT_TRACE_DEBUG |
|
1194 COMPONENT_TRACE( ( _L( "### Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists, initial channel lists:" )) ); |
|
1195 |
|
1196 COMPONENT_TRACE( ( _L( "### newInfos contents:" )) ); |
|
1197 iProxyManager.TraceChannelInfoList(newInfos); |
|
1198 |
|
1199 COMPONENT_TRACE( ( _L( "### iChannelInfoList contents:" )) ); |
|
1200 iProxyManager.TraceChannelInfoList(iChannelInfoList); |
|
1201 |
|
1202 COMPONENT_TRACE( ( _L( "### iRemovedChannelsInfoList contents:" )) ); |
|
1203 iProxyManager.TraceChannelInfoList(iRemovedChannelsInfoList); |
|
1204 #endif |
|
1205 |
|
1206 // Compare old infos to new infos and notify removals to sessions, |
|
1207 // add removed infos to iRemovedChannelsInfoList, |
|
1208 // destroy CSensrvChannel objects of removed channelsm, and |
|
1209 // remove old infos from iChannelInfoList. |
|
1210 for (TInt oldLoop = iChannelInfoList.Count() - 1; err == KErrNone && oldLoop >= 0 ; oldLoop--) |
|
1211 { |
|
1212 // If match was not found, this channel has been removed |
|
1213 const TSensrvChannelInfo& oldInfo(iChannelInfoList[oldLoop]); |
|
1214 TInt index = FindChannel(newInfos, oldInfo); |
|
1215 if (index == KErrNotFound) |
|
1216 { |
|
1217 // Notify interested sessions |
|
1218 iProxyManager.NotifyChannelChange(oldInfo, ESensrvChannelChangeTypeRemoved); |
|
1219 |
|
1220 // Add info to removed infos. |
|
1221 err = iRemovedChannelsInfoList.Append(oldInfo); |
|
1222 if (err != KErrNone) |
|
1223 { |
|
1224 // Error is ignored as we cannot do anything about this. It results in channel id |
|
1225 // being regenerated to this channel if it is readded later, which is inconvenient, but |
|
1226 // not critical. |
|
1227 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - ERROR: iRemovedChannelsInfoList.Append failure: %d, count: %d" ), err, oldLoop ) ); |
|
1228 } |
|
1229 |
|
1230 // Destroy and remove from channel list the related channel object as it is obsolete. |
|
1231 TInt channelCount = iChannelList.Count(); |
|
1232 for(TInt i = 0; i < channelCount; i++) |
|
1233 { |
|
1234 if (iChannelList[i]->Id() == oldInfo.iChannelId) |
|
1235 { |
|
1236 delete iChannelList[i]; |
|
1237 iChannelList.Remove(i); |
|
1238 break; |
|
1239 } |
|
1240 } |
|
1241 |
|
1242 // Remove channel info from iChannelInfoList |
|
1243 iChannelInfoList.Remove(oldLoop); |
|
1244 } |
|
1245 } |
|
1246 |
|
1247 // Compare new infos to old infos and notify additions to sessions, |
|
1248 // remove added infos from iRemovedChannelsInfoList if they are there, and |
|
1249 // append new infos to iChannelInfoList. |
|
1250 TInt newCount = newInfos.Count(); |
|
1251 for (TInt newLoop = 0; err == KErrNone && newLoop < newCount; newLoop++) |
|
1252 { |
|
1253 const TSensrvChannelInfo& newInfo(newInfos[newLoop]); |
|
1254 TInt index = FindChannel(newInfo, iChannelInfoList); |
|
1255 if (index >= 0 && index < iChannelInfoList.Count()) |
|
1256 { |
|
1257 // Update silently the actual data item size from SSY channel registration if still unset |
|
1258 TSensrvChannelInfo& oldInfo(iChannelInfoList[index]); |
|
1259 if (oldInfo.iDataItemSize <= 0 && newInfo.iDataItemSize > 0) |
|
1260 { |
|
1261 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - channel %d, new data item size: %d" ), |
|
1262 oldInfo.iChannelId, newInfo.iDataItemSize ) ); |
|
1263 oldInfo.iDataItemSize = newInfo.iDataItemSize; |
|
1264 } |
|
1265 } |
|
1266 else |
|
1267 { |
|
1268 TSensrvResourceChannelInfo newResourceInfo(newInfo); |
|
1269 |
|
1270 // Store dynamic channel status |
|
1271 newResourceInfo.iDynamic = FindChannel(newInfo, iDynamicChannelInfoList) != KErrNotFound; // Store dynamic status |
|
1272 |
|
1273 err = iChannelInfoList.Append(newResourceInfo); |
|
1274 if (err == KErrNone) |
|
1275 { |
|
1276 // Notify interested sessions |
|
1277 iProxyManager.NotifyChannelChange(newInfo, ESensrvChannelChangeTypeAdded); |
|
1278 |
|
1279 // Remove from iRemovedChannelsInfoList, in case there has been this channel previously |
|
1280 index = FindChannel(newInfo, iRemovedChannelsInfoList); |
|
1281 if(index >= 0 && index < iRemovedChannelsInfoList.Count()) |
|
1282 { |
|
1283 iRemovedChannelsInfoList.Remove(index); |
|
1284 } |
|
1285 } |
|
1286 else |
|
1287 { |
|
1288 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - ERROR: iChannelInfoList.Append failure: %d, count: %d" ), err, newLoop ) ); |
|
1289 } |
|
1290 } |
|
1291 } |
|
1292 |
|
1293 // Note: It might be slightly more efficient to simply reset the iChannelInfoList and |
|
1294 // repopulate it with newInfos content as opposed to explicit appends and removes |
|
1295 // above, but that would create a risk that iChannelInfoList was left empty in |
|
1296 // case append fails to allocate new memory. Since there is no way to resurrect |
|
1297 // proxy with no channels once it has been unloaded, this is not acceptable. |
|
1298 |
|
1299 #ifdef COMPONENT_TRACE_DEBUG |
|
1300 COMPONENT_TRACE( ( _L( "### " )) ); |
|
1301 COMPONENT_TRACE( ( _L( "### Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists, after changes" )) ); |
|
1302 |
|
1303 COMPONENT_TRACE( ( _L( "### iChannelInfoList contents (should be same as newInfos):" )) ); |
|
1304 iProxyManager.TraceChannelInfoList(iChannelInfoList); |
|
1305 |
|
1306 COMPONENT_TRACE( ( _L( "### iRemovedChannelsInfoList contents (should have infos removed from iChannelInfoList added to it):" )) ); |
|
1307 iProxyManager.TraceChannelInfoList(iRemovedChannelsInfoList); |
|
1308 #endif |
|
1309 |
|
1310 // Cleanup newinfos |
|
1311 newInfos.Close(); |
|
1312 |
|
1313 if (iDeletionFlag) |
|
1314 { |
|
1315 // Cleanup bad proxy after its channels have been removed |
|
1316 CleanupPlugin(); |
|
1317 } |
|
1318 |
|
1319 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::UpdateChannelInfoLists - return: %d" ), err ) ); |
|
1320 |
|
1321 return err; |
|
1322 } |
|
1323 |
|
1324 |
|
1325 // --------------------------------------------------------------------------- |
|
1326 // SSY thread main function. |
|
1327 // Creates new active scheduler and cleanup stack and installs those. |
|
1328 // Initializes SSY mediator. |
|
1329 // Starts the new active scheduler. |
|
1330 // --------------------------------------------------------------------------- |
|
1331 // |
|
1332 TInt CSensrvPluginProxy::SsyThreadFunction( TAny* aParameter ) |
|
1333 { |
|
1334 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SsyThreadFunction(aParameter: 0x%x)" ), aParameter ) ); |
|
1335 |
|
1336 if (!aParameter) |
|
1337 { |
|
1338 ERROR_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - ERROR: NULL proxy, cannot start thread." ) ) ); |
|
1339 return KErrBadHandle; |
|
1340 } |
|
1341 |
|
1342 __UHEAP_MARK; |
|
1343 |
|
1344 #ifdef MEMORY_TRACE_DEBUG |
|
1345 // TRACE heap usage |
|
1346 TInt heapSize = User::Heap().Size(); |
|
1347 TInt biggestBlock(0); |
|
1348 TInt heapAvail = User::Heap().Available(biggestBlock); |
|
1349 TInt used(heapSize-heapAvail); |
|
1350 MEMORY_TRACE( ( _L( "#### Sensor Server, SSY starting - HEAP: Size: %d, Available: %d, Used: %d" ), heapSize, heapAvail, used ) ); |
|
1351 #endif |
|
1352 |
|
1353 CSensrvPluginProxy* proxy = static_cast<CSensrvPluginProxy*>(aParameter); |
|
1354 |
|
1355 TInt err(KErrNone); |
|
1356 |
|
1357 // Create new cleanup stack |
|
1358 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
1359 |
|
1360 if ( cleanup ) |
|
1361 { |
|
1362 // Create and install the active scheduler we need |
|
1363 CSensrvSsyActiveScheduler* scheduler = NULL; |
|
1364 TRAP(err, scheduler = CSensrvSsyActiveScheduler::NewL()); |
|
1365 |
|
1366 if (err == KErrNone) |
|
1367 { |
|
1368 CActiveScheduler::Install( scheduler ); |
|
1369 |
|
1370 proxy->Mutex().Wait(); |
|
1371 |
|
1372 COMPONENT_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - Started thread for plugin UID: 0x%x" ), proxy->iImplementationUid.iUid) ); |
|
1373 |
|
1374 // initialize SSY mediator |
|
1375 err = proxy->SsyMediator()->Initialize(); |
|
1376 |
|
1377 if (err == KErrNone) |
|
1378 { |
|
1379 // Initial notify to server mediator via null transaction |
|
1380 // Notifying NULL transaction cannot fail, so no error handling |
|
1381 proxy->ServerMediator()->Notify(NULL); |
|
1382 |
|
1383 proxy->Mutex().Signal(); |
|
1384 |
|
1385 COMPONENT_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - Starting scheduler" )) ); |
|
1386 |
|
1387 CActiveScheduler::Start(); |
|
1388 |
|
1389 COMPONENT_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - Scheduler stopped" )) ); |
|
1390 |
|
1391 // Signal final closure of ecom session for SSY thread |
|
1392 REComSession::FinalClose(); |
|
1393 } |
|
1394 else |
|
1395 { |
|
1396 ERROR_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - ERROR: Failed to initialize SSY mediator, cannot start thread: %d." ),err ) ); |
|
1397 proxy->Mutex().Signal(); |
|
1398 } |
|
1399 |
|
1400 // Cleanup |
|
1401 delete scheduler; |
|
1402 scheduler = NULL; |
|
1403 } |
|
1404 else |
|
1405 { |
|
1406 ERROR_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - ERROR: Failed to create scheduler, cannot start thread: %d." ),err ) ); |
|
1407 } |
|
1408 |
|
1409 delete cleanup; |
|
1410 cleanup = NULL; |
|
1411 } |
|
1412 else |
|
1413 { |
|
1414 ERROR_TRACE( ( _L( "Sensor Server - SsyThreadFunction() - ERROR: No memory to create cleanup stack, cannot start thread." ) ) ); |
|
1415 err = KErrNoMemory; |
|
1416 } |
|
1417 |
|
1418 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::SsyThreadFunction - return" ) ) ); |
|
1419 |
|
1420 #ifdef MEMORY_TRACE_DEBUG |
|
1421 // TRACE heap usage |
|
1422 heapSize = User::Heap().Size(); |
|
1423 heapAvail = User::Heap().Available(biggestBlock); |
|
1424 TInt newUsed(heapSize-heapAvail); |
|
1425 MEMORY_TRACE( ( _L( "#### Sensor Server, SSY exit - HEAP: Size: %d, Available: %d, Used: %d, Change in used: %d" ), heapSize, heapAvail, newUsed, newUsed - used ) ); |
|
1426 #endif |
|
1427 |
|
1428 __UHEAP_MARKEND; |
|
1429 |
|
1430 return err; |
|
1431 } |
|
1432 |
|
1433 // --------------------------------------------------------------------------- |
|
1434 // Cleanup item implementation for plugin initialization |
|
1435 // --------------------------------------------------------------------------- |
|
1436 // |
|
1437 void CSensrvPluginProxy::CleanupInitializePlugin( TAny* aAny ) |
|
1438 { |
|
1439 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CleanupInitializePlugin()" ) ) ); |
|
1440 |
|
1441 CSensrvPluginProxy* proxy = reinterpret_cast<CSensrvPluginProxy*>(aAny); |
|
1442 |
|
1443 if (proxy) |
|
1444 { |
|
1445 // Uninitialized RThread object also has valid handle to current thread |
|
1446 if (proxy->iSsyThread.Handle() && proxy->iSsyThread.Handle() != RThread().Handle()) |
|
1447 { |
|
1448 proxy->iSsyThread.Terminate(KErrCancel); |
|
1449 proxy->iSsyThread.Close(); |
|
1450 } |
|
1451 |
|
1452 // Clean up any pending channel open messages |
|
1453 proxy->iLoadWaitQueue->RemoveAll(); |
|
1454 proxy->iPreviousSsyLoadFailed = ETrue; |
|
1455 proxy->Mutex().Signal(); |
|
1456 } |
|
1457 |
|
1458 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::CleanupInitializePlugin - return" ) ) ); |
|
1459 } |
|
1460 |
|
1461 // --------------------------------------------------------------------------- |
|
1462 // Finds channel from info list that matches to given channel info |
|
1463 // --------------------------------------------------------------------------- |
|
1464 // |
|
1465 TInt CSensrvPluginProxy::FindChannel( const TSensrvChannelInfo& aChannelInfo, |
|
1466 const RSensrvResourceChannelInfoList& aChannelInfoList ) |
|
1467 { |
|
1468 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::FindChannel (RSensrvResourceChannelInfoList)" ) ) ); |
|
1469 |
|
1470 TInt index = aChannelInfoList.Find(aChannelInfo, TSensrvResourceChannelInfo::CompareFindMatch); |
|
1471 |
|
1472 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::FindChannel - index %d, return" ), index ) ); |
|
1473 |
|
1474 return index; |
|
1475 } |
|
1476 |
|
1477 // --------------------------------------------------------------------------- |
|
1478 // Finds channel from info list that matches to given channel info |
|
1479 // --------------------------------------------------------------------------- |
|
1480 // |
|
1481 TInt CSensrvPluginProxy::FindChannel( const RSensrvChannelInfoList& aChannelInfoList, |
|
1482 const TSensrvChannelInfo& aChannelInfo ) |
|
1483 { |
|
1484 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::FindChannel (RSensrvChannelInfoList) Reverse" ) ) ); |
|
1485 |
|
1486 TInt index = aChannelInfoList.Find(aChannelInfo, TSensrvResourceChannelInfo::CompareFindMatchReverse); |
|
1487 |
|
1488 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::FindChannel - index %d, return" ), index ) ); |
|
1489 |
|
1490 return index; |
|
1491 } |
|
1492 |
|
1493 // --------------------------------------------------------------------------- |
|
1494 // Increments dynamic channel change listener count |
|
1495 // --------------------------------------------------------------------------- |
|
1496 // |
|
1497 void CSensrvPluginProxy::AddChannelChangeListener() |
|
1498 { |
|
1499 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::AddChannelChangeListener" ) ) ); |
|
1500 |
|
1501 ++iChannelChangeListenerCount; |
|
1502 StopUnloadTimer(); |
|
1503 |
|
1504 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::AddChannelChangeListener - count %d return " ), |
|
1505 iChannelChangeListenerCount ) ); |
|
1506 } |
|
1507 |
|
1508 // --------------------------------------------------------------------------- |
|
1509 // Decrements dynamic channel change listener count |
|
1510 // --------------------------------------------------------------------------- |
|
1511 // |
|
1512 void CSensrvPluginProxy::RemoveChannelChangeListener() |
|
1513 { |
|
1514 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::RemoveChannelChangeListener" ) ) ); |
|
1515 |
|
1516 if (iChannelChangeListenerCount > 0) |
|
1517 { |
|
1518 --iChannelChangeListenerCount; |
|
1519 if (!iChannelChangeListenerCount) |
|
1520 { |
|
1521 StartUnloadTimerIfNeeded(); |
|
1522 } |
|
1523 } |
|
1524 else |
|
1525 { |
|
1526 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::RemoveChannelChangeListener - ERROR: count corrupt" ) ) ); |
|
1527 } |
|
1528 |
|
1529 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::RemoveChannelChangeListener - count %d return " ), |
|
1530 iChannelChangeListenerCount ) ); |
|
1531 } |
|
1532 |
|
1533 // --------------------------------------------------------------------------- |
|
1534 // Enqueues delayed initialize transaction |
|
1535 // --------------------------------------------------------------------------- |
|
1536 // |
|
1537 TInt CSensrvPluginProxy::EnqueueDelayedInitializeTransaction() |
|
1538 { |
|
1539 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::EnqueueDelayedInitializeTransaction" ) ) ); |
|
1540 |
|
1541 TInt err = KErrNone; |
|
1542 |
|
1543 // Enqueue initialization transaction if queue is empty. |
|
1544 if (iLoadWaitQueue->IsEmpty()) |
|
1545 { |
|
1546 CSensrvTransaction* transaction = NULL; |
|
1547 TRAP(err, transaction = CSensrvTransaction::NewL( |
|
1548 NULL, this, NULL, CSensrvTransaction::ETransTypeDelayedInitialize)); |
|
1549 if (err == KErrNone) |
|
1550 { |
|
1551 err = QueueTransaction(transaction, EFalse); |
|
1552 if (err != KErrNone) |
|
1553 { |
|
1554 delete transaction; |
|
1555 transaction = NULL; |
|
1556 } |
|
1557 } |
|
1558 else |
|
1559 { |
|
1560 ERROR_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::EnqueueDelayedInitializeTransaction - ERROR: Failed to create transaction err: %d" ), err ) ); |
|
1561 } |
|
1562 } |
|
1563 |
|
1564 COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPluginProxy::EnqueueDelayedInitializeTransaction - return" ) ) ); |
|
1565 |
|
1566 return err; |
|
1567 } |