|
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 <barsc2.h> |
|
17 #include <barsread2.h> |
|
18 #include <e32property.h> |
|
19 #include <e32uid.h> |
|
20 #include <e32power.h> |
|
21 |
|
22 #include <ssm/ssmcmd.hrh> |
|
23 #include <ssm/ssmsubstates.hrh> |
|
24 |
|
25 #include <ssm/ssmstatetransition.h> |
|
26 #include <ssm/ssmcommandlistresourcereader.h> |
|
27 |
|
28 #include "gsastatepolicyshutdown.h" |
|
29 #include "ssmdebug.h" |
|
30 #include "ssmpanic.h" |
|
31 |
|
32 /** |
|
33 Panic used by Shutdown policy plug-in when resource reader is invalid. |
|
34 Strings must not be longer than 16 characters or they will be truncated by User::Panic() |
|
35 */ |
|
36 _LIT(KPanicGsaShutdownState, "ShutdownStatePolicy"); |
|
37 |
|
38 /** |
|
39 Shutdown state policy resource file path. "z:/private/<SID of SSM>/shutdown/" |
|
40 */ |
|
41 _LIT(KCommandListPath, "z:\\private\\2000D75B\\shutdown\\"); |
|
42 |
|
43 /** |
|
44 Used to create an instance of MSsmStatePolicy class. |
|
45 |
|
46 @return A pointer to an instance of MSsmStatePolicy |
|
47 */ |
|
48 EXPORT_C MSsmStatePolicy* CGsaStatePolicyShutdown::NewL() |
|
49 { |
|
50 CGsaStatePolicyShutdown* self = new (ELeave) CGsaStatePolicyShutdown; |
|
51 CleanupStack::PushL(self); |
|
52 self->ConstructL(); |
|
53 CleanupStack::Pop(self); |
|
54 return self; |
|
55 } |
|
56 |
|
57 /** |
|
58 Makes a RFs connection and maintains a list of supported transition states from shutdown state. |
|
59 |
|
60 @leave One of the error value returned by RProperty::Get() or RFs::Connect() or RArray::AppendL() |
|
61 @see RProperty::Get |
|
62 */ |
|
63 void CGsaStatePolicyShutdown::ConstructL() |
|
64 { |
|
65 // Read the hardware reason |
|
66 User::LeaveIfError(RProperty::Get(KUidSystemCategory, KSystemStartupModeKey, iHardwareReason)); |
|
67 User::LeaveIfError(iFs.Connect()); |
|
68 |
|
69 iCommandListResourceReader = CSsmCommandListResourceReader::NewL(iFs, KCommandListPath(), *this); |
|
70 } |
|
71 |
|
72 /** |
|
73 default CTOR |
|
74 */ |
|
75 CGsaStatePolicyShutdown::CGsaStatePolicyShutdown() |
|
76 { |
|
77 } |
|
78 |
|
79 /** |
|
80 DTOR |
|
81 */ |
|
82 CGsaStatePolicyShutdown::~CGsaStatePolicyShutdown() |
|
83 { |
|
84 delete iCommandListResourceReader; |
|
85 iSubStates.Close(); |
|
86 iFs.Close(); |
|
87 } |
|
88 |
|
89 /** |
|
90 Initializes command list resource reader. |
|
91 |
|
92 @param aStatus to complete when the initialization operation has finished |
|
93 @panic EInvalidResourceReader if the command list resource reader is invalid |
|
94 |
|
95 @see MSsmStatePolicy::Initialize |
|
96 */ |
|
97 void CGsaStatePolicyShutdown::Initialize(TRequestStatus& aStatus) |
|
98 { |
|
99 __ASSERT_DEBUG(iCommandListResourceReader, PanicNow(KPanicGsaShutdownState, EInvalidResourceReader)); |
|
100 |
|
101 // initialise command list resource reader. |
|
102 iCommandListResourceReader->Initialise(aStatus); |
|
103 } |
|
104 |
|
105 /** |
|
106 Cancels an asynchronous Initialize operation. |
|
107 |
|
108 @see MSsmStatePolicy::InitializeCancel |
|
109 */ |
|
110 void CGsaStatePolicyShutdown::InitializeCancel() |
|
111 { |
|
112 iCommandListResourceReader->InitialiseCancel(); |
|
113 } |
|
114 |
|
115 /** |
|
116 Deletes all resources and frees itself. |
|
117 |
|
118 @see MSsmStatePolicy::Release |
|
119 */ |
|
120 void CGsaStatePolicyShutdown::Release() |
|
121 { |
|
122 delete this; |
|
123 } |
|
124 |
|
125 /** |
|
126 Determines if an incoming shutdown state transition request should be accepted or rejected. |
|
127 Only transition to ESsmFail state is allowed from ESsmShutdown state. All other requests are rejected. |
|
128 Clients calling this API should posess 'ECapabilityPowerMgmt', else the API will return ENotAllowed. |
|
129 |
|
130 @param aRequest Contains information about the new request |
|
131 @param aCurrent Contains NULL or the first accepted but not yet completed transition request |
|
132 @param aQueued Contains NULL or a second accepted but not yet started transition request |
|
133 @param aMessage Message sent by SSM server, used to check if the client has 'ECapabilityPowerMgmt' |
|
134 |
|
135 @return one of the TResponse value |
|
136 @see MSsmStatePolicy::TransitionAllowed |
|
137 @see MSsmStatePolicy::TResponse |
|
138 */ |
|
139 MSsmStatePolicy::TResponse CGsaStatePolicyShutdown::TransitionAllowed(const TSsmStateTransition& aRequest, TSsmStateTransition const* /*aCurrent*/, |
|
140 TSsmStateTransition const* /*aQueued*/, const RMessagePtr2& aMessage) |
|
141 { |
|
142 TResponse response = ENotAllowed; |
|
143 |
|
144 if (!aMessage.HasCapability(ECapabilityPowerMgmt)) |
|
145 { |
|
146 return response; |
|
147 } |
|
148 |
|
149 if (aRequest.State().MainState() == ESsmFail) |
|
150 { |
|
151 // Going into failed state will override anything currently ongoing or queued |
|
152 response = EReplaceCurrentClearQueue; |
|
153 } |
|
154 #ifdef SYMBIAN_SSM_GRACEFUL_SHUTDOWN |
|
155 if(aRequest.State().MainState() == ESsmShutdown) |
|
156 { |
|
157 response = EDefinitelyAllowed; |
|
158 } |
|
159 #endif //SYMBIAN_SSM_GRACEFUL_SHUTDOWN |
|
160 |
|
161 #ifdef _DEBUG |
|
162 TSsmStateName name = aRequest.State().Name(); |
|
163 DEBUGPRINT3(_L("Shutdown Policy : Transition to state %S. allowed with response %d"), &name, response); |
|
164 #endif |
|
165 return response; |
|
166 } |
|
167 |
|
168 /** |
|
169 Create the command list associated with a sub state transition. |
|
170 |
|
171 @param aState Contains the state and substate that identifies the command list to create |
|
172 @param aReason Contains the reason as given by the request |
|
173 @param aStatus to complete when the operation has finished |
|
174 @panic EInvalidResourceReader if the command list resource reader is invalid |
|
175 @see MSsmStatePolicy::PrepareCommandList |
|
176 */ |
|
177 void CGsaStatePolicyShutdown::PrepareCommandList(TSsmState aState, TInt aReason, TRequestStatus& aStatus) |
|
178 { |
|
179 __ASSERT_DEBUG( iCommandListResourceReader , PanicNow(KPanicGsaShutdownState, EInvalidResourceReader)); |
|
180 |
|
181 iSoftwareReason = aReason; |
|
182 |
|
183 //Let's start from the beginning if no specific minor state is selected |
|
184 iRequestedSubState = ((aState.SubState()==KSsmAnySubState) ? ESsmShutdownSubStateCritical : aState.SubState()); |
|
185 iPublishState.Set(aState.MainState(), ((iRequestedSubState==KSsmAnySubState) ? ESsmShutdownSubStateCritical : iRequestedSubState)); |
|
186 const TInt commandListId = iPublishState.SubState(); |
|
187 |
|
188 //Build the commandlist from resource |
|
189 iCommandListResourceReader->PrepareCommandList(commandListId, iPublishState, aStatus); |
|
190 } //lint !e1746 Suppress parameter 'aState' could be made const reference |
|
191 |
|
192 /** |
|
193 Cancels asynchronous PrepareCommandList operation. |
|
194 |
|
195 @see MSsmStatePolicy::PrepareCommandListCancel |
|
196 */ |
|
197 void CGsaStatePolicyShutdown::PrepareCommandListCancel() |
|
198 { |
|
199 iCommandListResourceReader->PrepareCommandListCancel(); |
|
200 } |
|
201 |
|
202 /** |
|
203 Return the command list once the PrepareCommandList has completed. |
|
204 Ownership of the returned command list is transferred to the caller. |
|
205 @panic EInvalidResourceReader if the command list resource reader is invalid |
|
206 @return The command list created during the preceding PrepareCommandList step |
|
207 */ |
|
208 CSsmCommandList* CGsaStatePolicyShutdown::CommandList() |
|
209 { |
|
210 __ASSERT_DEBUG( iCommandListResourceReader , PanicNow(KPanicGsaShutdownState, EInvalidResourceReader)); |
|
211 |
|
212 return iCommandListResourceReader->GetCommandList(); |
|
213 } |
|
214 |
|
215 /** |
|
216 Determines the next sub state transition. |
|
217 @param aCurrentTransition Contains the last executed state |
|
218 @param aReason Contains the reason as given by the request |
|
219 @param aError Contains the completion code from the last executed sub-state transition |
|
220 @param aSeverity Contains the severity of the failed command in case the sub-state transition ended with an error |
|
221 @param aNextState The next System State to head for, if there is one |
|
222 @panic EInvalidMainState if the current state is not shutdown |
|
223 @return ETrue if aNextState contains another System State to head for, or |
|
224 EFalse if there is no further transitions to do. |
|
225 @see MSsmStatePolicy::GetNextState |
|
226 */ |
|
227 TBool CGsaStatePolicyShutdown::GetNextState(TSsmState aCurrentTransition, TInt aReason, TInt aError, TInt /*aSeverity*/, TSsmState& aNextState) |
|
228 { |
|
229 __ASSERT_ALWAYS(aCurrentTransition.MainState() == ESsmShutdown, PanicNow(KPanicGsaShutdownState, EInvalidShutdownState)); |
|
230 DEBUGPRINT2(_L("Shutdown Policy : CLE returned with error : %d after execution of Shutdown command list."), aError); |
|
231 |
|
232 if (KErrNone != aError) |
|
233 { |
|
234 aNextState = TSsmState(ESsmFail, KSsmAnySubState); |
|
235 #ifdef _DEBUG |
|
236 TSsmStateName name = aNextState.Name(); |
|
237 DEBUGPRINT3(_L("Shutdown Policy : CLE returned with (error : %d) so moving to Fail State : %S."), aError, &name); |
|
238 #endif |
|
239 return ETrue; |
|
240 } |
|
241 |
|
242 // Get the sub states from resource reader only once |
|
243 if (!iSubStatesCount) |
|
244 { |
|
245 // Get sub states list from resource reader |
|
246 TRAPD(err, iCommandListResourceReader->GetCommandListIdsL(iSubStates)); |
|
247 if (err) |
|
248 { |
|
249 DEBUGPRINT2(_L("Shutdown Policy : Command list ids prepared with error: %d"), err); |
|
250 } |
|
251 else |
|
252 { |
|
253 iSubStatesCount = iSubStates.Count(); |
|
254 } |
|
255 } |
|
256 |
|
257 TInt index = iSubStates.Find(iRequestedSubState); |
|
258 |
|
259 if ((index < 0) || (index >= (iSubStatesCount - 1))) |
|
260 { |
|
261 return EFalse; |
|
262 } |
|
263 |
|
264 // ESsmShutdownSubStatePowerOff is transition to EPwStandby. So further transition should not be allowed. |
|
265 // ESsmShutdownSubStateReStart is transition to EPwRestart. |
|
266 // On successful restart (EPwRestart) control will not reach here again. |
|
267 if (iRequestedSubState == ESsmShutdownSubStatePowerOff) |
|
268 { |
|
269 return EFalse; |
|
270 } |
|
271 else if (ESsmShutdownSubStateNonCritical != iRequestedSubState) |
|
272 { |
|
273 iRequestedSubState = iSubStates[++index]; |
|
274 aNextState = TSsmState(ESsmShutdown, iRequestedSubState); |
|
275 } |
|
276 else |
|
277 { |
|
278 TUint16 subState = (EPwRestart == aReason) ? ESsmShutdownSubStateReStart : ESsmShutdownSubStatePowerOff; |
|
279 aNextState = TSsmState(ESsmShutdown, subState); |
|
280 } |
|
281 #ifdef _DEBUG |
|
282 TSsmStateName name = aNextState.Name(); |
|
283 DEBUGPRINT2(_L("Shutdown Policy : Transition to next state is : %S"), &name); |
|
284 #endif |
|
285 return ETrue; |
|
286 } //lint !e1746 Suppress parameter 'aCurrentTransition' could be made const reference |
|
287 |
|
288 /** |
|
289 Callback used by CSsmCommandListResourceReader when a decision needs to be made |
|
290 on whether to include a command in a command list or not. |
|
291 |
|
292 @param aResourceFile Instance of CResourceFile |
|
293 @param aResourceId Resource id of SSM_SYMBIAN_CONDITIONAL_INFORMATION struct for command |
|
294 @return ETrue in case the command needs to be included in command list, else EFalse. |
|
295 |
|
296 @see MSsmConditionalCallback::ConditionalCommandAllowedL |
|
297 */ |
|
298 TBool CGsaStatePolicyShutdown::ConditionalCommandAllowedL(CResourceFile& /*aResourceFile*/, TInt /*aResourceId*/) |
|
299 { |
|
300 // no commands use 'conditional_information' in Shutdown state command list. |
|
301 PanicNow(KPanicGsaShutdownState, EConditionalInfoNotImplemented); |
|
302 return EFalse; // avoid a compiler warning. |
|
303 } |