pimappservices/calendar/shared/src/agmtlsproxy.cpp
changeset 0 f979ecb2b13e
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     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