|
1 // Copyright (c) 1997-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 // Multialarm version of Alert Server |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 */ |
|
21 |
|
22 #include "EIKALSRV.H" |
|
23 |
|
24 // System includes |
|
25 |
|
26 #include "EIKSRV.PAN" |
|
27 #include <eiksrv.h> |
|
28 #include <asaltdefs.h> |
|
29 #include <asshdalarm.h> |
|
30 |
|
31 // User includes |
|
32 #include "EIKALSUP.H" |
|
33 #include "EIKSVFTY.H" |
|
34 #include "EIKPANIC.H" |
|
35 #include "EIKSRV.PAN" |
|
36 |
|
37 |
|
38 // Security constants |
|
39 |
|
40 const TUint8 KPolicyElementSID = 0; |
|
41 |
|
42 const TInt KAlarmServerSid = 0x101f5027; |
|
43 |
|
44 const TUint KRangeCount = 6; |
|
45 |
|
46 const TInt KEikServAlarmAlertServerRanges[KRangeCount] = |
|
47 { |
|
48 EASAltOpCodeNotify, |
|
49 EASAltOpCodeVisible, |
|
50 EASAltOpCodeGetUserTime, |
|
51 EASAltOpCodeStartPlayingSound, |
|
52 EASAltOpCodeGetEndQuietTime, |
|
53 EASAltOpCodeLast, |
|
54 }; |
|
55 |
|
56 const TUint8 KElementsIndex[KRangeCount] = |
|
57 { |
|
58 CPolicyServer::EAlwaysPass, //Always passing no capability required (Notify, NotifyCancel) |
|
59 KPolicyElementSID, //Requires SID to be of Alarmserver ie.0x101f5027 (Visible,SetState, SetAlarm, SetDeferTime) |
|
60 CPolicyServer::EAlwaysPass, //Always passing no capability required (GetUserTime, Logon) |
|
61 KPolicyElementSID, //Requires SID to be of Alarmserver ie.0x101f5027 (StartPlayingSound, StopPlayingSound, VisibleAll, SetStateAll, StopPlayingSoundAll, DeleteAlarm) |
|
62 CPolicyServer::EAlwaysPass, //Always passing no capability required (GetEndQuietTime, GetMaxAlarms) |
|
63 CPolicyServer::ENotSupported, //Not Supported [EASAltOpCodeLast-End] |
|
64 }; |
|
65 |
|
66 const CPolicyServer::TPolicyElement KPolicyElements[] = |
|
67 { |
|
68 {_INIT_SECURITY_POLICY_S0(KAlarmServerSid), CPolicyServer::EFailClient} |
|
69 }; |
|
70 |
|
71 const CPolicyServer::TPolicy KEikServAlarmAlertServerPolicy = |
|
72 { |
|
73 CPolicyServer::EAlwaysPass, |
|
74 KRangeCount, |
|
75 KEikServAlarmAlertServerRanges, |
|
76 KElementsIndex, |
|
77 KPolicyElements |
|
78 }; |
|
79 |
|
80 |
|
81 // |
|
82 // class CEikServAlarmAlertServer |
|
83 // |
|
84 |
|
85 /** |
|
86 Constructor. |
|
87 */ |
|
88 CEikServAlarmAlertServer::CEikServAlarmAlertServer(TInt aPriority, MEikServAlarmFactory& aAlarmControlFactory, TInt aMaxAlarms) : |
|
89 CPolicyServer(aPriority, KEikServAlarmAlertServerPolicy), |
|
90 iAlarmControlFactory(aAlarmControlFactory), |
|
91 iMaxAlarms(aMaxAlarms) |
|
92 { |
|
93 __ASSERT_ALWAYS(aMaxAlarms > 0, Panic(EEsPanicAlarmAlert)); |
|
94 } |
|
95 |
|
96 /** |
|
97 Creates a new Alert Server. When an alarm expires, the Alert Server will request an Alarm Control from |
|
98 the Alarm Control factory. The number of Alarm Controls at any instance in time will not exceed the specified |
|
99 maximum limit. |
|
100 |
|
101 @param aAlarmControlFactory Pointer to the Alarm Control factory. The Alert Server does not take ownership. |
|
102 @param aMaxAlarms Maximum number of concurrent Alarm Controls that the Alarm Control factory will be requested to manufacture. |
|
103 @return Pointer to the Alert Server. |
|
104 */ |
|
105 EXPORT_C CEikServAlarmAlertServer* CEikServAlarmAlertServer::NewL(MEikServAlarmFactory* aAlarmControlFactory, TInt aMaxAlarms) |
|
106 { |
|
107 CEikServAlarmAlertServer* server = new (ELeave) CEikServAlarmAlertServer(EActivePriorityIpcEventsHigh, *aAlarmControlFactory, aMaxAlarms); |
|
108 |
|
109 CleanupStack::PushL(server); |
|
110 server->StartL(KAlarmAlertServerName); |
|
111 CleanupStack::Pop(server); |
|
112 |
|
113 return server; |
|
114 } |
|
115 |
|
116 |
|
117 /** |
|
118 Creates a new Alert Server. When an alarm expires, the Alert Server will request an Alarm Control from |
|
119 the Alarm Control factory. There is only one Alarm Control at any instance in time. |
|
120 |
|
121 @param aAlarmControlFactory Pointer to the Alarm Control factory. The Alert Server does not take ownership. |
|
122 @return Pointer to the Alert Server. |
|
123 */ |
|
124 EXPORT_C CEikServAlarmAlertServer* CEikServAlarmAlertServer::NewL(MEikServAlarmFactory* aAlarmControlFactory) |
|
125 { |
|
126 return NewL(aAlarmControlFactory, 1); |
|
127 } |
|
128 |
|
129 CEikServAlarmAlertServer::~CEikServAlarmAlertServer() |
|
130 { |
|
131 iSession = NULL; |
|
132 } |
|
133 |
|
134 CSession2* CEikServAlarmAlertServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const |
|
135 { |
|
136 const TVersion KAlarmAlertServerVersion(KASAltVersionMajor, KASAltVersionMinor, KASAltVersionBuild); |
|
137 if (iSession) |
|
138 User::Leave(KErrArgument); // There should only ever be one session with the alarm alert server. |
|
139 |
|
140 if (!User::QueryVersionSupported(KAlarmAlertServerVersion, aVersion) || aVersion.iMajor <=2) //Current implementation doesn't support old clients |
|
141 User::Leave(KErrNotSupported); |
|
142 |
|
143 CEikServAlarmAlertSession* const session = CEikServAlarmAlertSession::NewL(iAlarmControlFactory, iMaxAlarms); |
|
144 const_cast<CEikServAlarmAlertServer*>(this)->iSession = session; // iSession does not *own* what it points to |
|
145 return session; |
|
146 } |
|
147 |
|
148 |
|
149 EXPORT_C void CEikServAlarmAlertServer::TaskKeyPressedL() |
|
150 { |
|
151 if (iSession) |
|
152 iSession->TaskKeyPressedL(); |
|
153 } |
|
154 |
|
155 |
|
156 EXPORT_C void CEikServAlarmAlertServer::HandleSwitchOnEvent() |
|
157 { |
|
158 if (iSession) |
|
159 iSession->HandleSwitchOnEvent(); |
|
160 } |
|
161 |
|
162 |
|
163 EXPORT_C void CEikServAlarmAlertServer::SetQuietPeriodL(TTime aQuietPeriodEndTime) |
|
164 { |
|
165 if (iSession) |
|
166 iSession->SetQuietPeriodL(aQuietPeriodEndTime); |
|
167 } |
|
168 |
|
169 |
|
170 EXPORT_C void CEikServAlarmAlertServer::ClearAllAlarmsL() |
|
171 { |
|
172 if (iSession) |
|
173 iSession->ClearAllAlarmsL(); |
|
174 } |
|
175 |
|
176 |
|
177 // |
|
178 // class CEikServAlarmAlertSession |
|
179 // |
|
180 |
|
181 |
|
182 CEikServAlarmAlertSession* CEikServAlarmAlertSession::NewL(MEikServAlarmFactory& aAlarmControlFactory, TInt aMaxAlarms) |
|
183 { |
|
184 CEikServAlarmAlertSession* const session = new(ELeave) CEikServAlarmAlertSession(aAlarmControlFactory, aMaxAlarms); |
|
185 CleanupStack::PushL(session); |
|
186 session->ConstructL(); |
|
187 CleanupStack::Pop(session); |
|
188 return session; |
|
189 } |
|
190 |
|
191 |
|
192 CEikServAlarmAlertSession::CEikServAlarmAlertSession(MEikServAlarmFactory& aAlarmControlFactory, TInt aMaxAlarms) : |
|
193 iVisible(EFalse), iAlarmControlFactory(aAlarmControlFactory), iMaxAlarms(aMaxAlarms) |
|
194 { |
|
195 } |
|
196 |
|
197 |
|
198 CEikServAlarmAlertSession::~CEikServAlarmAlertSession() |
|
199 { |
|
200 CEikServAlarmAlertServer* const server = AlarmAlertServer(); |
|
201 if (server) |
|
202 server->SessionDied(); |
|
203 |
|
204 // Delete all the alarm supervisors |
|
205 const TInt count = iAlarmSupervisors.Count(); |
|
206 for(TInt i = 0; i < count; i++) |
|
207 delete iAlarmSupervisors[i]; |
|
208 |
|
209 iAlarmSupervisors.Reset(); |
|
210 iResponseQueue.Reset(); |
|
211 } |
|
212 |
|
213 |
|
214 void CEikServAlarmAlertSession::ConstructL() |
|
215 { |
|
216 if (iMaxAlarms == 1) |
|
217 { |
|
218 CEikAlmControlSupervisor* alarmSupervisor = CEikAlmControlSupervisor::NewLC(iAlarmControlFactory, this); |
|
219 iAlarmSupervisors.AppendL(alarmSupervisor); |
|
220 CleanupStack::Pop(alarmSupervisor); |
|
221 } |
|
222 } |
|
223 |
|
224 |
|
225 void CEikServAlarmAlertSession::TaskKeyPressedL() |
|
226 { |
|
227 const TInt count = iAlarmSupervisors.Count(); |
|
228 for(TInt idx = 0; idx < count; idx++) |
|
229 { |
|
230 if (iAlarmSupervisors[idx]->IsVisible()) |
|
231 iAlarmSupervisors[idx]->CmdTaskAwayFromAlarmL(); |
|
232 } |
|
233 } |
|
234 |
|
235 |
|
236 void CEikServAlarmAlertSession::HandleSwitchOnEvent() |
|
237 { |
|
238 const TInt count = iAlarmSupervisors.Count(); |
|
239 for(TInt idx = 0; idx < count; idx++) |
|
240 iAlarmSupervisors[idx]->SynchronizeCountDownTimer(); |
|
241 } |
|
242 |
|
243 |
|
244 void CEikServAlarmAlertSession::ServiceL(const RMessage2 &aMessage) |
|
245 { |
|
246 TInt idSlot(0); |
|
247 TInt idx(0); |
|
248 |
|
249 const TInt opCode = aMessage.Function(); |
|
250 switch (opCode) |
|
251 { |
|
252 case EASAltOpCodeLogon: //Will be completed automatically when session dies. |
|
253 break; |
|
254 |
|
255 case EASAltOpCodeNotify: |
|
256 if (!iMessage.IsNull()) // don't accept second pending notification request |
|
257 { |
|
258 _LIT(KPanicCategory,"EikSrv-ASAlt"); |
|
259 aMessage.Panic(KPanicCategory, EEsPanicAlarmAlert); |
|
260 } |
|
261 else |
|
262 { |
|
263 if (iResponseQueue.Count() == 0) |
|
264 iMessage = aMessage; |
|
265 else |
|
266 { |
|
267 aMessage.WriteL(0, TPckgC<TAlarmId>(iResponseQueue[0].AlarmId())); |
|
268 aMessage.WriteL(1, TPckgC<TTime>(iResponseQueue[0].TimeToSnooze())); |
|
269 aMessage.Complete(iResponseQueue[0].ResponseCode()); |
|
270 iResponseQueue.Remove(0); |
|
271 } |
|
272 } |
|
273 break; |
|
274 |
|
275 case EASAltOpCodeNotifyCancel: |
|
276 if (!iMessage.IsNull()) |
|
277 { |
|
278 iMessage.Complete(KErrCancel); |
|
279 aMessage.Complete(KErrNone); |
|
280 } |
|
281 else |
|
282 aMessage.Complete(KErrNone); |
|
283 break; |
|
284 |
|
285 case EASAltOpCodeSetAlarm: |
|
286 { |
|
287 TASShdAlarm alarm; |
|
288 TPckg<TASShdAlarm> pAlarm(alarm); |
|
289 aMessage.ReadL(0,pAlarm); |
|
290 |
|
291 if( (idx = FindAlarm(alarm.Id())) >=0 ) |
|
292 { |
|
293 iAlarmSupervisors[idx]->ServiceL(aMessage); |
|
294 aMessage.Complete(KErrNone); |
|
295 return; |
|
296 } |
|
297 |
|
298 // alarm was not found |
|
299 if (iAlarmSupervisors.Count() >= iMaxAlarms) |
|
300 { |
|
301 // and no room to create new alarm, return KErrNotFound to client to indikate this |
|
302 aMessage.Complete(KErrNotFound); |
|
303 return; |
|
304 } |
|
305 |
|
306 CEikAlmControlSupervisor* alarmSupervisor = CEikAlmControlSupervisor::NewLC(iAlarmControlFactory, this); |
|
307 iAlarmSupervisors.AppendL(alarmSupervisor); |
|
308 CleanupStack::Pop(alarmSupervisor); |
|
309 alarmSupervisor->ServiceL(aMessage); |
|
310 aMessage.Complete(KErrNone); |
|
311 } |
|
312 break; |
|
313 |
|
314 case EASAltOpCodeGetMaxAlarms: |
|
315 aMessage.WriteL(0,TPckgC<TInt>(iMaxAlarms)); |
|
316 aMessage.Complete(KErrNone); |
|
317 break; |
|
318 |
|
319 case EASAltOpCodeSetState: |
|
320 case EASAltOpCodeStartPlayingSound: |
|
321 case EASAltOpCodeVisible: |
|
322 idSlot = 1; |
|
323 //fall through |
|
324 case EASAltOpCodeStopPlayingSound: |
|
325 { |
|
326 const TAlarmId alarmId = (idSlot==0 ? aMessage.Int0() : aMessage.Int1()); |
|
327 if ((idx = FindAlarm(alarmId)) >=0) |
|
328 { |
|
329 iAlarmSupervisors[idx]->ServiceL(aMessage); |
|
330 aMessage.Complete(KErrNone); |
|
331 } |
|
332 else //alarm was not found |
|
333 aMessage.Complete(KErrNotFound); |
|
334 } |
|
335 break; |
|
336 |
|
337 case EASAltOpCodeVisibleAll: |
|
338 case EASAltOpCodeSetStateAll: |
|
339 case EASAltOpCodeStopPlayingSoundAll: |
|
340 for(idx = 0; idx < iAlarmSupervisors.Count(); idx++) |
|
341 iAlarmSupervisors[idx]->ServiceL(aMessage); |
|
342 |
|
343 aMessage.Complete(KErrNone); |
|
344 break; |
|
345 |
|
346 case EASAltOpCodeSetDeferTime: |
|
347 { |
|
348 iQuietPeriodEndTime = TTime(MAKE_TUINT64(aMessage.Int1(), aMessage.Int0())); |
|
349 aMessage.Complete(KErrNone); |
|
350 } |
|
351 break; |
|
352 |
|
353 case EASAltOpCodeGetEndQuietTime: |
|
354 aMessage.WriteL(0,TPckgC<TTime>(iQuietPeriodEndTime)); |
|
355 aMessage.Complete(KErrNone); |
|
356 break; |
|
357 |
|
358 case EASAltOpCodeDeleteAlarmAll: |
|
359 case EASAltOpCodeDeleteAlarm: |
|
360 DeleteAlarmL(aMessage); |
|
361 break; |
|
362 |
|
363 default: |
|
364 aMessage.Complete(KErrNotSupported); |
|
365 break; |
|
366 } |
|
367 |
|
368 UpdateVisibility(); |
|
369 } |
|
370 |
|
371 |
|
372 CEikServAlarmAlertServer* CEikServAlarmAlertSession::AlarmAlertServer() const |
|
373 { |
|
374 return static_cast<CEikServAlarmAlertServer*>( const_cast<CServer2*>(Server()) ); |
|
375 } |
|
376 |
|
377 |
|
378 void CEikServAlarmAlertSession::UpdateVisibility() |
|
379 { |
|
380 iVisible = EFalse; |
|
381 |
|
382 const TInt count = iAlarmSupervisors.Count(); |
|
383 for(TInt i = 0; i < count; i++) |
|
384 iVisible |= iAlarmSupervisors[i]->IsVisible(); |
|
385 } |
|
386 |
|
387 |
|
388 |
|
389 void CEikServAlarmAlertSession::RespondEventL(TASAltAlertServerResponse aCode) |
|
390 { |
|
391 RespondEventL(aCode, KNullAlarmId); |
|
392 } |
|
393 |
|
394 |
|
395 void CEikServAlarmAlertSession::RespondEventL(TASAltAlertServerResponse aCode, TAlarmId aId, TTime aTimeToSnooze) |
|
396 { |
|
397 if (iMessage.IsNull()) // if no request pending |
|
398 QueueEventL(aCode, aId, aTimeToSnooze); |
|
399 else |
|
400 { |
|
401 iMessage.WriteL(0,TPckgC<TAlarmId>(aId)); |
|
402 iMessage.WriteL(1,TPckgC<TTime>(aTimeToSnooze)); |
|
403 iMessage.Complete(aCode); |
|
404 } |
|
405 } |
|
406 |
|
407 |
|
408 void CEikServAlarmAlertSession::QueueEventL(TASAltAlertServerResponse& aCode, TAlarmId& aId, TTime& aTimeToSnooze) |
|
409 { |
|
410 if (iResponseQueue.Count() < KAlertResponseQueueSize) //ignore new response if queue is full |
|
411 { |
|
412 TAlarmResponse response(aCode, aId, aTimeToSnooze); |
|
413 iResponseQueue.AppendL(response); |
|
414 } |
|
415 } |
|
416 |
|
417 |
|
418 void CEikServAlarmAlertSession::ClearAllAlarmsL() |
|
419 { |
|
420 RespondEventL(EASAltAlertServerResponseClearAll); |
|
421 } |
|
422 |
|
423 |
|
424 void CEikServAlarmAlertSession::SetQuietPeriodL(TTime aQuietPeriodEndTime) |
|
425 { |
|
426 iQuietPeriodEndTime = aQuietPeriodEndTime; |
|
427 |
|
428 RespondEventL(EASAltAlertServerResponseQuietPeriod); |
|
429 } |
|
430 |
|
431 |
|
432 TInt CEikServAlarmAlertSession::FindAlarm(TAlarmId aAlarmId) const |
|
433 { |
|
434 if (iMaxAlarms == 1) |
|
435 return 0; |
|
436 |
|
437 const TInt count = iAlarmSupervisors.Count(); |
|
438 for(TInt i = 0; i < count; i++) |
|
439 { |
|
440 if (iAlarmSupervisors[i]->AlarmId() == aAlarmId) |
|
441 return i; |
|
442 } |
|
443 |
|
444 return KErrNotFound; |
|
445 } |
|
446 |
|
447 |
|
448 void CEikServAlarmAlertSession::DeleteAlarmL(const RMessage2& aMessage) |
|
449 { |
|
450 if (iMaxAlarms == 1) |
|
451 { |
|
452 aMessage.Complete(KErrNone); |
|
453 return; |
|
454 } |
|
455 |
|
456 TInt idx = 0; |
|
457 if (aMessage.Function() == EASAltOpCodeDeleteAlarmAll) // delete all alarms |
|
458 { |
|
459 const TInt cnt = iAlarmSupervisors.Count(); |
|
460 for(idx = 0; idx < cnt; idx++) |
|
461 delete iAlarmSupervisors[idx]; |
|
462 |
|
463 iAlarmSupervisors.Reset(); |
|
464 aMessage.Complete(KErrNone); |
|
465 return; |
|
466 } |
|
467 else //delete particular alarm |
|
468 { |
|
469 const TAlarmId alarmId(aMessage.Int0()); |
|
470 if( (idx = FindAlarm(alarmId)) >=0 ) // found! |
|
471 { |
|
472 delete iAlarmSupervisors[idx]; |
|
473 iAlarmSupervisors.Remove(idx); |
|
474 aMessage.Complete(KErrNone); |
|
475 } |
|
476 else // not found |
|
477 aMessage.Complete(KErrNotFound); |
|
478 } |
|
479 } |
|
480 |
|
481 |
|
482 TAlarmResponse::TAlarmResponse(TASAltAlertServerResponse aCode, TAlarmId aId, TTime aTime) : |
|
483 iCode(aCode), |
|
484 iId(aId), |
|
485 iTime(aTime) |
|
486 { |
|
487 } |
|
488 |
|
489 |
|
490 TASAltAlertServerResponse TAlarmResponse::ResponseCode() const |
|
491 { |
|
492 return iCode; |
|
493 } |
|
494 |
|
495 |
|
496 TAlarmId TAlarmResponse::AlarmId() const |
|
497 { |
|
498 return iId; |
|
499 } |
|
500 |
|
501 |
|
502 TTime TAlarmResponse::TimeToSnooze() const |
|
503 { |
|
504 return iTime; |
|
505 } |
|
506 |