|
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 <barsread2.h> |
|
17 #include <e32property.h> |
|
18 #include <e32uid.h> |
|
19 |
|
20 #include <ssm/ssmcmd.hrh> |
|
21 #include <ssm/ssmsubstates.hrh> |
|
22 |
|
23 #include <ssm/ssmstatetransition.h> |
|
24 #include <ssm/ssmcommandlistresourcereader.h> |
|
25 #include <ssm/startupdomainpskeys.h> |
|
26 #include <ssm/ssmpatchableconstants.h> |
|
27 |
|
28 #include "gsastatepolicynormal.h" |
|
29 #include "ssmdebug.h" |
|
30 #include "ssmpanic.h" |
|
31 |
|
32 /** |
|
33 Panic used by Normal 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(KPanicGsaNormalState, "NormalStatePolicy"); |
|
37 |
|
38 /** |
|
39 Normal state policy resource file path. "z:/private/<SID of SSM>/normal/" |
|
40 */ |
|
41 _LIT(KCommandListPath, "z:\\private\\2000D75B\\normal\\"); |
|
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* CGsaStatePolicyNormal::NewL() |
|
49 { |
|
50 CGsaStatePolicyNormal* self = new (ELeave) CGsaStatePolicyNormal; |
|
51 CleanupStack::PushL(self); |
|
52 self->ConstructL(); |
|
53 CleanupStack::Pop(self); |
|
54 return self; |
|
55 } |
|
56 |
|
57 /** |
|
58 default CTOR |
|
59 */ |
|
60 CGsaStatePolicyNormal::CGsaStatePolicyNormal() |
|
61 { |
|
62 } |
|
63 |
|
64 /** |
|
65 DTOR |
|
66 */ |
|
67 CGsaStatePolicyNormal::~CGsaStatePolicyNormal() |
|
68 { |
|
69 delete iCommandListResourceReader; |
|
70 delete iEvaluator; |
|
71 iCurrentlySupportedTransitions.Close(); |
|
72 iFs.Close(); |
|
73 } |
|
74 |
|
75 /** |
|
76 Makes a RFs connection and maintains a list of supported transition states from normal state. |
|
77 |
|
78 @leave One of the error value returned by RFs::Connect() or RArray::AppendL() |
|
79 */ |
|
80 void CGsaStatePolicyNormal::ConstructL() |
|
81 { |
|
82 User::LeaveIfError(iFs.Connect()); |
|
83 |
|
84 if (IsSsmGracefulOffline()) |
|
85 { |
|
86 // Used to evaluate conditions in command lists. |
|
87 iEvaluator = CConditionEvaluate::NewL(); |
|
88 //Substates ESsmNormalRfOnSubState and ESsmNormalRfOffSubState are the valid transition from Normal State |
|
89 iCurrentlySupportedTransitions.AppendL(TSsmState(ESsmNormal, ESsmNormalRfOnSubState)); |
|
90 iCurrentlySupportedTransitions.AppendL(TSsmState(ESsmNormal, ESsmNormalRfOffSubState)); |
|
91 } |
|
92 // Add supported transitions from Normal 'ESsmNormal' |
|
93 iCurrentlySupportedTransitions.AppendL(TSsmState(ESsmShutdown, KSsmAnySubState)); |
|
94 iCurrentlySupportedTransitions.AppendL(TSsmState(ESsmFail, KSsmAnySubState)); |
|
95 iCurrentlySupportedTransitions.AppendL(TSsmState(ESsmShutdown, ESsmShutdownSubStateCritical)); |
|
96 |
|
97 // create resource reader |
|
98 iCommandListResourceReader = CSsmCommandListResourceReader::NewL(iFs, KCommandListPath(), *this); |
|
99 } |
|
100 |
|
101 /** |
|
102 Initializes command list resource reader. |
|
103 |
|
104 @param aStatus to complete when the initialization operation has finished |
|
105 @panic EInvalidResourceReader if the command list resource reader is invalid |
|
106 |
|
107 @see MSsmStatePolicy::Initialize |
|
108 */ |
|
109 void CGsaStatePolicyNormal::Initialize(TRequestStatus& aStatus) |
|
110 { |
|
111 __ASSERT_DEBUG(iCommandListResourceReader, PanicNow(KPanicGsaNormalState, EInvalidResourceReader)); |
|
112 |
|
113 // initialise command list resource reader. |
|
114 iCommandListResourceReader->Initialise(aStatus); |
|
115 } |
|
116 |
|
117 /** |
|
118 Cancels an asynchronous Initialize operation. |
|
119 |
|
120 @see MSsmStatePolicy::InitializeCancel |
|
121 */ |
|
122 void CGsaStatePolicyNormal::InitializeCancel() |
|
123 { |
|
124 iCommandListResourceReader->InitialiseCancel(); |
|
125 } |
|
126 |
|
127 /** |
|
128 Deletes all resources and frees itself. |
|
129 |
|
130 @see MSsmStatePolicy::Release |
|
131 */ |
|
132 void CGsaStatePolicyNormal::Release() |
|
133 { |
|
134 delete this; |
|
135 } |
|
136 |
|
137 /** |
|
138 Determines if an incoming normal state transition request should be accepted or rejected. |
|
139 Transition to ESsmFail and ESsmShutdown state is allowed from ESsmNormal state. All other requests are rejected. |
|
140 Clients calling this API should posess 'ECapabilityPowerMgmt', else the API will return ENotAllowed. |
|
141 |
|
142 @param aRequest Contains information about the new request |
|
143 @param aCurrent Contains NULL or the first accepted but not yet completed transition request |
|
144 @param aQueued Contains NULL or a second accepted but not yet started transition request |
|
145 @param aMessage Message sent by SSM server, used to check if the client has 'ECapabilityPowerMgmt' |
|
146 |
|
147 @return one of the TResponse value |
|
148 @see MSsmStatePolicy::TransitionAllowed |
|
149 @see MSsmStatePolicy::TResponse |
|
150 */ |
|
151 MSsmStatePolicy::TResponse CGsaStatePolicyNormal::TransitionAllowed(const TSsmStateTransition& aRequest, TSsmStateTransition const* aCurrent, |
|
152 TSsmStateTransition const* aQueued, const RMessagePtr2& aMessage) |
|
153 { |
|
154 TResponse response = ENotAllowed; |
|
155 if (!aMessage.HasCapability(ECapabilityPowerMgmt)) |
|
156 { |
|
157 return response; |
|
158 } |
|
159 |
|
160 //Check if the requested transition is supported from current state |
|
161 if (TransitionSupported(aRequest.State())) |
|
162 { |
|
163 if((NULL == aCurrent) && (NULL == aQueued)) |
|
164 { |
|
165 // SsmServer is idle |
|
166 response = EDefinitelyAllowed; |
|
167 } |
|
168 else if((aRequest.State().MainState() == ESsmFail) || (aRequest.State().MainState() == ESsmShutdown)) |
|
169 { |
|
170 // Going into fail/shutdown state will override anything currently ongoing or queued |
|
171 response = EReplaceCurrentClearQueue; |
|
172 } |
|
173 } |
|
174 |
|
175 #ifdef _DEBUG |
|
176 TSsmStateName name = aRequest.State().Name(); |
|
177 DEBUGPRINT3(_L("Normal Policy : Transition (Requested State: %S) is allowed with (Response: %d)."), &name, response); |
|
178 #endif |
|
179 |
|
180 return response; |
|
181 } |
|
182 |
|
183 /** |
|
184 Create the command list associated with a sub state transition. |
|
185 |
|
186 @param aState Contains the state and substate that identifies the command list to create |
|
187 @param aReason Contains the reason as given by the request |
|
188 @param aStatus to complete when the operation has finished |
|
189 @panic EInvalidResourceReader if the command list resource reader is invalid |
|
190 @see MSsmStatePolicy::PrepareCommandList |
|
191 */ |
|
192 void CGsaStatePolicyNormal::PrepareCommandList(TSsmState aState, TInt /*aReason*/, TRequestStatus& aStatus) |
|
193 { |
|
194 __ASSERT_DEBUG( iCommandListResourceReader , PanicNow(KPanicGsaNormalState, EInvalidResourceReader)); |
|
195 |
|
196 //Let's start from the beginning if no specific sub state is selected |
|
197 const TUint16 substate = aState.SubState(); |
|
198 const TSsmState state(aState.MainState(), (substate==KSsmAnySubState) ? ESsmNormalSubState : substate); |
|
199 const TInt commandListId = state.SubState(); |
|
200 |
|
201 //Build the commandlist from resource |
|
202 iCommandListResourceReader->PrepareCommandList(commandListId, state, aStatus); |
|
203 } //lint !e1746 Suppress parameter 'aState' could be made const reference |
|
204 |
|
205 /** |
|
206 Cancels asynchronous PrepareCommandList operation. |
|
207 |
|
208 @see MSsmStatePolicy::PrepareCommandListCancel |
|
209 */ |
|
210 void CGsaStatePolicyNormal::PrepareCommandListCancel() |
|
211 { |
|
212 iCommandListResourceReader->PrepareCommandListCancel(); |
|
213 } |
|
214 |
|
215 /** |
|
216 Return the command list once the PrepareCommandList has completed. |
|
217 Ownership of the returned command list is transferred to the caller. |
|
218 @panic EInvalidResourceReader if the command list resource reader is invalid |
|
219 @return The command list created during the preceding PrepareCommandList step |
|
220 */ |
|
221 CSsmCommandList* CGsaStatePolicyNormal::CommandList() |
|
222 { |
|
223 __ASSERT_DEBUG( iCommandListResourceReader , PanicNow(KPanicGsaNormalState, EInvalidResourceReader)); |
|
224 |
|
225 return iCommandListResourceReader->GetCommandList(); |
|
226 } |
|
227 |
|
228 /** |
|
229 Determines the next sub state transition. |
|
230 @param aCurrentTransition Contains the last executed state |
|
231 @param aReason Contains the reason as given by the request |
|
232 @param aError Contains the completion code from the last executed sub-state transition |
|
233 @param aSeverity Contains the severity of the failed command in case the sub-state transition ended with an error |
|
234 @param aNextState The next System State to head for, if there is one |
|
235 @panic EInvalidNormalState if the current state is not Normal |
|
236 @return ETrue if aNextState contains another System State to head for, or |
|
237 EFalse if there is no further transitions to do. |
|
238 @see MSsmStatePolicy::GetNextState |
|
239 */ |
|
240 TBool CGsaStatePolicyNormal::GetNextState(TSsmState aCurrentTransition, TInt /*aReason*/, TInt aError, TInt /*aSeverity*/, TSsmState& aNextState) |
|
241 { |
|
242 __ASSERT_ALWAYS(aCurrentTransition.MainState() == ESsmNormal, PanicNow(KPanicGsaNormalState, EInvalidNormalState)); |
|
243 DEBUGPRINT2(_L("Normal Policy : CLE returned with error : %d after execution of Normal command list."), aError); |
|
244 |
|
245 if (KErrNone != aError) |
|
246 { |
|
247 aNextState = TSsmState(ESsmFail, KSsmAnySubState); |
|
248 #ifdef _DEBUG |
|
249 TSsmStateName name = aNextState.Name(); |
|
250 DEBUGPRINT3(_L("Normal Policy : CLE returned with (error : %d) so moving to Fail State : %S."), aError, &name); |
|
251 #endif |
|
252 return ETrue; |
|
253 } |
|
254 |
|
255 //Boot into RF ON/OFF substate when patchable constant KSsmGracefulOffline is enabled and the state |
|
256 //transition is requested from Startup to Normal with a substate request "KSsmAnySubState" . |
|
257 //This will be executed only once in the bootup. |
|
258 if (IsSsmGracefulOffline() && (aCurrentTransition.SubState() == KSsmAnySubState)) |
|
259 { |
|
260 TInt offlineMode = EBootIntoOnlineModeUninitialized; |
|
261 TInt simStatus = ESimUsable; |
|
262 if ((RProperty::Get(KPSUidStartup, KStartupBootIntoOffline, offlineMode) == KErrNone) && (RProperty::Get(KPSUidStartup, KPSSimStatus, simStatus ) == KErrNone)) |
|
263 { |
|
264 //Boot into RF OFF substate if KStartupBootIntoOffline=EBootIntoOfflineMode or KPSSimStatus!=SimUsable |
|
265 //or else boot in to RF ON substate |
|
266 TUint16 nextSubstate; |
|
267 nextSubstate = (offlineMode == EBootIntoOfflineMode || !(simStatus == ESimUsable)) ? ESsmNormalRfOffSubState : ESsmNormalRfOnSubState; |
|
268 aNextState = TSsmState(ESsmNormal, nextSubstate); |
|
269 #ifdef _DEBUG |
|
270 TSsmStateName name = aNextState.Name(); |
|
271 DEBUGPRINT2(_L("Normal Policy : Transition to next state is : %S"), &name); |
|
272 #endif |
|
273 return ETrue; |
|
274 } |
|
275 else |
|
276 { |
|
277 //Move to Fail state if P&S keys KStartupBootIntoOffline and KPSUidStartup are not defined. |
|
278 aNextState = TSsmState(ESsmFail, KSsmAnySubState); |
|
279 #ifdef _DEBUG |
|
280 TSsmStateName name = aNextState.Name(); |
|
281 DEBUGPRINT3(_L("Normal Policy : P&S key undefined returned with (error : %d) so moving to Fail State : %S."), aError, &name); |
|
282 #endif |
|
283 return ETrue; |
|
284 } |
|
285 } |
|
286 return EFalse; // no more substates to execute |
|
287 |
|
288 } //lint !e1746 Suppress parameter 'aCurrentTransition' could be made const reference |
|
289 |
|
290 /** |
|
291 Callback used by CSsmCommandListResourceReader when a decision needs to be made |
|
292 on whether to include a command in a command list or not. |
|
293 |
|
294 @param aResourceFile Instance of CResourceFile |
|
295 @param aResourceId Resource id of SSM_SYMBIAN_CONDITIONAL_INFORMATION struct for command |
|
296 @return ETrue in case the command needs to be included in command list, else EFalse. |
|
297 |
|
298 @see MSsmConditionalCallback::ConditionalCommandAllowedL |
|
299 */ |
|
300 TBool CGsaStatePolicyNormal::ConditionalCommandAllowedL(CResourceFile& aResourceFile, TInt aResourceId) |
|
301 { |
|
302 TBool ret = EFalse; |
|
303 if (IsSsmGracefulOffline()) |
|
304 { |
|
305 //conditions are evaluated when patchable constant KSsmGracefulOffline is enabled |
|
306 ret = iEvaluator->EvaluateL(aResourceFile, aResourceId); |
|
307 } |
|
308 else |
|
309 { |
|
310 // no commands use 'conditional_information' in Normal state command list. |
|
311 PanicNow(KPanicGsaNormalState, EConditionalInfoNotImplemented); |
|
312 } |
|
313 return ret; |
|
314 } |
|
315 |
|
316 /* |
|
317 Helper function to check whether requested transition is supported or not. |
|
318 @param aRequestedState Requested transition |
|
319 @return ETrue if transition is supported |
|
320 EFalse if transition is not supported |
|
321 */ |
|
322 TBool CGsaStatePolicyNormal::TransitionSupported(const TSsmState& aRequestedState) const |
|
323 { |
|
324 return (iCurrentlySupportedTransitions.Find(aRequestedState) > KErrNotFound); |
|
325 } |