|
1 // Copyright (c) 2007-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 <ssm/ssmsubstates.hrh> |
|
17 |
|
18 #include "ssmdebug.h" |
|
19 |
|
20 #include "saastateadaptation.h" |
|
21 #include "clayerpanic.h" |
|
22 #include "startupadaptationadapter.h" |
|
23 |
|
24 |
|
25 /* |
|
26 * Creates a new object associated with the passed in CStartupAdaptationAdapter |
|
27 * |
|
28 * @internalComponent |
|
29 */ |
|
30 CSaaStateAdaptation* CSaaStateAdaptation::NewL(CStartupAdaptationAdapter* aAdapter) |
|
31 { |
|
32 CSaaStateAdaptation* self = new (ELeave) CSaaStateAdaptation(aAdapter); |
|
33 CleanupStack::PushL(self); |
|
34 self->ConstructL(); |
|
35 CleanupStack::Pop(self); |
|
36 return self; |
|
37 } |
|
38 |
|
39 /* |
|
40 * Destructor for this object |
|
41 * |
|
42 * @internalComponent |
|
43 */ |
|
44 CSaaStateAdaptation::~CSaaStateAdaptation() |
|
45 { |
|
46 iEventQueue.Close(); |
|
47 } |
|
48 |
|
49 /* |
|
50 * Decrements the reference count for this object, deleting it if necessary |
|
51 * |
|
52 * @internalComponent |
|
53 */ |
|
54 void CSaaStateAdaptation::Release() |
|
55 { |
|
56 // This MClass is owned by the singleton CStartupAdaptationAdapter class so |
|
57 // release should do nothing. |
|
58 } |
|
59 |
|
60 /* |
|
61 * |
|
62 * |
|
63 * @internalComponent |
|
64 */ |
|
65 void CSaaStateAdaptation::RequestCoopSysStateChange(TSsmState aState, TRequestStatus& aStatus) |
|
66 { |
|
67 // If this adaptation is busy then complete with KErrInUse |
|
68 if(Busy()) |
|
69 { |
|
70 TRequestStatus* statusPtr = &aStatus; |
|
71 User::RequestComplete(statusPtr, KErrInUse); |
|
72 return; |
|
73 } |
|
74 // Set this request status |
|
75 SetRequestStatus(&aStatus); |
|
76 aStatus = KRequestPending; |
|
77 // No outstand requests so set up command id |
|
78 SetCommandId(StartupAdaptation::EGlobalStateChange); |
|
79 // Map TSsmState to TGlobalState |
|
80 iGlobalStatePckg() = MapToStartupAdaptationState(aState); |
|
81 |
|
82 // Pass this to the adapter |
|
83 TRAPD(err, iAdapter->QueueDispatchL(this)); |
|
84 if(err != KErrNone) |
|
85 { |
|
86 // Failed to queue adaptation, complete with error |
|
87 SetRequestStatus(NULL); |
|
88 TRequestStatus* statusPtr = &aStatus; |
|
89 User::RequestComplete(statusPtr, err); |
|
90 } |
|
91 } //lint !e1746 Suppress parameter 'aState' could be made const reference |
|
92 |
|
93 /* |
|
94 * |
|
95 * |
|
96 * @internalComponent |
|
97 */ |
|
98 void CSaaStateAdaptation::RequestCoopSysSelfTest(TRequestStatus& aStatus) |
|
99 { |
|
100 // If this adaptation is busy then complete with KErrInUse |
|
101 if(Busy()) |
|
102 { |
|
103 TRequestStatus* statusPtr = &aStatus; |
|
104 User::RequestComplete(statusPtr, KErrInUse); |
|
105 return; |
|
106 } |
|
107 // Set this request status |
|
108 SetRequestStatus(&aStatus); |
|
109 aStatus = KRequestPending; |
|
110 // No outstand requests so set up command id |
|
111 SetCommandId(StartupAdaptation::EExecuteSelftests); |
|
112 // No parameters to set to pass in |
|
113 |
|
114 // Pass this to the adapter |
|
115 TRAPD(err, iAdapter->QueueDispatchL(this)); |
|
116 if(err != KErrNone) |
|
117 { |
|
118 // Failed to queue adaptation, complete with error |
|
119 SetRequestStatus(NULL); |
|
120 TRequestStatus* statusPtr = &aStatus; |
|
121 User::RequestComplete(statusPtr, err); |
|
122 } |
|
123 } |
|
124 |
|
125 /* |
|
126 * |
|
127 * |
|
128 * @internalComponent |
|
129 */ |
|
130 void CSaaStateAdaptation::RequestCoopSysPerformRestartActions(TInt aReason, TRequestStatus& aStatus) |
|
131 { |
|
132 // If this adaptation is busy then complete with KErrInUse |
|
133 if(Busy()) |
|
134 { |
|
135 TRequestStatus* statusPtr = &aStatus; |
|
136 User::RequestComplete(statusPtr, KErrInUse); |
|
137 return; |
|
138 } |
|
139 // Set this request status |
|
140 SetRequestStatus(&aStatus); |
|
141 aStatus = KRequestPending; |
|
142 // No outstand requests so set up command id |
|
143 SetCommandId(StartupAdaptation::EExecuteReset); |
|
144 // Set the reason package contents |
|
145 iResetReasonPckg() = static_cast<StartupAdaptation::TResetReason>(aReason); |
|
146 |
|
147 // Pass this to the adapter |
|
148 TRAPD(err, iAdapter->QueueDispatchL(this)); |
|
149 if(err != KErrNone) |
|
150 { |
|
151 // Failed to queue adaptation, complete with error |
|
152 SetRequestStatus(NULL); |
|
153 TRequestStatus* statusPtr = &aStatus; |
|
154 User::RequestComplete(statusPtr, err); |
|
155 } |
|
156 } |
|
157 |
|
158 /* |
|
159 * |
|
160 * |
|
161 * @internalComponent |
|
162 */ |
|
163 void CSaaStateAdaptation::RequestCoopSysPerformShutdownActions(TInt /*aReason*/, TRequestStatus& aStatus) |
|
164 { |
|
165 // If this adaptation is busy then complete with KErrInUse |
|
166 if(Busy()) |
|
167 { |
|
168 TRequestStatus* statusPtr = &aStatus; |
|
169 User::RequestComplete(statusPtr, KErrInUse); |
|
170 return; |
|
171 } |
|
172 // Set this request status |
|
173 SetRequestStatus(&aStatus); |
|
174 aStatus = KRequestPending; |
|
175 // No outstand requests so set up command id |
|
176 SetCommandId(StartupAdaptation::EExecuteShutdown); |
|
177 // No parameters to set to pass in |
|
178 |
|
179 // Pass this to the adapter |
|
180 TRAPD(err, iAdapter->QueueDispatchL(this)); |
|
181 if(err != KErrNone) |
|
182 { |
|
183 // Failed to queue adaptation, complete with error |
|
184 SetRequestStatus(NULL); |
|
185 TRequestStatus* statusPtr = &aStatus; |
|
186 User::RequestComplete(statusPtr, err); |
|
187 } |
|
188 } |
|
189 |
|
190 /* |
|
191 * |
|
192 * |
|
193 * @internalComponent |
|
194 */ |
|
195 void CSaaStateAdaptation::RequestCoopSysPerformRfsActions(TSsmRfsType aRfsType, TRequestStatus& aStatus) |
|
196 { |
|
197 // If this adaptation is busy then complete with KErrInUse |
|
198 if(Busy()) |
|
199 { |
|
200 TRequestStatus* statusPtr = &aStatus; |
|
201 User::RequestComplete(statusPtr, KErrInUse); |
|
202 return; |
|
203 } |
|
204 // Set this request status |
|
205 SetRequestStatus(&aStatus); |
|
206 aStatus = KRequestPending; |
|
207 // No outstand requests so set up command id |
|
208 SetCommandId(StartupAdaptation::EExecuteDOSRfs); |
|
209 // Set up the reason |
|
210 switch(aRfsType) |
|
211 { |
|
212 case ESsmShallowRfs: |
|
213 iRfsReasonPckg() = StartupAdaptation::ENormalRFS; |
|
214 break; |
|
215 case ESsmDeepRfs: |
|
216 iRfsReasonPckg() = StartupAdaptation::EDeepRFS; |
|
217 break; |
|
218 default: |
|
219 // Assume the reason is a custom one |
|
220 iRfsReasonPckg() = static_cast<StartupAdaptation::TRFSReason>(aRfsType); |
|
221 break; |
|
222 } |
|
223 // Pass this to the adapter |
|
224 TRAPD(err, iAdapter->QueueDispatchL(this)); |
|
225 if(err != KErrNone) |
|
226 { |
|
227 // Failed to queue adaptation, complete with error |
|
228 SetRequestStatus(NULL); |
|
229 TRequestStatus* statusPtr = &aStatus; |
|
230 User::RequestComplete(statusPtr, err); |
|
231 } |
|
232 } |
|
233 |
|
234 /* |
|
235 * |
|
236 * |
|
237 * @internalComponent |
|
238 */ |
|
239 void CSaaStateAdaptation::RequestCancel() |
|
240 { |
|
241 CancelRequest(); |
|
242 } |
|
243 |
|
244 /* |
|
245 * |
|
246 * |
|
247 * @internalComponent |
|
248 */ |
|
249 void CSaaStateAdaptation::NotifyCoopSysEvent(TDes8& aEvent, TRequestStatus& aStatus) |
|
250 { |
|
251 if(iEventStatus != NULL) |
|
252 { |
|
253 DEBUGPRINT1A("SAA - Multiple notify coop sys event requests detected, completing with KErrInUse"); |
|
254 TRequestStatus* statusPtr = &aStatus; |
|
255 User::RequestComplete(statusPtr, KErrInUse); |
|
256 return; |
|
257 } |
|
258 if(iEventQueue.Count() != 0) |
|
259 { |
|
260 // Complete immediately with an event from the queue |
|
261 DEBUGPRINT1A("SAA - Completing notify coop sys event immediately with queued event"); |
|
262 // Read value from array |
|
263 TPckgBuf<TSsmCoopSysEventType> pckgBuf(iEventQueue[0]); |
|
264 // Remove value from array |
|
265 iEventQueue.Remove(0); |
|
266 // Copy descriptor package across |
|
267 aEvent.Copy(pckgBuf); |
|
268 // Complete status |
|
269 TRequestStatus* statusPtr = &aStatus; |
|
270 User::RequestComplete(statusPtr, KErrNone); |
|
271 } |
|
272 else |
|
273 { |
|
274 // No events in queue so wait |
|
275 aStatus = KRequestPending; |
|
276 iEventStatus = &aStatus; |
|
277 iEventOutputBuffer = &aEvent; |
|
278 } |
|
279 } |
|
280 |
|
281 /* |
|
282 * |
|
283 * |
|
284 * @internalComponent |
|
285 */ |
|
286 void CSaaStateAdaptation::NotifyCancel() |
|
287 { |
|
288 if(iEventStatus != NULL) |
|
289 { |
|
290 User::RequestComplete(iEventStatus, KErrCancel); |
|
291 iEventStatus = NULL; |
|
292 } |
|
293 // Clear buffer |
|
294 iEventOutputBuffer = NULL; |
|
295 } |
|
296 |
|
297 /* |
|
298 * Constructs a new state adaptation object and associates it with aAdapter |
|
299 * |
|
300 * @internalComponent |
|
301 */ |
|
302 CSaaStateAdaptation::CSaaStateAdaptation(CStartupAdaptationAdapter* aAdapter) |
|
303 : CAdaptationBase(aAdapter) |
|
304 { |
|
305 |
|
306 } |
|
307 |
|
308 /** |
|
309 * Number of events to pre-allocate in the event queue |
|
310 * |
|
311 * @internalComponent |
|
312 */ |
|
313 const TInt KEventQueueReserveValue = 8; |
|
314 |
|
315 /* |
|
316 * Second phase of construction |
|
317 * |
|
318 * @internalComponent |
|
319 */ |
|
320 void CSaaStateAdaptation::ConstructL() |
|
321 { |
|
322 // Preallocate event queue some memory |
|
323 iEventQueue.ReserveL(KEventQueueReserveValue); |
|
324 } |
|
325 |
|
326 /** |
|
327 * See CAdaptationBase for description of method. |
|
328 * |
|
329 * @internalComponent |
|
330 */ |
|
331 void CSaaStateAdaptation::RequestComplete(const StartupAdaptation::TCommand __DEBUG_ONLY(aCommandId), TDesC8& aRetPckg) |
|
332 { |
|
333 DEBUGPRINT3A("SAA - Response received from adaptation with commandId: %d, expecting %d", aCommandId, CommandId()); |
|
334 __ASSERT_DEBUG(aCommandId == CommandId(), CLAYER_PANIC(ECLayerUnexpectedCommandResponse)); |
|
335 switch(CommandId()) |
|
336 { |
|
337 case StartupAdaptation::EGlobalStateChange: // fall through |
|
338 case StartupAdaptation::EExecuteSelftests: // fall through |
|
339 case StartupAdaptation::EExecuteShutdown: // fall through |
|
340 case StartupAdaptation::EExecuteReset: // fall through |
|
341 case StartupAdaptation::EExecuteDOSRfs: |
|
342 { |
|
343 StartupAdaptation::TResponsePckg responsePckg; |
|
344 responsePckg.Copy(aRetPckg); |
|
345 CompleteRequestStatus(responsePckg()); |
|
346 break; |
|
347 } |
|
348 default: |
|
349 // Return an error to the client |
|
350 CompleteRequestStatus(KErrArgument); |
|
351 break; |
|
352 } |
|
353 } |
|
354 |
|
355 /** |
|
356 * See CAdaptationBase for description of method. |
|
357 * |
|
358 * @internalComponent |
|
359 */ |
|
360 TDesC8* CSaaStateAdaptation::ParameterPckg() |
|
361 { |
|
362 TDesC8* ptr = NULL; |
|
363 switch(CommandId()) |
|
364 { |
|
365 case StartupAdaptation::EGlobalStateChange: |
|
366 ptr = &iGlobalStatePckg; |
|
367 break; |
|
368 case StartupAdaptation::EExecuteSelftests: |
|
369 ptr = &iNullBuf; |
|
370 break; |
|
371 case StartupAdaptation::EExecuteShutdown: |
|
372 ptr = &iNullBuf; |
|
373 break; |
|
374 case StartupAdaptation::EExecuteDOSRfs: |
|
375 ptr = &iRfsReasonPckg; |
|
376 break; |
|
377 case StartupAdaptation::EExecuteReset: |
|
378 ptr = &iResetReasonPckg; |
|
379 break; |
|
380 default: |
|
381 ptr = NULL; |
|
382 break; |
|
383 } |
|
384 return ptr; |
|
385 } |
|
386 |
|
387 /** |
|
388 * Maps a TSsmState object into the associated StartupAdaptation::TGlobalState value. |
|
389 * |
|
390 * Uses the following mappings: |
|
391 * |
|
392 * ESWStateStartingUiServices = TSsmState(ESsmStartup, ESWStateStartingUiServices - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
393 * ESWStateStartingCriticalApps = TSsmState(ESsmStartup, ESWStateStartingCriticalApps - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
394 * ESWStateSelfTestOK = TSsmState(ESsmStartup, ESWStateSelfTestOK - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
395 * // States for the security check phase. |
|
396 * ESWStateSecurityCheck = TSsmState(ESsmStartup, ESWStateSecurityCheck - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
397 * ESWStateCriticalPhaseOK = TSsmState(ESsmStartup, ESWStateCriticalPhaseOK - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
398 * ESWStateEmergencyCallsOnly = TSsmState(ESsmStartup, ESWStateEmergencyCallsOnly - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
399 * // Terminal states defined by the boot mode (and some other variables such as offline mode). |
|
400 * ESWStateTest = TSsmState(ESsmStartup, ESWStateTest - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
401 * ESWStateCharging = TSsmState(ESsmStartup, ESWStateCharging - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
402 * ESWStateAlarm = TSsmState(ESsmStartup, ESWStateAlarm - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
403 * ESWStateNormalRfOn = TSsmState(ESsmNormal, ESWStateNormalRfOn - ESWStateStartingUiServices + ESsmStartupSubStateCriticalStatic); |
|
404 * ESWStateNormalRfOff = TSsmState(ESsmNormal, ESWStateNormalRfOff - ESWStateStartingUiServices + ESsmStartupSubStateCriticalStatic); |
|
405 * ESWStateNormalBTSap = TSsmState(ESsmNormal, ESWStateNormalBTSap - ESWStateStartingUiServices + ESsmStartupSubStateCriticalStatic); |
|
406 * // States for notifying adaptation about a terminal state change. |
|
407 * ESWStateAlarmToCharging = TSsmState(ESsmStartup, ESWStateAlarmToCharging - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
408 * ESWStateChargingToAlarm = TSsmState(ESsmStartup, ESWStateChargingToAlarm - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
409 * ESWStateChargingToNormal = TSsmState(ESsmStartup, ESWStateChargingToNormal - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
410 * ESWStateAlarmToNormal = TSsmState(ESsmStartup, ESWStateAlarmToNormal - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); |
|
411 * // Shutdown-related states. |
|
412 * ESWStateShuttingDown = TSsmState(ESsmShutdown, KSsmAnySubState); |
|
413 * // Error states during critical phase. |
|
414 * ESWStateFatalStartupError = TSsmState(ESsmFail, KSsmAnySubState); |
|
415 * |
|
416 * Returns 0 on invalid TSsmState |
|
417 * |
|
418 * @internalComponent |
|
419 */ |
|
420 StartupAdaptation::TGlobalState CSaaStateAdaptation::MapToStartupAdaptationState(TSsmState aState) |
|
421 { |
|
422 using namespace StartupAdaptation; |
|
423 |
|
424 // Calculate the difference from the substate to the value of TGlobalState values |
|
425 // This uses ESsmStartupSubStateNonCritical to map to the correct part of the staged |
|
426 // start-up architecture and therefore to map the states as described in the comment |
|
427 // for this method. |
|
428 const TInt KStartupSubStateAdjustment = static_cast<TInt>(ESWStateStartingUiServices) |
|
429 - static_cast<TInt>(ESsmStartupSubStateNonCritical); |
|
430 // Adjust the substate value |
|
431 const TInt adjustedStartupSubStateValue = aState.SubState() + KStartupSubStateAdjustment; |
|
432 |
|
433 // Calculate the difference from the substate to the value of TGlobalState values |
|
434 // This uses ESsmStartupSubStateCriticalStatic to map to the correct states as described |
|
435 // in the comment for this method. |
|
436 const TInt KNormalSubStateAdjustment = static_cast<TInt>(ESWStateStartingUiServices) |
|
437 - static_cast<TInt>(ESsmStartupSubStateCriticalStatic); |
|
438 |
|
439 // Adjust the substate value |
|
440 const TInt adjustedNormalSubStateValue = aState.SubState() + KNormalSubStateAdjustment; |
|
441 |
|
442 TGlobalState ret = static_cast<TGlobalState>(0); |
|
443 |
|
444 if(aState.MainState() == ESsmStartup) |
|
445 { |
|
446 ret = static_cast<TGlobalState>(adjustedStartupSubStateValue); |
|
447 } |
|
448 else if(aState.MainState() == ESsmNormal) |
|
449 { |
|
450 ret = static_cast<TGlobalState>(adjustedNormalSubStateValue); |
|
451 } |
|
452 else if(aState.MainState() == ESsmShutdown) |
|
453 { |
|
454 ret = ESWStateShuttingDown; |
|
455 } |
|
456 else if(aState.MainState() == ESsmFail) |
|
457 { |
|
458 ret = ESWStateFatalStartupError; |
|
459 } |
|
460 |
|
461 // Validate the return value is correct |
|
462 switch(aState.MainState()) |
|
463 { |
|
464 case ESsmStartup: |
|
465 if(ret < ESWStateStartingUiServices || |
|
466 (ret > ESWStateAlarm && ret < ESWStateAlarmToCharging) || |
|
467 ret > ESWStateAlarmToNormal) |
|
468 { |
|
469 CLAYER_PANIC(ECLayerInvalidSubState); |
|
470 } |
|
471 break; |
|
472 case ESsmNormal: |
|
473 if(ret < ESWStateNormalRfOn || ret > ESWStateNormalBTSap) |
|
474 { |
|
475 CLAYER_PANIC(ECLayerInvalidSubState); |
|
476 } |
|
477 break; |
|
478 case ESsmShutdown: |
|
479 if(aState.SubState() != KSsmAnySubState) |
|
480 { |
|
481 CLAYER_PANIC(ECLayerInvalidSubState); |
|
482 } |
|
483 break; |
|
484 case ESsmFail: |
|
485 if(aState.SubState() != KSsmAnySubState) |
|
486 { |
|
487 CLAYER_PANIC(ECLayerInvalidSubState); |
|
488 } |
|
489 break; |
|
490 default: |
|
491 // Do nothing |
|
492 break; |
|
493 } |
|
494 return ret; |
|
495 } //lint !e1746 Suppress parameter 'aState' could be made const reference |
|
496 |
|
497 /** |
|
498 * Processes the event passed in and distributes to waiting client or queues event. |
|
499 * |
|
500 * @internalComponent |
|
501 */ |
|
502 void CSaaStateAdaptation::ProcessEventL(TSsmCoopSysEventType aEventType) |
|
503 { |
|
504 DEBUGPRINT2A("SAA - State adaptation processing event with type: %d", aEventType); |
|
505 if(iEventStatus == NULL) |
|
506 { |
|
507 // Need to queue event as nothing is waiting to be notified |
|
508 iEventQueue.AppendL(aEventType); |
|
509 } |
|
510 else |
|
511 { |
|
512 // Client waiting for event |
|
513 __ASSERT_DEBUG(iEventOutputBuffer != NULL, CLAYER_PANIC(ECLayerNullStateEventBuffer)); |
|
514 TPckgBuf<TSsmCoopSysEventType> pckgBuf(aEventType); |
|
515 // Copy event across |
|
516 iEventOutputBuffer->Copy(pckgBuf); |
|
517 // Complete status |
|
518 User::RequestComplete(iEventStatus, KErrNone); |
|
519 // Clear event status and buffer |
|
520 iEventOutputBuffer = NULL; |
|
521 iEventStatus = NULL; |
|
522 } |
|
523 } |