|
1 /* |
|
2 * Copyright (c) 2007 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: Command scheduler. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include "alfcommandscheduler.h" |
|
21 #include "alf/alfcommand.h" |
|
22 #include "alflogger.h" |
|
23 |
|
24 #include <uiacceltk/HuiUtil.h> |
|
25 |
|
26 // Internal flags. |
|
27 enum TAlfSchedulerFlags |
|
28 { |
|
29 EAlfSchedulerPrimaryLightsOn = 0x01, |
|
30 EAlfSchedulerSecondaryLightsOn = 0x02, |
|
31 EAlfSchedulerApplicationForeground = 0x04, |
|
32 EAlfSchedulerRunning = 0x08 |
|
33 }; |
|
34 |
|
35 // ======== CTimedEvent MEMBER FUNCTIONS ======== |
|
36 |
|
37 // --------------------------------------------------------------------------- |
|
38 // NewLC |
|
39 // --------------------------------------------------------------------------- |
|
40 // |
|
41 CAlfCommandScheduler::CTimedEvent* CAlfCommandScheduler::CTimedEvent::NewLC( |
|
42 const TAlfCommand& aCommand, |
|
43 CAlfCommandScheduler& aScheduler ) |
|
44 { |
|
45 CTimedEvent* self = new (ELeave) CTimedEvent(aScheduler); |
|
46 CleanupStack::PushL( self ); |
|
47 self->ConstructL( aCommand ); |
|
48 return self; |
|
49 } |
|
50 |
|
51 // --------------------------------------------------------------------------- |
|
52 // Destructor |
|
53 // --------------------------------------------------------------------------- |
|
54 // |
|
55 CAlfCommandScheduler::CTimedEvent::~CTimedEvent() |
|
56 { |
|
57 Cancel(); |
|
58 delete iCommand; |
|
59 } |
|
60 |
|
61 // --------------------------------------------------------------------------- |
|
62 // Constructor |
|
63 // --------------------------------------------------------------------------- |
|
64 // |
|
65 CAlfCommandScheduler::CTimedEvent::CTimedEvent( CAlfCommandScheduler& aScheduler ) |
|
66 : CTimer( EPriorityStandard ), iScheduler( aScheduler ) |
|
67 { |
|
68 CActiveScheduler::Add( this ); |
|
69 } |
|
70 |
|
71 // --------------------------------------------------------------------------- |
|
72 // ConstructL |
|
73 // --------------------------------------------------------------------------- |
|
74 // |
|
75 void CAlfCommandScheduler::CTimedEvent::ConstructL(const TAlfCommand& aCommand) |
|
76 { |
|
77 CTimer::ConstructL(); |
|
78 |
|
79 // Make a copy of the command. |
|
80 TAlfCommand* data = (TAlfCommand*) new (ELeave) TUint8[aCommand.Size()]; |
|
81 Mem::Copy((TAny*)data, (TAny*)&aCommand, aCommand.Size()); |
|
82 iCommand = data; |
|
83 } |
|
84 |
|
85 // --------------------------------------------------------------------------- |
|
86 // Called when timer triggers. |
|
87 // --------------------------------------------------------------------------- |
|
88 // |
|
89 void CAlfCommandScheduler::CTimedEvent::RunL() |
|
90 { |
|
91 iScheduler.ExecuteEventL( *iCommand ); |
|
92 delete this; |
|
93 } |
|
94 |
|
95 // --------------------------------------------------------------------------- |
|
96 // Called when RunL leaves |
|
97 // --------------------------------------------------------------------------- |
|
98 // |
|
99 TInt CAlfCommandScheduler::CTimedEvent::RunError(TInt aError) |
|
100 { |
|
101 __ALFLOGSTRING1( "CAlfCommandScheduler::ExecuteEventL leaves with %d", aError ) |
|
102 delete this; |
|
103 return aError; |
|
104 } |
|
105 |
|
106 // --------------------------------------------------------------------------- |
|
107 // Execute command after given timed. |
|
108 // --------------------------------------------------------------------------- |
|
109 // |
|
110 void CAlfCommandScheduler::CTimedEvent::ExecuteAfter( |
|
111 TInt aIntervalInMilliSeconds, |
|
112 TBool aStartPaused ) |
|
113 { |
|
114 __ASSERT_ALWAYS( !IsActive(), USER_INVARIANT() ); |
|
115 iTimeLeftInMilliSeconds = aIntervalInMilliSeconds; |
|
116 |
|
117 // If the scheduler is not paused... |
|
118 if ( !aStartPaused ) |
|
119 { |
|
120 // ...start the timer. |
|
121 After( aIntervalInMilliSeconds * 1000 ); |
|
122 iLastStartTime.UniversalTime(); // Update the start-time stamp. |
|
123 } |
|
124 } |
|
125 |
|
126 // --------------------------------------------------------------------------- |
|
127 // Pauses the time |
|
128 // --------------------------------------------------------------------------- |
|
129 // |
|
130 void CAlfCommandScheduler::CTimedEvent::Pause() |
|
131 { |
|
132 // If not paused... |
|
133 if ( IsActive() ) |
|
134 { |
|
135 // ... cancel the timer and update the time left. |
|
136 Cancel(); |
|
137 TTime timeNow; |
|
138 timeNow.UniversalTime(); |
|
139 iTimeLeftInMilliSeconds -= |
|
140 timeNow.MicroSecondsFrom( iLastStartTime ).Int64()/1000; |
|
141 } |
|
142 } |
|
143 |
|
144 // --------------------------------------------------------------------------- |
|
145 // Continue timer. |
|
146 // --------------------------------------------------------------------------- |
|
147 // |
|
148 void CAlfCommandScheduler::CTimedEvent::Continue() |
|
149 { |
|
150 // If not running... |
|
151 if ( !IsActive() ) |
|
152 { |
|
153 // ... execute the event... |
|
154 if ( iTimeLeftInMilliSeconds <= 0 ) |
|
155 { |
|
156 // ...now |
|
157 TRAP_IGNORE(iScheduler.ExecuteEventL( *iCommand )) |
|
158 delete this; |
|
159 } |
|
160 else |
|
161 { |
|
162 // ...after the time left. |
|
163 After( iTimeLeftInMilliSeconds * 1000 ); |
|
164 iLastStartTime.UniversalTime(); // Update the start-time stamp. |
|
165 } |
|
166 } |
|
167 } |
|
168 |
|
169 // --------------------------------------------------------------------------- |
|
170 // Calculates the time left. |
|
171 // --------------------------------------------------------------------------- |
|
172 // |
|
173 TInt CAlfCommandScheduler::CTimedEvent::TimeLeftInMilliSeconds() const |
|
174 { |
|
175 TInt timeLeftInMilliSeconds = 0; |
|
176 if ( IsActive() ) |
|
177 { |
|
178 TTime timeNow; |
|
179 timeNow.UniversalTime(); |
|
180 timeLeftInMilliSeconds = |
|
181 iTimeLeftInMilliSeconds - |
|
182 timeNow.MicroSecondsFrom( iLastStartTime ).Int64()/1000; |
|
183 } |
|
184 else |
|
185 { |
|
186 timeLeftInMilliSeconds = iTimeLeftInMilliSeconds; |
|
187 } |
|
188 |
|
189 if ( timeLeftInMilliSeconds < 0 ) |
|
190 { |
|
191 timeLeftInMilliSeconds = 0; |
|
192 } |
|
193 return timeLeftInMilliSeconds; |
|
194 } |
|
195 |
|
196 // ======== CAlfCommandScheduler MEMBER FUNCTIONS ======== |
|
197 |
|
198 // --------------------------------------------------------------------------- |
|
199 // NewL |
|
200 // --------------------------------------------------------------------------- |
|
201 // |
|
202 CAlfCommandScheduler* CAlfCommandScheduler::NewL( CAlfEnv& aEnv) |
|
203 { |
|
204 CAlfCommandScheduler* self = new (ELeave) CAlfCommandScheduler( aEnv ); |
|
205 CleanupStack::PushL( self ); |
|
206 self->ConstructL(); |
|
207 CleanupStack::Pop( self ); |
|
208 return self; |
|
209 } |
|
210 |
|
211 // --------------------------------------------------------------------------- |
|
212 // Constructor |
|
213 // --------------------------------------------------------------------------- |
|
214 // |
|
215 CAlfCommandScheduler::CAlfCommandScheduler( CAlfEnv& aEnv) |
|
216 : iEnv(aEnv) |
|
217 { |
|
218 } |
|
219 |
|
220 // --------------------------------------------------------------------------- |
|
221 // ConstructL |
|
222 // Update internal flags. |
|
223 // --------------------------------------------------------------------------- |
|
224 // |
|
225 void CAlfCommandScheduler::ConstructL() |
|
226 { |
|
227 iLight = CHWRMLight::NewL(this); // Calls LightStatusChanged() |
|
228 |
|
229 iFlags |= EAlfSchedulerApplicationForeground; |
|
230 iFlags |= EAlfSchedulerRunning; |
|
231 |
|
232 // Workaround for non-working light status reports |
|
233 iFlags |= EAlfSchedulerPrimaryLightsOn; |
|
234 } |
|
235 |
|
236 // --------------------------------------------------------------------------- |
|
237 // Destructor |
|
238 // --------------------------------------------------------------------------- |
|
239 // |
|
240 CAlfCommandScheduler::~CAlfCommandScheduler() |
|
241 { |
|
242 iEvents.ResetAndDestroy(); |
|
243 delete iLight; |
|
244 } |
|
245 |
|
246 // --------------------------------------------------------------------------- |
|
247 // Executes given command after given time |
|
248 // --------------------------------------------------------------------------- |
|
249 // |
|
250 void CAlfCommandScheduler::ScheduleCommandL( |
|
251 const TAlfCommand& aCommand, |
|
252 TInt aTimeInMilliSeconds ) |
|
253 { |
|
254 if (aTimeInMilliSeconds == 0) |
|
255 { |
|
256 __ALFLOGSTRING( "CAlfCommandScheduler::ScheduleCommandL execute now" ) |
|
257 // Execute now |
|
258 aCommand.ExecuteL( iEnv ); |
|
259 return; |
|
260 } |
|
261 |
|
262 // Create timed event |
|
263 __ALFLOGSTRING1( "CAlfCommandScheduler::ScheduleCommandL in %dms", aTimeInMilliSeconds ) |
|
264 CTimedEvent* event = CTimedEvent::NewLC( aCommand, *this ); |
|
265 iEvents.AppendL( event ); |
|
266 CleanupStack::Pop( event ); |
|
267 event->ExecuteAfter( aTimeInMilliSeconds, !(iFlags&EAlfSchedulerRunning) ); |
|
268 } |
|
269 |
|
270 // --------------------------------------------------------------------------- |
|
271 // Cancel all object commands. |
|
272 // --------------------------------------------------------------------------- |
|
273 // |
|
274 void CAlfCommandScheduler::CancelCommands( TAny* aObject ) |
|
275 { |
|
276 for ( TInt i = iEvents.Count() - 1; i >= 0; i--) |
|
277 { |
|
278 const TAlfObjectCommand* objectCommand = |
|
279 iEvents[i]->iCommand->ObjectCommand(); |
|
280 if(objectCommand && objectCommand->Object() == aObject) |
|
281 { |
|
282 delete iEvents[i]; |
|
283 iEvents.Remove( i ); |
|
284 } |
|
285 } |
|
286 iEvents.Compress(); |
|
287 } |
|
288 |
|
289 // --------------------------------------------------------------------------- |
|
290 // Cancels specific operation for given object |
|
291 // --------------------------------------------------------------------------- |
|
292 // |
|
293 void CAlfCommandScheduler::CancelCommands(TAny* aObject, TAlfOp aCommandOperation) |
|
294 { |
|
295 for(TInt i = iEvents.Count() - 1; i >= 0; --i) |
|
296 { |
|
297 const TAlfObjectCommand* objectCommand = |
|
298 iEvents[i]->iCommand->ObjectCommand(); |
|
299 if(objectCommand && |
|
300 objectCommand->Object() == aObject && |
|
301 objectCommand->Operation() == aCommandOperation) |
|
302 { |
|
303 // Cancel this one. |
|
304 delete iEvents[i]; |
|
305 iEvents.Remove( i ); |
|
306 } |
|
307 } |
|
308 iEvents.Compress(); |
|
309 } |
|
310 |
|
311 // --------------------------------------------------------------------------- |
|
312 // Cancels given command types from given object |
|
313 // --------------------------------------------------------------------------- |
|
314 // |
|
315 void CAlfCommandScheduler::CancelCommands(TAny* aObject, |
|
316 TAlfCommandType aCommandType, |
|
317 TInt aParam) |
|
318 { |
|
319 for(TInt i = iEvents.Count() - 1; i >= 0; --i) |
|
320 { |
|
321 const TAlfObjectCommand* objectCommand = |
|
322 iEvents[i]->iCommand->ObjectCommand(); |
|
323 |
|
324 if(objectCommand && |
|
325 objectCommand->Object() == aObject && |
|
326 objectCommand->Type() == aCommandType) |
|
327 { |
|
328 if(objectCommand->Type() == EAlfCommandTypeCustomEvent) |
|
329 { |
|
330 const TAlfCustomEventCommand* cec = |
|
331 (const TAlfCustomEventCommand*) objectCommand; |
|
332 |
|
333 if(cec->Param() != aParam) |
|
334 { |
|
335 // Not this one, wrong parameter. |
|
336 continue; |
|
337 } |
|
338 } |
|
339 // Cancel this one. |
|
340 delete iEvents[i]; |
|
341 iEvents.Remove( i ); |
|
342 } |
|
343 } |
|
344 |
|
345 iEvents.Compress(); |
|
346 } |
|
347 |
|
348 // --------------------------------------------------------------------------- |
|
349 // Returns time left ot the command |
|
350 // --------------------------------------------------------------------------- |
|
351 // |
|
352 TInt CAlfCommandScheduler::MilliSecondsUntilCommand( |
|
353 TAny* aObject ) |
|
354 { |
|
355 TInt returnValue = KErrNotFound; |
|
356 |
|
357 for ( TInt i = iEvents.Count() - 1; i >= 0; i--) |
|
358 { |
|
359 const TAlfObjectCommand* objectCommand = |
|
360 iEvents[i]->iCommand->ObjectCommand(); |
|
361 if(objectCommand && objectCommand->Object() == aObject) |
|
362 { |
|
363 TInt timeLeft = iEvents[i]->TimeLeftInMilliSeconds(); |
|
364 if ( returnValue == KErrNotFound || timeLeft < returnValue ) |
|
365 { |
|
366 returnValue = timeLeft; |
|
367 } |
|
368 } |
|
369 } |
|
370 |
|
371 return returnValue; |
|
372 } |
|
373 |
|
374 // --------------------------------------------------------------------------- |
|
375 // Returns time left ot the command |
|
376 // --------------------------------------------------------------------------- |
|
377 // |
|
378 TInt CAlfCommandScheduler::MilliSecondsUntilCommand( |
|
379 TAny* aObject, |
|
380 TAlfOp aCommandOperation ) |
|
381 { |
|
382 TInt returnValue = KErrNotFound; |
|
383 |
|
384 for(TInt i = iEvents.Count() - 1; i >= 0; --i) |
|
385 { |
|
386 const TAlfObjectCommand* objectCommand = |
|
387 iEvents[i]->iCommand->ObjectCommand(); |
|
388 if(objectCommand && |
|
389 objectCommand->Object() == aObject && |
|
390 objectCommand->Operation() == aCommandOperation) |
|
391 { |
|
392 TInt timeLeft = iEvents[i]->TimeLeftInMilliSeconds(); |
|
393 if ( returnValue == KErrNotFound || timeLeft < returnValue ) |
|
394 { |
|
395 returnValue = timeLeft; |
|
396 } |
|
397 } |
|
398 } |
|
399 |
|
400 return returnValue; |
|
401 } |
|
402 |
|
403 // --------------------------------------------------------------------------- |
|
404 // Returns time left ot the command |
|
405 // --------------------------------------------------------------------------- |
|
406 // |
|
407 TInt CAlfCommandScheduler::MilliSecondsUntilCommand( |
|
408 TAny* aObject, |
|
409 TAlfCommandType aCommandType, |
|
410 TInt aParam ) |
|
411 { |
|
412 TInt returnValue = KErrNotFound; |
|
413 |
|
414 for(TInt i = iEvents.Count() - 1; i >= 0; --i) |
|
415 { |
|
416 const TAlfObjectCommand* objectCommand = |
|
417 iEvents[i]->iCommand->ObjectCommand(); |
|
418 |
|
419 if(objectCommand && |
|
420 objectCommand->Object() == aObject && |
|
421 objectCommand->Type() == aCommandType) |
|
422 { |
|
423 if(objectCommand->Type() == EAlfCommandTypeCustomEvent) |
|
424 { |
|
425 const TAlfCustomEventCommand* cec = |
|
426 (const TAlfCustomEventCommand*) objectCommand; |
|
427 |
|
428 if(cec->Param() != aParam) |
|
429 { |
|
430 // Not this one, wrong parameter. |
|
431 continue; |
|
432 } |
|
433 } |
|
434 TInt timeLeft = iEvents[i]->TimeLeftInMilliSeconds(); |
|
435 if ( returnValue == KErrNotFound || timeLeft < returnValue ) |
|
436 { |
|
437 returnValue = timeLeft; |
|
438 } |
|
439 } |
|
440 } |
|
441 |
|
442 return returnValue; |
|
443 } |
|
444 |
|
445 // --------------------------------------------------------------------------- |
|
446 // Executes command |
|
447 // --------------------------------------------------------------------------- |
|
448 // |
|
449 void CAlfCommandScheduler::ExecuteEventL( TAlfCommand& aCommand ) |
|
450 { |
|
451 for ( TInt i = 0 ; i < iEvents.Count() ; i++ ) |
|
452 { |
|
453 if ( iEvents[i]->iCommand == &aCommand ) |
|
454 { |
|
455 iEvents.Remove( i ); |
|
456 iEvents.Compress(); |
|
457 break; |
|
458 } |
|
459 } |
|
460 |
|
461 aCommand.ExecuteL( iEnv ); |
|
462 } |
|
463 |
|
464 // --------------------------------------------------------------------------- |
|
465 // Called when foreground status changes. |
|
466 // --------------------------------------------------------------------------- |
|
467 // |
|
468 void CAlfCommandScheduler::AppicationOnForeground( TBool aForeground ) |
|
469 { |
|
470 if ( aForeground ) |
|
471 { |
|
472 iFlags |= EAlfSchedulerApplicationForeground; |
|
473 } |
|
474 else |
|
475 { |
|
476 iFlags &= ~EAlfSchedulerApplicationForeground; |
|
477 } |
|
478 |
|
479 UpdateSchedulerState(); |
|
480 } |
|
481 |
|
482 // --------------------------------------------------------------------------- |
|
483 // Called when display light status changes. |
|
484 // --------------------------------------------------------------------------- |
|
485 // |
|
486 void CAlfCommandScheduler::LightStatusChanged( |
|
487 TInt aTarget, |
|
488 CHWRMLight::TLightStatus aStatus ) |
|
489 { |
|
490 if( aTarget&CHWRMLight::EPrimaryDisplay ) |
|
491 { |
|
492 if( aStatus == CHWRMLight::ELightOn || |
|
493 aStatus == CHWRMLight::ELightStatusUnknown ) |
|
494 { |
|
495 iFlags |= EAlfSchedulerPrimaryLightsOn; |
|
496 } |
|
497 else if( aStatus == CHWRMLight::ELightOff ) |
|
498 { |
|
499 iFlags &= ~EAlfSchedulerPrimaryLightsOn; |
|
500 } |
|
501 else |
|
502 { |
|
503 // for PC lint |
|
504 } |
|
505 } |
|
506 |
|
507 if( aTarget&CHWRMLight::ESecondaryDisplay ) |
|
508 { |
|
509 if( aStatus == CHWRMLight::ELightOn || |
|
510 aStatus == CHWRMLight::ELightStatusUnknown ) |
|
511 { |
|
512 iFlags |= EAlfSchedulerSecondaryLightsOn; |
|
513 } |
|
514 else if( aStatus == CHWRMLight::ELightOff ) |
|
515 { |
|
516 iFlags &= ~EAlfSchedulerSecondaryLightsOn; |
|
517 } |
|
518 else |
|
519 { |
|
520 // for PC lint |
|
521 } |
|
522 } |
|
523 |
|
524 UpdateSchedulerState(); |
|
525 } |
|
526 |
|
527 // --------------------------------------------------------------------------- |
|
528 // Updates scheduling state based on the internal flags. |
|
529 // --------------------------------------------------------------------------- |
|
530 // |
|
531 void CAlfCommandScheduler::UpdateSchedulerState() |
|
532 { |
|
533 if ( (iFlags&EAlfSchedulerPrimaryLightsOn || |
|
534 iFlags&EAlfSchedulerSecondaryLightsOn ) && |
|
535 iFlags&EAlfSchedulerApplicationForeground ) |
|
536 { |
|
537 // Run the scheduler |
|
538 Run(); |
|
539 } |
|
540 else |
|
541 { |
|
542 // Pause schduler |
|
543 Pause(); |
|
544 } |
|
545 } |
|
546 |
|
547 // --------------------------------------------------------------------------- |
|
548 // Restarts the scheduling. |
|
549 // --------------------------------------------------------------------------- |
|
550 // |
|
551 void CAlfCommandScheduler::Run() |
|
552 { |
|
553 if ( iFlags&EAlfSchedulerRunning ) |
|
554 { |
|
555 return; // Already running |
|
556 } |
|
557 |
|
558 iFlags |= EAlfSchedulerRunning; |
|
559 |
|
560 for(TInt i = iEvents.Count() - 1; i >= 0; --i) |
|
561 { |
|
562 iEvents[i]->Continue(); |
|
563 |
|
564 // Executing a command may have potentially altered the iEvents array, |
|
565 // e.g. application may have canceled other commands when one command was |
|
566 // executed. We must make sure that we don't overindex here ! |
|
567 if (i > iEvents.Count() + 1) |
|
568 { |
|
569 i = iEvents.Count(); |
|
570 } |
|
571 } |
|
572 } |
|
573 |
|
574 // --------------------------------------------------------------------------- |
|
575 // Pause scheduling. |
|
576 // --------------------------------------------------------------------------- |
|
577 // |
|
578 void CAlfCommandScheduler::Pause() |
|
579 { |
|
580 if ( !(iFlags&EAlfSchedulerRunning) ) |
|
581 { |
|
582 return; // Already paused |
|
583 } |
|
584 |
|
585 iFlags &= ~EAlfSchedulerRunning; |
|
586 for(TInt i = iEvents.Count() - 1; i >= 0; --i) |
|
587 { |
|
588 iEvents[i]->Pause(); |
|
589 } |
|
590 |
|
591 } |