|
1 /* |
|
2 * Copyright (c) 2004 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: Provides methods for queueing and other funtionalities for alarms. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 //debug |
|
21 #include "calendarui_debug.h" |
|
22 |
|
23 #include "CalenSvrAlarmManager.h" |
|
24 #include <calenglobaldata.h> |
|
25 |
|
26 #include "CalendarPrivateCRKeys.h" // includes CalendarInternalCRKeys.h |
|
27 |
|
28 #include <asshdalarm.h> |
|
29 #include <bacntf.h> |
|
30 #include <centralrepository.h> |
|
31 #include <tz.h> |
|
32 #include <calenconstants.h> |
|
33 |
|
34 const TUid KUidAgendaAlarmCategory = { 0x101F4A70 }; |
|
35 |
|
36 |
|
37 // --------------------------------------------------------------------------- |
|
38 // ?description_if_needed |
|
39 // --------------------------------------------------------------------------- |
|
40 // |
|
41 CCalenSvrAlarmManager* CCalenSvrAlarmManager::NewL() |
|
42 { |
|
43 TRACE_ENTRY_POINT; |
|
44 |
|
45 CCalenSvrAlarmManager* self = new( ELeave )CCalenSvrAlarmManager(); |
|
46 CleanupStack::PushL(self); |
|
47 self->ConstructL(); |
|
48 CleanupStack::Pop(self); |
|
49 |
|
50 TRACE_EXIT_POINT; |
|
51 return self; |
|
52 } |
|
53 |
|
54 // --------------------------------------------------------------------------- |
|
55 // ?description_if_needed |
|
56 // --------------------------------------------------------------------------- |
|
57 // |
|
58 CCalenSvrAlarmManager::CCalenSvrAlarmManager() |
|
59 { |
|
60 TRACE_ENTRY_POINT; |
|
61 TRACE_EXIT_POINT; |
|
62 } |
|
63 |
|
64 // --------------------------------------------------------------------------- |
|
65 // ?description_if_needed |
|
66 // --------------------------------------------------------------------------- |
|
67 // |
|
68 void CCalenSvrAlarmManager::ConstructL() |
|
69 { |
|
70 TRACE_ENTRY_POINT; |
|
71 |
|
72 // there is no visible need to keep the session open... |
|
73 // would it break something if we open it only when needed...? |
|
74 User::LeaveIfError( iAlarmServer.Connect() ); |
|
75 |
|
76 // store the current time zone |
|
77 // so we can check if it was changed after system time change |
|
78 iTimeZone = CurrentTimeZoneIdL(); |
|
79 |
|
80 // register locale change listener. This listens for system time |
|
81 // change events. When system time is changed, skipped alarms are checked |
|
82 // and alarms are requeued. |
|
83 TCallBack callback( LocaleChangeCallback, this ); |
|
84 iLocaleChangeNotifier = CEnvironmentChangeNotifier::NewL( CActive::EPriorityStandard, callback ); |
|
85 iLocaleChangeNotifier->Start(); |
|
86 |
|
87 TRACE_EXIT_POINT; |
|
88 } |
|
89 |
|
90 // --------------------------------------------------------------------------- |
|
91 // ?description_if_needed |
|
92 // --------------------------------------------------------------------------- |
|
93 // |
|
94 TUint CCalenSvrAlarmManager::CurrentTimeZoneIdL() const |
|
95 { |
|
96 TRACE_ENTRY_POINT; |
|
97 |
|
98 RTz timeZoneSrv; |
|
99 User::LeaveIfError( timeZoneSrv.Connect() ); |
|
100 CleanupClosePushL( timeZoneSrv ); |
|
101 |
|
102 CTzId* tzID = timeZoneSrv.GetTimeZoneIdL(); |
|
103 TUint id = tzID->TimeZoneNumericID(); |
|
104 delete tzID; |
|
105 |
|
106 CleanupStack::PopAndDestroy(); // close timeZoneSrv |
|
107 |
|
108 TRACE_EXIT_POINT; |
|
109 return id; |
|
110 } |
|
111 |
|
112 // --------------------------------------------------------------------------- |
|
113 // ?description_if_needed |
|
114 // --------------------------------------------------------------------------- |
|
115 // |
|
116 CCalenSvrAlarmManager::~CCalenSvrAlarmManager() |
|
117 { |
|
118 TRACE_ENTRY_POINT; |
|
119 |
|
120 delete iLocaleChangeNotifier; |
|
121 |
|
122 iAlarmServer.Close(); |
|
123 |
|
124 if ( iGlobalData ) |
|
125 { |
|
126 iGlobalData->Release(); |
|
127 } |
|
128 |
|
129 TRACE_EXIT_POINT; |
|
130 } |
|
131 |
|
132 // --------------------------------------------------------------------------- |
|
133 // ?description_if_needed |
|
134 // --------------------------------------------------------------------------- |
|
135 // |
|
136 TInt CCalenSvrAlarmManager::LocaleChangeCallback(TAny* aThisPtr) |
|
137 { |
|
138 TRACE_ENTRY_POINT; |
|
139 TInt retVal = static_cast<CCalenSvrAlarmManager*>( aThisPtr )->HandleLocaleChange(); |
|
140 TRACE_EXIT_POINT; |
|
141 return retVal; |
|
142 } |
|
143 |
|
144 // --------------------------------------------------------------------------- |
|
145 // ?description_if_needed |
|
146 // --------------------------------------------------------------------------- |
|
147 // |
|
148 TInt CCalenSvrAlarmManager::HandleLocaleChange() |
|
149 { |
|
150 TRACE_ENTRY_POINT; |
|
151 if( iLocaleChangeNotifier->Change() & EChangesSystemTime ) |
|
152 { |
|
153 PIM_TRAPD_HANDLE( CheckSkippedAlarmsL(); ) |
|
154 PIM_TRAPD_HANDLE( ReQueueAlarmsL(); ) |
|
155 } |
|
156 TRACE_EXIT_POINT; |
|
157 return 0; |
|
158 } |
|
159 |
|
160 // --------------------------------------------------------------------------- |
|
161 // ?description_if_needed |
|
162 // --------------------------------------------------------------------------- |
|
163 // |
|
164 void CCalenSvrAlarmManager::CheckSkippedAlarmsL() |
|
165 { |
|
166 TRACE_ENTRY_POINT; |
|
167 |
|
168 // remove alarms from alarm server |
|
169 RArray<TAlarmId> skippedAlarms; |
|
170 CleanupClosePushL( skippedAlarms ); |
|
171 GetSkippedAgendaAlarmsL( skippedAlarms ); |
|
172 |
|
173 // fetch the current time zone to compare it with the old one |
|
174 const TUint newTimeZone = CurrentTimeZoneIdL(); |
|
175 const TBool tzChanged( newTimeZone != iTimeZone ); |
|
176 iTimeZone = newTimeZone; |
|
177 |
|
178 if( skippedAlarms.Count() ) |
|
179 { |
|
180 for(TInt i(0); i < skippedAlarms.Count(); i++) |
|
181 { |
|
182 iAlarmServer.AlarmDelete( skippedAlarms[i] ); |
|
183 } |
|
184 SetSystemTimeChangedFlagL( KCalenLostAlarms ); |
|
185 } |
|
186 else |
|
187 { |
|
188 // there wasn't any skipped alarms, but time zone was changed |
|
189 if( tzChanged ) |
|
190 { |
|
191 // value KCalenTimeZoneChanged in KCalendarLostAlarm indicates a time zone change |
|
192 SetSystemTimeChangedFlagL( KCalenTimeZoneChanged ); |
|
193 } |
|
194 } |
|
195 |
|
196 CleanupStack::PopAndDestroy( &skippedAlarms ); // close skippedAlarms |
|
197 |
|
198 TRACE_EXIT_POINT; |
|
199 } |
|
200 |
|
201 // --------------------------------------------------------------------------- |
|
202 // Open an entry view to re-queue calendar alarms. |
|
203 // --------------------------------------------------------------------------- |
|
204 // |
|
205 void CCalenSvrAlarmManager::ReQueueAlarmsL() |
|
206 { |
|
207 TRACE_ENTRY_POINT; |
|
208 if( !iOpeningEntryView ) |
|
209 { |
|
210 // leave only after the iOpeningEntryView has been set back to EFalse! |
|
211 iOpeningEntryView = ETrue; |
|
212 |
|
213 |
|
214 // An entry view is created to make sure that the calendar |
|
215 // alarms get queued. The entry view creation within the |
|
216 // global data is done asyncronously. |
|
217 TRAPD( error, |
|
218 // Is the global data already constructed? |
|
219 CCalenGlobalData* existingGD = CCalenGlobalData::Instance(); |
|
220 CCalenGlobalData* gData = NULL; |
|
221 if ( !existingGD ) |
|
222 { |
|
223 // If not create the global data, but using |
|
224 // this class as the observer. |
|
225 // Context change notifier is NULL. |
|
226 iGlobalData = CCalenGlobalData::NewL( *this, NULL ); |
|
227 gData = iGlobalData; |
|
228 } |
|
229 else |
|
230 { |
|
231 gData = existingGD; |
|
232 CleanupReleasePushL( *existingGD ); |
|
233 } |
|
234 |
|
235 // Create the session |
|
236 gData->CalSessionL(); |
|
237 |
|
238 // Get the entryView, if this is null it the entry view |
|
239 // will be created asyncronously. |
|
240 gData->EntryViewL(); |
|
241 |
|
242 if ( existingGD ) |
|
243 { |
|
244 // If the global data already existed, it can be |
|
245 // released here else it will be released upon the |
|
246 // callback being completed. |
|
247 CleanupStack::PopAndDestroy(); // existingGD |
|
248 } |
|
249 ); |
|
250 |
|
251 iOpeningEntryView = EFalse; |
|
252 User::LeaveIfError( error ); |
|
253 } |
|
254 |
|
255 TRACE_EXIT_POINT; |
|
256 } |
|
257 |
|
258 // ----------------------------------------------------------------------------- |
|
259 // CCalenSvrAlarmManager::Completed |
|
260 // Called when the construction of the entry view |
|
261 // has completed. |
|
262 // ----------------------------------------------------------------------------- |
|
263 // |
|
264 void CCalenSvrAlarmManager::Completed(TInt /*aError*/) |
|
265 { |
|
266 // In this instance, interest is in the |
|
267 // entry view being created. Therefore |
|
268 // the global data can be released. |
|
269 iGlobalData->Release(); |
|
270 iGlobalData = NULL; |
|
271 } |
|
272 |
|
273 // ----------------------------------------------------------------------------- |
|
274 // CCalenSvrAlarmManager::NotifyProgress() |
|
275 // Returns if progress notifications are |
|
276 // required. As there is no interest in |
|
277 // the progress returns EFalse. |
|
278 // ----------------------------------------------------------------------------- |
|
279 // |
|
280 TBool CCalenSvrAlarmManager::NotifyProgress() |
|
281 { |
|
282 TRACE_ENTRY_POINT; |
|
283 |
|
284 return EFalse; |
|
285 |
|
286 TRACE_EXIT_POINT; |
|
287 } |
|
288 |
|
289 // ----------------------------------------------------------------------------- |
|
290 // CCalenSvrAlarmManager::Progress |
|
291 // Intentionally empty as there is no interest in the |
|
292 // progress of the entry view creation |
|
293 // ----------------------------------------------------------------------------- |
|
294 // |
|
295 void CCalenSvrAlarmManager::Progress(TInt /*aPercentageCompleted*/) |
|
296 { |
|
297 TRACE_ENTRY_POINT; |
|
298 TRACE_EXIT_POINT; |
|
299 } |
|
300 |
|
301 // --------------------------------------------------------------------------- |
|
302 // ?description_if_needed |
|
303 // --------------------------------------------------------------------------- |
|
304 // |
|
305 void CCalenSvrAlarmManager::SetSystemTimeChangedFlagL(TInt aFlag) |
|
306 { |
|
307 TRACE_ENTRY_POINT; |
|
308 |
|
309 CRepository* repository = CRepository::NewL( KCRUidCalendar ); |
|
310 CleanupStack::PushL( repository ); |
|
311 |
|
312 User::LeaveIfError( repository->Set( KCalendarLostAlarm, aFlag ) ); |
|
313 |
|
314 CleanupStack::PopAndDestroy(); // repository |
|
315 |
|
316 TRACE_EXIT_POINT; |
|
317 } |
|
318 |
|
319 // --------------------------------------------------------------------------- |
|
320 // ?description_if_needed |
|
321 // --------------------------------------------------------------------------- |
|
322 // |
|
323 void CCalenSvrAlarmManager::GetSkippedAgendaAlarmsL(RArray<TAlarmId>& aSkippedAlarms) const |
|
324 { |
|
325 TRACE_ENTRY_POINT; |
|
326 |
|
327 RArray<TAlarmId> alarmIds; |
|
328 CleanupClosePushL( alarmIds ); |
|
329 |
|
330 TRAPD( err, |
|
331 iAlarmServer.GetAlarmIdListForCategoryL( KUidAgendaAlarmCategory, alarmIds ); ) |
|
332 |
|
333 if( err == KErrNone ) |
|
334 { |
|
335 TTime now; |
|
336 now.HomeTime(); |
|
337 // ignoring seconds and microseconds. |
|
338 TDateTime tmp( now.DateTime() ); |
|
339 tmp.SetSecond( 0 ); |
|
340 tmp.SetMicroSecond( 0 ); |
|
341 now = tmp; |
|
342 |
|
343 for(TInt i(0); i < alarmIds.Count(); i++) |
|
344 { |
|
345 TASShdAlarm alarm; |
|
346 iAlarmServer.GetAlarmDetails( alarmIds[i], alarm ); |
|
347 |
|
348 if( alarm.IsFloating() && // fixed alarms won't expire due to time or time zone changes |
|
349 alarm.State() != EAlarmStateNotified && |
|
350 alarm.NextDueTime() < now ) |
|
351 { |
|
352 aSkippedAlarms.Append( alarmIds[i] ); |
|
353 } |
|
354 } |
|
355 } |
|
356 |
|
357 CleanupStack::PopAndDestroy( &alarmIds ); // close alarmIds array |
|
358 |
|
359 TRACE_EXIT_POINT; |
|
360 } |
|
361 |
|
362 |
|
363 // End of File |