|
1 // Copyright (c) 1998-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 |
|
17 #include "agmtlsproxy.h" |
|
18 #include "agmcalendartime.h" |
|
19 |
|
20 #include <vtzrules.h> |
|
21 #include <tzconverter.h> |
|
22 |
|
23 const TInt KMinYear = 0; |
|
24 const TInt KMaxYear = 9999; |
|
25 |
|
26 CAgnTlsProxy* CAgnTlsProxy::NewL(TAgnTlsTzRulesType aTzRulesType) |
|
27 { |
|
28 CAgnTlsProxy* self = new (ELeave) CAgnTlsProxy(); |
|
29 CleanupStack::PushL(self); |
|
30 self->ConstructL(aTzRulesType); |
|
31 CleanupStack::Pop(self); |
|
32 return self; |
|
33 } |
|
34 |
|
35 CAgnTlsProxy::~CAgnTlsProxy() |
|
36 { |
|
37 delete iCurrentTzChangeObserver; |
|
38 delete iTzRulesChangeObserver; |
|
39 delete iTimeConverter; |
|
40 delete iFixedTimeMode; |
|
41 delete iFloatingTimeMode; |
|
42 delete iTlsTzRules; |
|
43 iTzServer.Close(); |
|
44 iObservers.Reset(); |
|
45 } |
|
46 |
|
47 EXPORT_C CAgnTlsProxy* CAgnTlsProxy::CreateL(TAgnTlsTzRulesType aTzRulesType) |
|
48 { |
|
49 CAgnTlsProxy* self = static_cast<CAgnTlsProxy*>(Dll::Tls()); |
|
50 |
|
51 if (!self) |
|
52 { |
|
53 self = CAgnTlsProxy::NewL(aTzRulesType); |
|
54 Dll::SetTls(self); |
|
55 } |
|
56 |
|
57 ++self->iRefCount; |
|
58 |
|
59 return self; |
|
60 } |
|
61 |
|
62 EXPORT_C void CAgnTlsProxy::Release(TAny* /*aRef*/) |
|
63 { |
|
64 CAgnTlsProxy* self = static_cast<CAgnTlsProxy*>(Dll::Tls()); |
|
65 |
|
66 if(self) |
|
67 { |
|
68 if (--self->iRefCount <= 0) |
|
69 { |
|
70 __ASSERT_DEBUG(self->iRefCount == 0, User::Invariant()); |
|
71 |
|
72 delete self; |
|
73 Dll::FreeTls(); |
|
74 } |
|
75 } |
|
76 } |
|
77 |
|
78 CAgnTlsProxy::CAgnTlsProxy() |
|
79 :iRefCount(0) |
|
80 { |
|
81 } |
|
82 |
|
83 void CAgnTlsProxy::ConstructL(TAgnTlsTzRulesType aTzRulesType) |
|
84 { |
|
85 User::LeaveIfError(iTzServer.Connect()); |
|
86 iTimeConverter = CTzConverter::NewL(iTzServer); |
|
87 iFixedTimeMode = new (ELeave) TAgnCalendarFixedTimeMode(*iTimeConverter); |
|
88 iFloatingTimeMode = new (ELeave) TAgnCalendarFloatingTimeMode(*iTimeConverter); |
|
89 switch(aTzRulesType) |
|
90 { |
|
91 case TAgnTlsTzRulesType_Client: |
|
92 iTlsTzRules = new (ELeave) CAgnClientTlsTzRules(); |
|
93 break; |
|
94 case TAgnTlsTzRulesType_Server: |
|
95 iTlsTzRules = new (ELeave) CAgnServerTlsTzRules(); |
|
96 break; |
|
97 default: |
|
98 iTlsTzRules = NULL; |
|
99 break; |
|
100 } |
|
101 iCurrentTzChangeObserver = CAgnTzChangeObserver::NewL(*this, NTzUpdate::ECurrentTimeZoneId); |
|
102 iTzRulesChangeObserver = CAgnTzChangeObserver::NewL(*this, NTzUpdate::ETzRulesChange);; |
|
103 } |
|
104 |
|
105 const TAgnCalendarFixedTimeMode& CAgnTlsProxy::FixedTimeMode() const |
|
106 { |
|
107 return *iFixedTimeMode; |
|
108 } |
|
109 |
|
110 const TAgnCalendarFloatingTimeMode& CAgnTlsProxy::FloatingTimeMode() const |
|
111 { |
|
112 return *iFloatingTimeMode; |
|
113 } |
|
114 |
|
115 EXPORT_C RTz& CAgnTlsProxy::TzServer() |
|
116 { |
|
117 return iTzServer; |
|
118 } |
|
119 |
|
120 TUint16 CAgnTlsProxy::CurrentTzId() const |
|
121 { |
|
122 return iTimeConverter->CurrentTzId(); |
|
123 } |
|
124 |
|
125 CTzRules* CAgnTlsProxy::GetZoneForRulesL(const CTzRules& aRules) |
|
126 { |
|
127 CTzRules* foundTzRules = NULL; |
|
128 if(iTlsTzRules) |
|
129 { |
|
130 foundTzRules = iTlsTzRules->GetSharedTzRulesL(aRules); |
|
131 } |
|
132 return foundTzRules; |
|
133 } |
|
134 |
|
135 void CAgnTlsProxy::ReferenceRemoved(const CTzRules* aReference) |
|
136 { |
|
137 if(iTlsTzRules) |
|
138 { |
|
139 iTlsTzRules->ReferenceRemoved(aReference); |
|
140 } |
|
141 } |
|
142 |
|
143 EXPORT_C CTzRules* CAgnTlsProxy::GetCurrentSystemTzRulesL() |
|
144 { |
|
145 if(iTlsTzRules) |
|
146 { |
|
147 return iTlsTzRules->GetCurrentSystemTzRulesL(iTzServer); |
|
148 } |
|
149 return NULL; |
|
150 } |
|
151 |
|
152 void CAgnTlsProxy::HandleTzPropertyChangeL(NTzUpdate::TPropertyKeys aTzChangePropertyKey) |
|
153 { |
|
154 if(iTlsTzRules) |
|
155 { |
|
156 iTlsTzRules->SystemTzZoneChangedL(iTzServer, aTzChangePropertyKey); |
|
157 } |
|
158 |
|
159 // Notify observers |
|
160 |
|
161 __ASSERT_DEBUG(aTzChangePropertyKey==NTzUpdate::ECurrentTimeZoneId || aTzChangePropertyKey==NTzUpdate::ETzRulesChange, User::Invariant()); |
|
162 const TInt KObserverCount(iObservers.Count()); |
|
163 if(aTzChangePropertyKey == NTzUpdate::ECurrentTimeZoneId) |
|
164 { |
|
165 CTzId* sysTime = iTzServer.GetTimeZoneIdL(); |
|
166 CleanupStack::PushL(sysTime); |
|
167 for (TInt i(0) ; i < KObserverCount ; ++i) |
|
168 { |
|
169 iObservers[i]->HandleCurrentTimeZoneChangeL(*sysTime); |
|
170 } |
|
171 CleanupStack::PopAndDestroy(sysTime); |
|
172 } |
|
173 else |
|
174 { |
|
175 TPckgBuf<NTzUpdate::TTzRulesChange> pubSubBuf; |
|
176 |
|
177 if(KErrNone == RProperty::Get(NTzUpdate::KPropertyCategory, NTzUpdate::ETzRulesChange, pubSubBuf)) |
|
178 { |
|
179 for (TInt i(0) ; i < KObserverCount ; ++i) |
|
180 { |
|
181 iObservers[i]->HandleTzRulesChangeL(pubSubBuf().iUTCTimeOfRulesChange); |
|
182 } |
|
183 } |
|
184 } |
|
185 } |
|
186 |
|
187 EXPORT_C void CAgnTlsProxy::AddSystemTimeObserverL(MAgnTzChangeObserver* aObserver) |
|
188 { |
|
189 TRAPD(err, iObservers.InsertInAddressOrderL(aObserver)); |
|
190 if(err != KErrNone && err != KErrAlreadyExists) |
|
191 { |
|
192 User::Leave(err); |
|
193 } |
|
194 //Get the time stamp of time zone database changed last time and force the observer to respond |
|
195 TPckgBuf<NTzUpdate::TTzRulesChange> pubSubBuf; |
|
196 if(KErrNone == RProperty::Get(NTzUpdate::KPropertyCategory, NTzUpdate::ETzRulesChange, pubSubBuf)) |
|
197 { |
|
198 TTime tzChange = pubSubBuf().iUTCTimeOfRulesChange; |
|
199 aObserver->HandleTzRulesChangeL(tzChange); |
|
200 } |
|
201 } |
|
202 |
|
203 EXPORT_C void CAgnTlsProxy::RemoveSystemTimeObserver(MAgnTzChangeObserver* aObserver) |
|
204 { |
|
205 TInt index(iObservers.FindInAddressOrder(aObserver)); |
|
206 |
|
207 if (index != KErrNotFound) |
|
208 { |
|
209 iObservers.Remove(index); |
|
210 } |
|
211 } |
|
212 |
|
213 #if defined(_DEBUG) |
|
214 |
|
215 EXPORT_C void CAgnTlsProxy::__dbgClearTzClientCacheL(TBool aRestartCaching) |
|
216 { |
|
217 // This will clear the actualised rules cache |
|
218 CTzRules* rules = iTlsTzRules->GetCurrentSystemTzRulesL(iTzServer); |
|
219 rules->SetInitialStdTimeOffset(rules->InitialStdTimeOffset()); |
|
220 iTlsTzRules->ReferenceRemoved(rules); |
|
221 |
|
222 iTzServer.__dbgClearCacheL(aRestartCaching); |
|
223 } |
|
224 |
|
225 #else |
|
226 |
|
227 EXPORT_C void CAgnTlsProxy::__dbgClearTzClientCacheL(TBool /*aRestartCaching*/) {} |
|
228 |
|
229 #endif |
|
230 |
|
231 // |
|
232 // Tls Shared Time Zone Rules classes |
|
233 // |
|
234 |
|
235 CAgnTlsTzRules::CAgnTlsTzRules() : iCurrentSystemTzRules(NULL) |
|
236 { |
|
237 } |
|
238 |
|
239 CAgnTlsTzRules::~CAgnTlsTzRules() |
|
240 { |
|
241 } |
|
242 |
|
243 CTzRules* CAgnTlsTzRules::GetSystemTzFromTzServerL(RTz& aTzServer) |
|
244 { |
|
245 TTime startTime(0); |
|
246 TTime endTime(0); |
|
247 return aTzServer.GetTimeZoneRulesL(startTime, endTime, ETzUtcTimeReference); |
|
248 } |
|
249 |
|
250 CAgnServerTlsTzRules::~CAgnServerTlsTzRules() |
|
251 { |
|
252 delete iCurrentSystemTzRules; |
|
253 } |
|
254 |
|
255 CTzRules* CAgnServerTlsTzRules::GetSharedTzRulesL(const CTzRules& aTzRules) |
|
256 { |
|
257 return aTzRules.CloneL(); |
|
258 } |
|
259 |
|
260 void CAgnServerTlsTzRules::ReferenceRemoved(const CTzRules* aReference) |
|
261 { |
|
262 __ASSERT_DEBUG(aReference != iCurrentSystemTzRules, _L("deleting iCurrentSystemTzZone in CAgnServerTlsTzRules")); |
|
263 delete aReference; |
|
264 } |
|
265 |
|
266 CTzRules* CAgnServerTlsTzRules::GetCurrentSystemTzRulesL(RTz& aTzServer) |
|
267 { |
|
268 if(!iCurrentSystemTzRules) |
|
269 { |
|
270 iCurrentSystemTzRules = GetSystemTzFromTzServerL(aTzServer); |
|
271 } |
|
272 |
|
273 return iCurrentSystemTzRules->CloneL(); |
|
274 } |
|
275 |
|
276 void CAgnServerTlsTzRules::SystemTzZoneChangedL(RTz& aTzServer, NTzUpdate::TPropertyKeys /*aTzChangePropertyKey*/) |
|
277 { |
|
278 CTzRules* oldTzRules = iCurrentSystemTzRules; |
|
279 iCurrentSystemTzRules = GetSystemTzFromTzServerL(aTzServer); |
|
280 delete oldTzRules; |
|
281 } |
|
282 |
|
283 CAgnClientTlsTzRules::~CAgnClientTlsTzRules() |
|
284 { |
|
285 iTzRules.ResetAndDestroy(); |
|
286 iTzRulesReferences.Reset(); |
|
287 iTzIds.Reset(); |
|
288 } |
|
289 |
|
290 CTzRules* CAgnClientTlsTzRules::GetSharedTzRulesL(const CTzRules& aTzRules) |
|
291 { |
|
292 CTzRules* foundTzRules = NULL; |
|
293 const TInt KRuleCount(iTzRules.Count()); |
|
294 for (TInt i = 0; i < KRuleCount; i++) |
|
295 { |
|
296 if (iTzRules[i]->IsEqualTo(aTzRules)) |
|
297 { |
|
298 foundTzRules = iTzRules[i]; |
|
299 iTzRulesReferences[i] = iTzRulesReferences[i] + 1; |
|
300 break; |
|
301 } |
|
302 } |
|
303 |
|
304 if (foundTzRules == NULL) |
|
305 { |
|
306 foundTzRules = aTzRules.CloneL(); |
|
307 |
|
308 CleanupStack::PushL(foundTzRules); |
|
309 User::LeaveIfError(iTzRulesReferences.Append(1)); |
|
310 iTzRules.AppendL(foundTzRules); |
|
311 iTzIds.AppendL(KInvalidTzId);//KInvalidTzId represents a rule which is not obtained from the tz server |
|
312 CleanupStack::Pop(foundTzRules); |
|
313 } |
|
314 |
|
315 return foundTzRules; |
|
316 } |
|
317 |
|
318 void CAgnClientTlsTzRules::ReferenceRemoved(const CTzRules* aReference) |
|
319 { |
|
320 if (aReference == NULL) |
|
321 { |
|
322 return; |
|
323 } |
|
324 |
|
325 const TInt KRuleCount(iTzRules.Count()); |
|
326 for (TInt i = 0; i < KRuleCount; i++) |
|
327 { |
|
328 if (iTzRules[i] == aReference) |
|
329 { |
|
330 if (--iTzRulesReferences[i] <= 0) |
|
331 { |
|
332 delete iTzRules[i]; |
|
333 iTzRules.Remove(i); |
|
334 iTzRulesReferences.Remove(i); |
|
335 iTzIds.Remove(i); |
|
336 } |
|
337 break; |
|
338 } |
|
339 } |
|
340 } |
|
341 |
|
342 void CAgnClientTlsTzRules::SetCurrentSystemTzRulesL(CTzRules* aTzRules, TUint aTzId) |
|
343 { |
|
344 if(iCurrentSystemTzRules) |
|
345 { |
|
346 if (iCurrentSystemTzRules->IsEqualTo(*aTzRules)) |
|
347 { |
|
348 delete aTzRules; |
|
349 return; //We don't need to do anything as the system zone has been set. |
|
350 } |
|
351 else |
|
352 { |
|
353 ReferenceRemoved(iCurrentSystemTzRules); |
|
354 iCurrentSystemTzRules = NULL; |
|
355 } |
|
356 } |
|
357 |
|
358 CleanupStack::PushL(aTzRules); |
|
359 User::LeaveIfError(iTzRulesReferences.Append(1)); |
|
360 iTzRules.AppendL(aTzRules); |
|
361 iTzIds.AppendL(aTzId); |
|
362 CleanupStack::Pop(aTzRules); |
|
363 |
|
364 iCurrentSystemTzRules = aTzRules; |
|
365 } |
|
366 |
|
367 void CAgnClientTlsTzRules::UpdateCurrentSystemTzRulesL(RTz& aTzServer) |
|
368 { |
|
369 CTzId* tzid = aTzServer.GetTimeZoneIdL(); |
|
370 CleanupStack::PushL(tzid); |
|
371 CTzRules* rules = GetSystemTzFromTzServerL(aTzServer); |
|
372 SetCurrentSystemTzRulesL(rules, tzid->TimeZoneNumericID()); |
|
373 CleanupStack::PopAndDestroy(tzid); |
|
374 } |
|
375 |
|
376 CTzRules* CAgnClientTlsTzRules::GetCurrentSystemTzRulesL(RTz& aTzServer) |
|
377 { |
|
378 if(iCurrentSystemTzRules == NULL) |
|
379 { |
|
380 UpdateCurrentSystemTzRulesL(aTzServer); |
|
381 } |
|
382 |
|
383 AddReference(iCurrentSystemTzRules); |
|
384 |
|
385 return iCurrentSystemTzRules; |
|
386 } |
|
387 |
|
388 void CAgnClientTlsTzRules::UpdateCacheL(RTz& aTzServer) |
|
389 { |
|
390 const TInt count = iTzIds.Count(); |
|
391 for(TInt ii=0; ii<count; ++ii) |
|
392 { |
|
393 if(iTzIds[ii]>0) |
|
394 { |
|
395 CTzId* id = CTzId::NewL(iTzIds[ii]); |
|
396 CTzRules* rules = NULL; |
|
397 TRAPD(err, rules = aTzServer.GetTimeZoneRulesL(*id, KMinYear, KMaxYear, ETzUtcTimeReference)); |
|
398 delete id; |
|
399 CleanupStack::PushL(rules); |
|
400 if(err != KErrNone && err != KErrNotFound) |
|
401 { |
|
402 User::Leave(err); |
|
403 } |
|
404 if(rules && !iTzRules[ii]->IsEqualTo(*rules)) |
|
405 {//If a tz rule chached is different from the one in tz server for the same TZ ID, it needs to be updated with the new one. |
|
406 iTzRules[ii]->CopyL(*rules); |
|
407 } |
|
408 CleanupStack::PopAndDestroy(rules); |
|
409 } |
|
410 } |
|
411 } |
|
412 |
|
413 void CAgnClientTlsTzRules::SystemTzZoneChangedL(RTz& aTzServer, NTzUpdate::TPropertyKeys aTzChangePropertyKey) |
|
414 { |
|
415 UpdateCurrentSystemTzRulesL(aTzServer); |
|
416 if(aTzChangePropertyKey == NTzUpdate::ETzRulesChange) |
|
417 { |
|
418 UpdateCacheL(aTzServer); |
|
419 } |
|
420 } |
|
421 |
|
422 void CAgnClientTlsTzRules::AddReference(const CTzRules* aTzRules) |
|
423 { |
|
424 const TInt KRuleCount(iTzRules.Count()); |
|
425 for (TInt i = 0; i < KRuleCount; i++) |
|
426 { |
|
427 if (iTzRules[i] == aTzRules) |
|
428 { |
|
429 iTzRulesReferences[i] = iTzRulesReferences[i] + 1; |
|
430 break; |
|
431 } |
|
432 } |
|
433 } |
|
434 /***************************** Implementation of class CAgnTzChangeObserver ***************/ |
|
435 CAgnTzChangeObserver::CAgnTzChangeObserver(CAgnTlsProxy& aTlsProxy, NTzUpdate::TPropertyKeys aTzChangePropertyKey) |
|
436 :CActive(CActive::EPriorityStandard), iAgnTlsProxy(aTlsProxy), iTzChangePropertyKey(aTzChangePropertyKey) |
|
437 { |
|
438 CActiveScheduler::Add(this); |
|
439 } |
|
440 |
|
441 void CAgnTzChangeObserver::ConstructL() |
|
442 { |
|
443 User::LeaveIfError(iTzChangeProperty.Attach(NTzUpdate::KPropertyCategory, iTzChangePropertyKey)); |
|
444 iTzChangeProperty.Subscribe(iStatus); |
|
445 SetActive(); |
|
446 } |
|
447 |
|
448 CAgnTzChangeObserver* CAgnTzChangeObserver::NewL(CAgnTlsProxy& aTlsProxy, NTzUpdate::TPropertyKeys aTzChangePropertyKey) |
|
449 { |
|
450 CAgnTzChangeObserver* self = new (ELeave) CAgnTzChangeObserver(aTlsProxy, aTzChangePropertyKey); |
|
451 CleanupStack::PushL(self); |
|
452 self->ConstructL(); |
|
453 CleanupStack::Pop(self); |
|
454 return self; |
|
455 } |
|
456 |
|
457 CAgnTzChangeObserver::~CAgnTzChangeObserver() |
|
458 { |
|
459 Cancel(); |
|
460 iTzChangeProperty.Close(); |
|
461 } |
|
462 |
|
463 void CAgnTzChangeObserver::RunL() |
|
464 { |
|
465 if (iStatus.Int() == KErrNone) |
|
466 { |
|
467 iAgnTlsProxy.HandleTzPropertyChangeL(iTzChangePropertyKey); |
|
468 iTzChangeProperty.Subscribe(iStatus); |
|
469 SetActive(); |
|
470 } |
|
471 } |
|
472 |
|
473 void CAgnTzChangeObserver::DoCancel() |
|
474 { |
|
475 iTzChangeProperty.Cancel(); |
|
476 } |
|
477 |
|
478 |
|
479 |