tzservices/tzserver/Server/Source/timezonesession.cpp
author William Roberts <williamr@symbian.org>
Fri, 23 Apr 2010 14:37:17 +0100
branchRCL_3
changeset 22 c82a39b81a38
parent 0 2e3d3ce01487
child 39 469fa8a78de7
permissions -rw-r--r--
Rework addition of Symbian splash screen to reduce the source impact (uses SVG from Bug 2414) Notes: by using the OPTION SOURCEDIR parameter in the mifconv extension instructions, I can arrange to use the same source file name in sfimage, without having to export over the original Nokia file. This means that the name inside splashscreen.mbg is the same, which removes the need for the conditional compilation in SplashScreen.cpp, and gets rid of sf_splashscreen.mmp.

// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//

#include <s32mem.h>
#include <vtzrules.h>
#include <tzupdate.h>
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
#include <tzusernames.h>//new file added for CTzUserNames which is publishedPartner
#include <tzuserdefineddata.h> //new file added for CTzUserData which is publishedPartner
#endif
#include <tzlocalizedcityrecord.h>
#include <tzlocalizedtimezonerecord.h>
#include "timezonesession.h"
#include "timezoneserver.h"

CTzServerSession* CTzServerSession::NewL()
	{
	CTzServerSession* self = new (ELeave) CTzServerSession();
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop();
	return self;
	}

CTzServerSession::~CTzServerSession()
	{
	if (iPendingRequest)
		{
		iClientMessage.Complete(KErrCancel);
		iPendingRequest = EFalse;
		}

	TzServer()->SessionClosed();
	
	delete iTzUserDataCache;
	
	iCitiesResultCache.ResetAndDestroy();
	iCitiesResultCache.Close();
	delete iTimeZoneResultCache;
	delete iCityResultCache;
	}

CTzServerSession::CTzServerSession()
	{
	}

void CTzServerSession::ConstructL()
	{
	iTzUserDataCache = CTzUserDataCache::NewL();
	}

// completes a pending client notifier
void CTzServerSession::NotifyTZStatusChange(RTz::TTzChanges aChange, const TAny* aRequester)
	{
	if (static_cast<const CTzServerSession*>(aRequester) == this)
		{
		// no need informing the client making the change
		// he should look after him self
		return;
		}

	if (iPendingRequest)
		{
		iClientMessage.Complete(aChange);
		iPendingRequest = EFalse;
		}
	}

//
// Registers to receive notification to time and zone changes in the
// Server
TInt CTzServerSession::doRegisterTzChangeNotifier(const RMessage2& aMessage)
	{
	if (!iPendingRequest)
		{
		iClientMessage = aMessage;
		iPendingRequest = ETrue;
		}
	else
		{
		// the same client already requested such notice
		// Panic the client
		iPendingRequest = EFalse;
		aMessage.Panic(KTimeZoneServerName, RTz::EPanicNotificationRequestPending);
		
		return (KErrCancel);
		}

	return KRequestPending;
	}

//
// Cancels request to receive notification to time and zone changes in the
// Server
TInt CTzServerSession::doCancelRequestForTzChangeNoticeL(const RMessage2& /* aMessage */)
	{
	if (iPendingRequest)
		{
		iPendingRequest = EFalse;
		iClientMessage.Complete(KErrCancel);
		}
	else
		{
		User::Leave(KErrNotFound);
		}

	return KErrNone;
	}


TInt CTzServerSession::doSetTimeZoneL(const RMessage2& aMessage)
	{
	CBufFlat* buffer = CBufFlat::NewL(KMaxTimeZoneIdSize);
	CleanupStack::PushL(buffer);

	// Read from client message buffer
	// reserve the full space
	buffer->ExpandL(0, KMaxTimeZoneIdSize);
	TPtr8 bufferPtr(buffer->Ptr(0) );
	aMessage.ReadL(0, bufferPtr);

	RBufReadStream readStream;
	readStream.Open(*buffer);
	
	CTzId* zoneId = NULL;
	TRAPD(err, zoneId = CTzId::NewL(readStream));

	// Panic the client if it sent invalid data that would cause the server to panic.
	if (err == KErrArgument)
	    {
    	CleanupStack::PopAndDestroy(buffer);
        aMessage.Panic(KTimeZoneServerName, RTz::EPanicInvalidArgument);
        return KRequestPending;
	    }
	else
	    {
	    User::LeaveIfError(err);
	    }
	
	CleanupStack::PushL(zoneId);
	const CTzId& KInZoneId = TzServer()->TimeZoneManager().SetTimeZoneL(*zoneId, this, ETrue);
	CleanupStack::PopAndDestroy(zoneId);

	// return the new setting
	buffer->Reset();
	RBufWriteStream writeStream;
	writeStream.Open(*buffer);
	KInZoneId.ExternalizeL(writeStream);
	writeStream.CommitL();
	writeStream.Close();

	// Write to client message buffer
	aMessage.WriteL(1, buffer->Ptr(0));

	CleanupStack::PopAndDestroy(buffer);

	return (KErrNone);
	}
	
TInt CTzServerSession::doIsDaylightSavingOnL(const RMessage2& aMessage)
{
	CBufFlat* buffer = CBufFlat::NewL(KMaxTimeZoneIdSize);
	CleanupStack::PushL(buffer);
	// Read from client message buffer
	// reserve the full space
	buffer->ExpandL(0, KMaxTimeZoneIdSize);
	TPtr8 bufferPtr(buffer->Ptr(0) );
	aMessage.ReadL(0, bufferPtr);
	
	TPckgBuf<TTime> timeBuffer;
	aMessage.ReadL(1, timeBuffer);
	
	TTime time(timeBuffer());

	RBufReadStream readStream;
	readStream.Open(*buffer);

    CTzId* zoneId = NULL;
	TRAPD(err, zoneId = CTzId::NewL(readStream));
	
	// Panic the client if it sent invalid data that would cause the server to panic.
	if (err == KErrArgument)
	    {
    	CleanupStack::PopAndDestroy(buffer);
        aMessage.Panic( KTimeZoneServerName, RTz::EPanicInvalidArgument );
        return KRequestPending;
	    }
	else
	    {
	    User::LeaveIfError(err);
	    }
	
	CleanupStack::PushL(zoneId);
	
	if( time == Time::NullTTime())
		{
		time.UniversalTime();		
		}

	TInt isDaylightSavingOn = TzServer()->TimeZoneManager().IsDaylightSavingOnL(*zoneId, time);
	CleanupStack::PopAndDestroy(zoneId);
	// Write to client message buffer
	TPckg<TInt> response(isDaylightSavingOn);
	aMessage.WriteL(2, response);
	CleanupStack::PopAndDestroy(buffer);
	return (KErrNone);
}

TInt CTzServerSession::doGetLocalTimeZoneIdL(const RMessage2& aMessage)
	{
	const CTzId& KZoneId = TzServer()->TimeZoneManager().GetTimeZoneIdL();

	CBufFlat* buffer = CBufFlat::NewL(KMaxTimeZoneIdSize);
	CleanupStack::PushL(buffer);

	RBufWriteStream writeStream;
	writeStream.Open(*buffer);

	KZoneId.ExternalizeL(writeStream);

	writeStream.CommitL();
	writeStream.Close();

	// Write to client message buffer
	aMessage.WriteL(0, buffer->Ptr(0));

	CleanupStack::PopAndDestroy(buffer);
	return (KErrNone);

	}

TInt CTzServerSession::doGetLocalEncodedTimeZoneRulesL(const RMessage2& aMessage)
	{
	TPckgBuf<TInt> rulesSizeBuffer;
	aMessage.ReadL(0, rulesSizeBuffer);

	// Check if rules size buffer is valid. Panic the client if it sent 
	// invalid data that would cause the server to panic.
    TInt size = rulesSizeBuffer();
    const TInt KMaxSize = KMaxTInt / 2;
    if (size <= 0 || size >= KMaxSize)
        {
        aMessage.Panic( KTimeZoneServerName, RTz::EPanicInvalidArgument );
        return KRequestPending;
        }

	CBufFlat* buffer = CBufFlat::NewL(rulesSizeBuffer());
	CleanupStack::PushL(buffer);
	
	const CTzRules& KRules = TzServer()->TimeZoneManager().GetEncodedTimeZoneRulesL();		

	// Externalise rules	
	RBufWriteStream writeStream;
	writeStream.Open(*buffer);

	TRAPD(err, KRules.ExternalizeL(writeStream));
	// If the stream contains invalid data that would cause the server to panic 
	// then panic the client.
	if (err == KErrArgument)
	    {
	    CleanupStack::PopAndDestroy(buffer);
        aMessage.Panic( KTimeZoneServerName, RTz::EPanicInvalidArgument );
        return KRequestPending;
	    }
	else
	    {
	    User::LeaveIfError(err);
	    }
	    
	writeStream.CommitL();
	writeStream.Close();
	
	// Write to client message buffer
	aMessage.WriteL(1, buffer->Ptr(0));
	
	CleanupStack::PopAndDestroy(buffer);
	return KErrNone;
	}

TInt CTzServerSession::doGetLocalEncodedTimeZoneRulesSizeL(const RMessage2& aMessage)
	{
	TPckgBuf<TTime> startTimeBuffer;
	aMessage.ReadL(0, startTimeBuffer);
	
	TPckgBuf<TTime> endTimeBuffer;
	aMessage.ReadL(1, endTimeBuffer);
	
	TPckgBuf<TTzTimeReference> timeRefBuffer;
	aMessage.ReadL(2, timeRefBuffer);

	TInt rulesSize = TzServer()->TimeZoneManager().GetEncodedTimeZoneRulesSizeL(startTimeBuffer(), endTimeBuffer(),
		timeRefBuffer());
	
	// Write to client message buffer
	TPckgBuf<TInt> rulesSizeBuffer(rulesSize);
	aMessage.WriteL(3, rulesSizeBuffer);

	return KErrNone;
	}

TInt CTzServerSession::doGetForeignEncodedTimeZoneRulesL(const RMessage2& aMessage)
	{
	TPckgBuf<TInt> rulesSizeBuffer;
	aMessage.ReadL(0, rulesSizeBuffer);
   
	// Check if rules size buffer is invalid. Panic the client if it sent 
	// invalid data that would cause the server to panic.
    TInt size = rulesSizeBuffer();
    const TInt KMaxSize = KMaxTInt/2;
    if (size <= 0 || size >= KMaxSize)
        {
        aMessage.Panic( KTimeZoneServerName, RTz::EPanicInvalidArgument );
        return KRequestPending;
        }

	CBufFlat* buffer = CBufFlat::NewL(rulesSizeBuffer());
	CleanupStack::PushL(buffer);
	
	const CTzRules& KRules = TzServer()->TimeZoneManager().GetForeignEncodedTimeZoneRulesL();		

	// Externalise rules	
	RBufWriteStream writeStream;
	writeStream.Open(*buffer);
	// If the stream contains invalid data that would cause the server to panic 
	// then panic the client.
	TRAPD(err, KRules.ExternalizeL(writeStream));
	if (err == KErrArgument)
	    {
	    CleanupStack::PopAndDestroy(buffer);
        aMessage.Panic( KTimeZoneServerName, RTz::EPanicInvalidArgument );
        return KRequestPending;
	    }
	else
	    {
	    User::LeaveIfError(err);
	    }
	
	writeStream.CommitL();
	writeStream.Close();
	
	// Write to client message buffer
	aMessage.WriteL(1, buffer->Ptr(0));
	
	CleanupStack::PopAndDestroy(buffer);
	return KErrNone;
	}
	
TInt CTzServerSession::doGetForeignEncodedTimeZoneRulesSizeL(const RMessage2& aMessage)
	{
	TPckgBuf<TTime> startTimeBuffer;
	aMessage.ReadL(0, startTimeBuffer);

	TPckgBuf<TTime> endTimeBuffer;
	aMessage.ReadL(1, endTimeBuffer);

	// Read from client message buffer
	// reserve the full space
	CBufFlat* buffer = CBufFlat::NewL(KMaxTimeZoneIdSize + sizeof(TTzTimeReference));
	CleanupStack::PushL(buffer);

	buffer->ExpandL(0, KMaxTimeZoneIdSize + sizeof(TTzTimeReference));
	TPtr8 bufferPtr(buffer->Ptr(0) );
	aMessage.ReadL(2, bufferPtr);

	RBufReadStream readStream;
	readStream.Open(*buffer);
	
	CTzId* zoneId = NULL;
	TRAPD(err, zoneId = CTzId::NewL(readStream));
	// If the stream contains invalid data that would cause the server to panic 
	// then panic the client.
	if (err == KErrArgument)
	    {
	    CleanupStack::PopAndDestroy(buffer);
        aMessage.Panic( KTimeZoneServerName, RTz::EPanicInvalidArgument );
        return KRequestPending;
	    }
	else
	    {
	    User::LeaveIfError(err);
	    }

	CleanupStack::PushL(zoneId);

	TTzTimeReference timeRef(static_cast<TTzTimeReference>(readStream.ReadInt8L() ) );
	TPckgBuf<TTzTimeReference> timeRefBuffer(timeRef);
	
	TInt rulesSize = TzServer()->TimeZoneManager().GetForeignEncodedTimeZoneRulesSizeL(*zoneId, startTimeBuffer(),
		endTimeBuffer(), timeRefBuffer());


	// Write to client message buffer
	TPckgBuf<TInt> rulesSizeBuffer(rulesSize);
	aMessage.WriteL(3, rulesSizeBuffer);

	CleanupStack::PopAndDestroy(2,buffer);
	return KErrNone;
	}

TInt CTzServerSession::doConvertLocalZoneTimeL(const RMessage2& aMessage)
	{
	TPckgBuf<TTime> timeBuffer;
	aMessage.ReadL(0, timeBuffer);

	TPckgBuf<TTzTimeReference> timerRefBuffer;
	aMessage.ReadL(1, timerRefBuffer);

	TTime time(timeBuffer());
	TzServer()->TimeZoneManager().ConvertL(time, timerRefBuffer());

	// Write to client message buffer
	TPckg<TTime> timeInBuffer(time);
	aMessage.WriteL(2, timeInBuffer);

	return (KErrNone);
	}


TInt CTzServerSession::doConvertForeignZoneTimeL(const RMessage2& aMessage)
	{
	TPckgBuf<TTime> timeBuffer;
	aMessage.ReadL(0, timeBuffer);

	TPckgBuf<TTzTimeReference> timerRefBuffer;
	aMessage.ReadL(1, timerRefBuffer);

	// Read from client message buffer
	// reserve the full space
	CBufFlat* buffer = CBufFlat::NewL(KMaxTimeZoneIdSize);
	CleanupStack::PushL(buffer);

	buffer->ExpandL(0, KMaxTimeZoneIdSize);
	TPtr8 bufferPtr(buffer->Ptr(0) );
	aMessage.ReadL(2, bufferPtr);

	RBufReadStream readStream;
	readStream.Open(*buffer);

    CTzId* zoneId = NULL;
	TRAPD(err, zoneId = CTzId::NewL(readStream));
	// If the stream contains invalid data that would cause the server to panic 
	// then panic the client.
	if (err == KErrArgument)
	    {
	    CleanupStack::PopAndDestroy(buffer);
        aMessage.Panic( KTimeZoneServerName, RTz::EPanicInvalidArgument );
        return KRequestPending;
	    }
	else
	    {
	    User::LeaveIfError(err);
	    }
	
	CleanupStack::PushL(zoneId);

	TTime time(timeBuffer() );
	TzServer()->TimeZoneManager().ConvertL(*zoneId, time, timerRefBuffer());

	// Write to client message buffer
	TPckg<TTime> timeInBuffer(time);
	aMessage.WriteL(3, timeInBuffer);

	CleanupStack::PopAndDestroy(2);
	return (KErrNone);
	}
	
/**
Retrieves UTC offset for a number of time zone ids
*/
TInt CTzServerSession::doGetOffsetsForTimeZoneIdsL(const RMessage2& aMessage) const
	{
	TInt bufferSize = aMessage.Int0();				
    
    // If buffer size invalid then panic client.
    const TInt KMaxSize = KMaxTInt / 4;
    if (bufferSize <= 0 || bufferSize > KMaxSize)
        {
        aMessage.Panic( KTimeZoneServerName, RTz::EPanicInvalidArgument );
        return KRequestPending;
        }
	
	CBufFlat* idBuf = CBufFlat::NewL(bufferSize);
	CleanupStack::PushL(idBuf);
	idBuf->ExpandL(0,bufferSize);
	TPtr8 bufferPtr = idBuf->Ptr(0);
	aMessage.ReadL(1, bufferPtr);

	CTzConfigAgent& configAgent = TzServer()->TimeZoneManager();
	configAgent.GetOffsetsForTimeZoneIdsL(*idBuf);

	// Write to client message buffer
	aMessage.WriteL(1, idBuf->Ptr(0));

	CleanupStack::PopAndDestroy(idBuf);
		
	return KErrNone;
	}

/**
Sets the configuration of the UTC Offset auto-update functionality.

@param aMessage The client-server message parameter.
@return An error code.
@internalComponent
@capability ECapabilityWriteDeviceData Write Device Data capability is needed
to be able to set the UTC Offset auto-update configuration. This prevents
non-system applications from altering the settings.
*/
TInt CTzServerSession::doSetAutoUpdateBehaviorL(const RMessage2& aMessage)
    {
    // Configuration value is stored in message slot zero.
	TzServer()->TimeZoneManager().SetAutoUpdateBehaviorL(aMessage.Int0());
	return KErrNone;
    }
/**
Retrieves the auto update value
*/
TInt CTzServerSession::doAutoUpdateSettingL(const RMessage2& aMessage)
    {
   	TInt autoUpdate = TzServer()->TimeZoneManager().AutoUpdateSetting();
	// Write to client message buffer
	TPckg<TInt> response(autoUpdate);
	aMessage.WriteL(0, response);
	return (KErrNone);
	}

TInt CTzServerSession::doNotifyHomeTimeZoneChanged(const RMessage2& aMessage)
	{
	NTzUpdate::TTimeZoneChange change;
	change.iNewTimeZoneId = aMessage.Int0();
	change.iOldTimeZoneId = aMessage.Int1();
		
	TPckgBuf<NTzUpdate::TTimeZoneChange> changeBuf(change);
	return RProperty::Set(NTzUpdate::KPropertyCategory, NTzUpdate::EHomeTimeZoneId, changeBuf);
	}

TInt CTzServerSession::doSetHomeTimeL(const RMessage2& aMessage)
	{
	TPckgBuf<TTime> homeTimeBuffer;
	aMessage.ReadL(0, homeTimeBuffer);
	return TzServer()->TimeZoneManager().SetHomeTimeL(homeTimeBuffer());
	}

TInt CTzServerSession::doSetUnknownZoneTimeL(const RMessage2& aMessage)
	{
	TPckgBuf<TTime> utcTimeBuffer;
	TPckgBuf<TInt>  utcOffset;
	TPckgBuf<TBool>  persist;
	aMessage.ReadL(0, utcTimeBuffer);
	aMessage.ReadL(1, utcOffset);
	aMessage.ReadL(2, persist);

	return TzServer()->TimeZoneManager().SetUnknownTimeZoneTimeL(utcTimeBuffer(),utcOffset(),persist());
	}
	
/**
 * Creates user defined time zone
 * Arguments: 0 : Input - Buffer Size
 *			  1 : Input - Data Buffer contains time zone info 
 *			  2 : Output - ID of the time zone created 
 */	
TInt CTzServerSession::doCreateUserTimeZoneL(const RMessage2& aMessage)
	{
	const TInt buffersize = aMessage.Int0();
	
	CBufFlat* buffer = CBufFlat::NewL(buffersize);
	CleanupStack::PushL(buffer);

	buffer->ExpandL(0, buffersize);
	TPtr8 bufferPtr(buffer->Ptr(0) );
	aMessage.ReadL(1, bufferPtr);

	RBufReadStream readStream;
	CleanupClosePushL(readStream);
	readStream.Open(*buffer);
	
	CTzRules* rules = NULL;
	TRAPD(err, 	rules = CTzRules::NewL(readStream));

	// Panic the client if it sent invalid data that would cause the server to panic.
	if (err == KErrArgument)
	    {
    	CleanupStack::PopAndDestroy(2, buffer);
        aMessage.Panic(KTimeZoneServerName, RTz::EPanicInvalidArgument);
        return KRequestPending;
	    }
	else
	    {
	    User::LeaveIfError(err);
	    }
	    
	CleanupStack::PushL(rules);

	CTzUserNames* names = CTzUserNames::NewL(readStream);
	CleanupStack::PushL(names);
	TInt id = TzServer()->UserTimeZoneDb().CreateTzL(*rules, *names);		
	CleanupStack::PopAndDestroy(4, buffer);
	TPckgBuf<TInt> idBuffer(id);
	aMessage.WriteL(2, idBuffer);
	return KErrNone;
	}

/**
 * Update a user defined time zone
 * Arguments: 0 : Input - Size of data buffer 
 *			  1 : Input - Data buffer contained time zone info
 *			  2 : Input - ID of thetTime zone to be updated
 */	
TInt CTzServerSession::doUpdateUserTimeZoneL(const RMessage2& aMessage)
	{
	const TInt buffersize = aMessage.Int0();
	
	CBufFlat* buffer = CBufFlat::NewL(buffersize);
	CleanupStack::PushL(buffer);

	buffer->ExpandL(0, buffersize);
	TPtr8 bufferPtr(buffer->Ptr(0) );
	aMessage.ReadL(1, bufferPtr);

	RBufReadStream readStream;
	CleanupClosePushL(readStream);
	readStream.Open(*buffer);
	
	CTzRules* rules = NULL;
	TRAPD(err, 	rules = CTzRules::NewL(readStream));

	// Panic the client if it sent invalid data that would cause the server to panic.
	if (err == KErrArgument)
	    {
    	CleanupStack::PopAndDestroy(2, buffer);
        aMessage.Panic(KTimeZoneServerName, RTz::EPanicInvalidArgument);
        return KRequestPending;
	    }
	else
	    {
	    User::LeaveIfError(err);
	    }
	    
	CleanupStack::PushL(rules);

	CTzUserNames* names = CTzUserNames::NewL(readStream);;
	CleanupStack::PushL(names);
	
	const TInt id = aMessage.Int2();
	
    TzServer()->UserTimeZoneDb().UpdateTzL(id, *rules, *names);
	CleanupStack::PopAndDestroy(4, buffer);
	return KErrNone;
	}
	
/**
 * Delete a user defined time zone
 * Arguments: 0 : Input - Time Zone ID
 */		
TInt CTzServerSession::doDeleteUserTimeZoneL(const RMessage2& aMessage)
	{
	const TInt id = aMessage.Int0();
	TzServer()->UserTimeZoneDb().DeleteTzL(id);		
	return KErrNone;
	}
	
/**
 * Gets the size of user defined time zone names
 * Arguments: 0 : Input - Time Zone ID
 *			  1 : Output - size of time zone names
 */		
TInt CTzServerSession::doGetUserTimeZoneNamesSizeL(const RMessage2& aMessage)
	{
	const TInt id = aMessage.Int0();
	TInt sizeOfNames = 0;
	//ReadTzNamesL leaves if there is not a names found
	CTzUserNames* names = TzServer()->UserTimeZoneDb().ReadTzNamesL(id);		
	iTzUserDataCache->SetNames(names);
	sizeOfNames = iTzUserDataCache->SizeOfNames();
	// Write to client message buffer
	TPckgBuf<TInt> nameSizeBuffer(sizeOfNames);
	aMessage.WriteL(1, nameSizeBuffer);
	
	return KErrNone;
	}
		
/**
 * Gets user defined time zone names
 * Arguments: 0 : Output - Data buffer contained time zone name 
*/	
 TInt CTzServerSession::doGetUserTimeZoneNamesL(const RMessage2& aMessage)
	{
	TInt size = iTzUserDataCache->SizeOfNames();
	CBufFlat* buffer = CBufFlat::NewL(size);
	CleanupStack::PushL(buffer);
	buffer->ExpandL(0,size);
	
	RBufWriteStream writeStream;
	CleanupClosePushL(writeStream);
	writeStream.Open(*buffer);
	const CTzUserNames& names = iTzUserDataCache->GetNames();
	writeStream << names;
	writeStream.CommitL();
	aMessage.WriteL(0, buffer->Ptr(0));
	CleanupStack::PopAndDestroy(2, buffer);
	return KErrNone;
	}
	
/**
 * Gets the size of user defined time zone Ids
 * Arguments: 0 : Output - Size of time zone IDs
 */		
TInt CTzServerSession::doGetUserTimeZoneIdsSizeL(const RMessage2& aMessage)
	{
	RArray<TUint32> ids;
	CleanupClosePushL(ids);
	TzServer()->UserTimeZoneDb().ReadTzIdsL(ids);
	iTzUserDataCache->SetIdsL(ids);
	CleanupStack::PopAndDestroy(&ids);
		
	TInt idsSize = iTzUserDataCache->SizeOfIds();
	// Write to client message buffer
	TPckgBuf<TInt> idsSizeBuffer(idsSize);
	aMessage.WriteL(0, idsSizeBuffer);
	return KErrNone;
	}
	
/**
 * Gets the user defined time zone Ids
 * Arguments: 0 : Output - Data buffer contained time zone IDs
 */	
TInt CTzServerSession::doGetUserTimeZoneIdsL(const RMessage2& aMessage)
	{
	CBufFlat* buffer = CBufFlat::NewL(iTzUserDataCache->SizeOfIds());
	CleanupStack::PushL(buffer);
	buffer->ExpandL(0,iTzUserDataCache->SizeOfIds());
	
	RBufWriteStream writeStream;
	CleanupClosePushL(writeStream);
	writeStream.Open(*buffer);
	TArray<TUint32> ids = iTzUserDataCache->GetIds();
	TInt count = ids.Count();
	writeStream.WriteInt16L(count);
	for (TInt ii=0; ii<count; ++ii)
		{
		writeStream.WriteUint32L((ids)[ii]);	
		}
	writeStream.CommitL();
	aMessage.WriteL(0, buffer->Ptr(0));
	CleanupStack::PopAndDestroy(2, buffer);
	return KErrNone;	
	}

TInt CTzServerSession::doGetHeapSizeL(const RMessage2& aMessage)
	{
	TInt reply = User::Heap().Count();
	TInt sizeInBytes;
	reply = User::AllocSize(sizeInBytes);
	TPckg<TInt> heapCellsBuffer(reply);
	TPckg<TInt> heapsizeBuffer(sizeInBytes);
	aMessage.WriteL(0, heapCellsBuffer);
	aMessage.WriteL(1, heapsizeBuffer);	
	return reply;
	}

TInt CTzServerSession::doLocalizationReadCitiesSizeL(const RMessage2& aMessage)
	{
	iCitiesResultCache.ResetAndDestroy();
	TzServer()->LocalizationDb().ReadCitiesL(iCitiesResultCache);
	TInt resultSize = CTzLocalizedCityRecord::ExternalizeSize(iCitiesResultCache);
		
	// Write to client message buffer
	TPckgBuf<TInt> resultSizeBuffer(resultSize);
	aMessage.WriteL(0, resultSizeBuffer);

	return KErrNone;
	}

TInt CTzServerSession::doLocalizationReadCitiesTzIdSizeL(const RMessage2& aMessage)
	{
	iCitiesResultCache.ResetAndDestroy();
	TzServer()->LocalizationDb().ReadCitiesL(iCitiesResultCache, aMessage.Int1());
	TInt resultSize = CTzLocalizedCityRecord::ExternalizeSize(iCitiesResultCache);
		
	// Write to client message buffer
	TPckgBuf<TInt> resultSizeBuffer(resultSize);
	aMessage.WriteL(0, resultSizeBuffer);

	return KErrNone;
	}

TInt CTzServerSession::doLocalizationReadCitiesInGroupSizeL(const RMessage2& aMessage)
	{
	iCitiesResultCache.ResetAndDestroy();
	TzServer()->LocalizationDb().ReadCitiesInGroupL(iCitiesResultCache, aMessage.Int1());
	TInt resultSize = CTzLocalizedCityRecord::ExternalizeSize(iCitiesResultCache);
		
	// Write to client message buffer
	TPckgBuf<TInt> resultSizeBuffer(resultSize);
	aMessage.WriteL(0, resultSizeBuffer);

	return KErrNone;
	}

TInt CTzServerSession::doLocalizationReadCitiesL(const RMessage2& aMessage)
	{
	TInt maxSize = aMessage.GetDesLengthL(0);
	CBufFlat* buffer = CBufFlat::NewL(maxSize);
	CleanupStack::PushL(buffer);
	
	RBufWriteStream writeStream;
	writeStream.Open(*buffer);
	CleanupClosePushL(writeStream);
	CTzLocalizedCityRecord::ExternalizeL(iCitiesResultCache, writeStream);
	writeStream.CommitL();
	iCitiesResultCache.ResetAndDestroy();
	CleanupStack::PopAndDestroy(&writeStream);
	
	// Write to client message buffer
	aMessage.WriteL(0, buffer->Ptr(0));
	
	CleanupStack::PopAndDestroy(buffer);
	
	return KErrNone;
	}

TInt CTzServerSession::doLocalizationReadFrequentlyUsedZoneSizeL(const RMessage2& aMessage)
	{
	delete iTimeZoneResultCache;
	iTimeZoneResultCache = 0;
	iTimeZoneResultCache = TzServer()->LocalizationDb().ReadFrequentlyUsedZoneL(aMessage.Int1());
	TInt resultSize = iTimeZoneResultCache->ExternalizeSize();
	
	// Write to client message buffer
	TPckgBuf<TInt> resultSizeBuffer(resultSize);
	aMessage.WriteL(0, resultSizeBuffer);

	return KErrNone;
	}

TInt CTzServerSession::doLocalizationReadFrequentlyUsedZoneL(const RMessage2& aMessage)
	{
	TInt maxSize = aMessage.GetDesLengthL(0);
	CBufFlat* buffer = CBufFlat::NewL(maxSize);
	CleanupStack::PushL(buffer);
	
	RBufWriteStream writeStream;
	writeStream.Open(*buffer);
	CleanupClosePushL(writeStream);
	iTimeZoneResultCache->ExternalizeL(writeStream);
	writeStream.CommitL();
	delete iTimeZoneResultCache;
	iTimeZoneResultCache = 0;
	CleanupStack::PopAndDestroy(&writeStream);
		
	// Write to client message buffer
	aMessage.WriteL(0, buffer->Ptr(0));
	
	CleanupStack::PopAndDestroy(buffer);
	
	return KErrNone;
	}

TInt CTzServerSession::doLocalizationReadCachedTimeZoneCitySizeL(const RMessage2& aMessage)
	{
	delete iCityResultCache;
	iCityResultCache = 0;
	iCityResultCache = TzServer()->LocalizationDb().ReadCachedTimeZoneCityL(aMessage.Int1());
	TInt resultSize = iCityResultCache->ExternalizeSize();
	
	// Write to client message buffer
	TPckgBuf<TInt> resultSizeBuffer(resultSize);
	aMessage.WriteL(0, resultSizeBuffer);

	return KErrNone;
	}

TInt CTzServerSession::doLocalizationReadCachedTimeZoneCityL(const RMessage2& aMessage)
	{
	TInt maxSize = aMessage.GetDesLengthL(0);
	CBufFlat* buffer = CBufFlat::NewL(maxSize);
	CleanupStack::PushL(buffer);
	
	RBufWriteStream writeStream;
	writeStream.Open(*buffer);
	CleanupClosePushL(writeStream);
	iCityResultCache->ExternalizeL(writeStream);
	writeStream.CommitL();
	delete iCityResultCache;
	iCityResultCache = 0;
	CleanupStack::PopAndDestroy(&writeStream);
	
	// Write to client message buffer
	aMessage.WriteL(0, buffer->Ptr(0));
	
	CleanupStack::PopAndDestroy(buffer);
	
	return KErrNone;
	}

TInt CTzServerSession::doLocalizationOpenDbL()
	{
	TzServer()->LocalizationDb().OpenDbL();
	return KErrNone;
	}

TInt CTzServerSession::doLocalizationCloseDb()
	{
	TzServer()->LocalizationDb().CloseDb();
	return KErrNone;
	}

TInt CTzServerSession::doLocalizationWriteCityL(const RMessage2& aMessage)
	{
	TInt length=aMessage.GetDesLengthL(0);
	HBufC* const cityName=HBufC::NewLC(length);
	TPtr cityNamePtr(cityName->Des());
	aMessage.ReadL(0, cityNamePtr);

	TzServer()->LocalizationDb().WriteCityL(*cityName, (TUint16)aMessage.Int1(), aMessage.Int2(), aMessage.Int3());
	
	CleanupStack::PopAndDestroy(cityName);
	
	return KErrNone;
	}

TInt CTzServerSession::doLocalizationDeleteCityL(const RMessage2& aMessage)
	{
	TInt length=aMessage.GetDesLengthL(0);
	HBufC* const cityName=HBufC::NewLC(length);
	TPtr cityNamePtr(cityName->Des());
	aMessage.ReadL(0, cityNamePtr);

	TzServer()->LocalizationDb().DeleteCityL(*cityName, (TUint16)aMessage.Int1());
	
	CleanupStack::PopAndDestroy(cityName);
	
	return KErrNone;
	}

TInt CTzServerSession::doLocalizationWriteFrequentlyUsedZoneL(const RMessage2& aMessage)
	{
	TInt length=aMessage.GetDesLengthL(0);
	CBufFlat* buffer = CBufFlat::NewL(length);
	CleanupStack::PushL(buffer);
	buffer->ExpandL(0,length);
	TPtr8 des(buffer->Ptr(0));
	aMessage.ReadL(0,des);
	RBufReadStream readStream;
	readStream.Open(*buffer);
	CleanupClosePushL(readStream);
	CTzLocalizedTimeZoneRecord* timeZone = CTzLocalizedTimeZoneRecord::NewLC(readStream);
	CTzLocalizedCityRecord* city = CTzLocalizedCityRecord::NewLC(readStream);
	TInt frequentlyUsedZone = readStream.ReadInt32L();
	
	TzServer()->LocalizationDb().WriteFrequentlyUsedZoneL(*timeZone, *city, frequentlyUsedZone);

	CleanupStack::PopAndDestroy(city);
	CleanupStack::PopAndDestroy(timeZone);
	CleanupStack::PopAndDestroy(&readStream);
	CleanupStack::PopAndDestroy(buffer);
	
	return KErrNone;
	}

TInt CTzServerSession::doLocalizationWriteAllFrequentlyUsedZonesL(const RMessage2& aMessage)
	{
	TInt length=aMessage.GetDesLengthL(0);
	CBufFlat* buffer = CBufFlat::NewL(length);
	CleanupStack::PushL(buffer);
	buffer->ExpandL(0,length);
	TPtr8 des(buffer->Ptr(0));
	aMessage.ReadL(0,des);
	RBufReadStream readStream;
	readStream.Open(*buffer);
	CleanupClosePushL(readStream);
	RPointerArray<CTzLocalizedTimeZoneRecord> timeZones;
	CleanupStack::PushL(TCleanupItem(CleanupTimeZonePointerArray,&timeZones));
	CTzLocalizedTimeZoneRecord::InternalizeL(readStream, timeZones);
	RPointerArray<CTzLocalizedCityRecord> cities;
	CleanupStack::PushL(TCleanupItem(CleanupCityPointerArray,&cities));
	CTzLocalizedCityRecord::InternalizeL(readStream, cities);
	
	TzServer()->LocalizationDb().WriteAllFrequentlyUsedZonesL(timeZones, cities);
	
	CleanupStack::PopAndDestroy();	// cities
	CleanupStack::PopAndDestroy();	// timeZones
	CleanupStack::PopAndDestroy(&readStream);
	CleanupStack::PopAndDestroy(buffer);
	
	return KErrNone;
	}

TInt CTzServerSession::doSwiObsBeginL(const RMessage2& /*aMessage*/)
	{
	TzServer()->SwiObserver().BeginL();
	return KErrNone;
	}

TInt CTzServerSession::doSwiObsFileChangedL(const RMessage2& aMessage)
	{
	TzServer()->SwiObserver().FileChangedL((RTz::TSWIObserverFilterIndex)aMessage.Int0());
	return KErrNone;
	}

TInt CTzServerSession::doSwiObsEndL(const RMessage2& /*aMessage*/)
	{
	TzServer()->SwiObserver().EndL();
	return KErrNone;
	}

void CTzServerSession::ServiceL(const RMessage2& aMessage)
	{
	TInt reply = KErrNone;
	switch(aMessage.Function())
		{
#if defined(_DEBUG)
	case CTzServer::ESrvOpcodeResourceCount:
		reply = doGetHeapSizeL(aMessage);
		break;
	case CTzServer::ESrvOpcodeSetHeapFailure:
		User::__DbgSetAllocFail(RHeap::EUser,(RAllocator::TAllocFail)aMessage.Int0(),aMessage.Int1());
		break;
	case CTzServer::ESrvOpcodeResetHeap:
		User::__DbgSetAllocFail(FALSE,RAllocator::ENone,1);
		iTzUserDataCache->Reset();
		TzServer()->TimeZoneManager().ResetForeignTimeZoneRulesCache();
		break;	
#endif
	case CTzServer::EConvertLocalZoneTime:
		reply = doConvertLocalZoneTimeL(aMessage);
		break;
	case CTzServer::EConvertForeignZoneTime:
		reply = doConvertForeignZoneTimeL(aMessage);
		break;
	case CTzServer::ESetTimeZone:
		reply = doSetTimeZoneL(aMessage);
		break;
	case CTzServer::ENotifyHomeTimeZoneChanged:
		reply = doNotifyHomeTimeZoneChanged(aMessage);
		break;
	case CTzServer::EGetLocalTimeZoneId:
		reply = doGetLocalTimeZoneIdL(aMessage);
		break;
	case CTzServer::EGetLocalEncodedTimeZoneRules:
		reply = doGetLocalEncodedTimeZoneRulesL(aMessage);
		break;
	case CTzServer::EGetLocalOlsenEncodedTimeZoneRules:	
		reply = KErrNotSupported;
		break;
	case CTzServer::EGetLocalEncodedTimeZoneRulesSize:
		reply = doGetLocalEncodedTimeZoneRulesSizeL(aMessage);
		break;		
	case CTzServer::EGetLocalOlsenEncodedTimeZoneRulesSize:
		reply = KErrNotSupported;
		break;		
	case CTzServer::EGetForeignEncodedTimeZoneRules:
		reply = doGetForeignEncodedTimeZoneRulesL(aMessage);
		break;
	case CTzServer::EGetForeignEncodedTimeZoneRulesSize:
		reply = doGetForeignEncodedTimeZoneRulesSizeL(aMessage);
		break;				
	case CTzServer::ERegisterTimeChangeNotifier:
		reply = doRegisterTzChangeNotifier(aMessage);
		break;
	case CTzServer::ECancelRequestforNotice:
		reply = doCancelRequestForTzChangeNoticeL(aMessage);
		break;
	case CTzServer::EGetOffsetsForTimeZoneIds:
		reply = doGetOffsetsForTimeZoneIdsL(aMessage);
		break;
	case CTzServer::EEnableAutoUpdate:
	    reply = doSetAutoUpdateBehaviorL(aMessage);
	    break;
	case CTzServer::EIsDaylightSavingOn:
	    reply = doIsDaylightSavingOnL(aMessage);
	    break;
	case CTzServer::EAutoUpdate:
	    reply = doAutoUpdateSettingL(aMessage);
	    break;
	case CTzServer::ESetHomeTime:
		reply = doSetHomeTimeL(aMessage);
		break;
	case CTzServer::ESetUnknownZoneTime:
		reply = doSetUnknownZoneTimeL(aMessage);
		break;
	case CTzServer::EGetUserTimeZoneNames:
		reply = doGetUserTimeZoneNamesL(aMessage);
		break;
	case CTzServer::EGetUserTimeZoneNamesSize:
		reply = doGetUserTimeZoneNamesSizeL(aMessage);
		break;
	case CTzServer::EGetUserTimeZoneIds:
		reply = doGetUserTimeZoneIdsL(aMessage);
		break;
	case CTzServer::EGetUserTimeZoneIdsSize:
		reply = doGetUserTimeZoneIdsSizeL(aMessage);
		break;
	case CTzServer::ECreateUserTimeZone:
		reply = doCreateUserTimeZoneL(aMessage);
		break;
	case CTzServer::EUpdateUserTimeZone:
		reply = doUpdateUserTimeZoneL(aMessage);
		break;
	case CTzServer::EDeleteUserTimeZone:
		reply = doDeleteUserTimeZoneL(aMessage);
		break;
	case CTzServer::ELocalizationReadCitiesSize:
		reply = doLocalizationReadCitiesSizeL(aMessage);
		break;
	case CTzServer::ELocalizationReadCitiesTzIdSize:
		reply = doLocalizationReadCitiesTzIdSizeL(aMessage);
		break;
	case CTzServer::ELocalizationReadCitiesInGroupSize:
		reply = doLocalizationReadCitiesInGroupSizeL(aMessage);
		break;
	case CTzServer::ELocalizationReadCities:
		reply = doLocalizationReadCitiesL(aMessage);
		break;
	case CTzServer::ELocalizationReadFrequentlyUsedZoneSize:
		reply = doLocalizationReadFrequentlyUsedZoneSizeL(aMessage);
		break;
	case CTzServer::ELocalizationReadFrequentlyUsedZone:
		reply = doLocalizationReadFrequentlyUsedZoneL(aMessage);
		break;
	case CTzServer::ELocalizationReadCachedTimeZoneCitySize:
		reply = doLocalizationReadCachedTimeZoneCitySizeL(aMessage);
		break;
	case CTzServer::ELocalizationReadCachedTimeZoneCity:
		reply = doLocalizationReadCachedTimeZoneCityL(aMessage);
		break;
	case CTzServer::ELocalizationOpenDb:
		reply = doLocalizationOpenDbL();
		break;
	case CTzServer::ELocalizationCloseDb:
		reply = doLocalizationCloseDb();
		break;
	case CTzServer::ELocalizationWriteCity:
		reply = doLocalizationWriteCityL(aMessage);
		break;
	case CTzServer::ELocalizationDeleteCity:
		reply = doLocalizationDeleteCityL(aMessage);
		break;
	case CTzServer::ELocalizationWriteFrequentlyUsedZone:
		reply = doLocalizationWriteFrequentlyUsedZoneL(aMessage);
		break;
	case CTzServer::ELocalizationWriteAllFrequentlyUsedZones:
		reply = doLocalizationWriteAllFrequentlyUsedZonesL(aMessage);
		break;
	case CTzServer::ESwiObsBegin:
		reply = doSwiObsBeginL(aMessage);
		break;
	case CTzServer::ESwiObsFileChanged:
		reply = doSwiObsFileChangedL(aMessage);
		break;
	case CTzServer::ESwiObsEnd:
		reply = doSwiObsEndL(aMessage);
		break;
	default:
		reply = KErrNotFound;
		break;
		}

	if (reply != KRequestPending)
		{
		aMessage.Complete(reply);
		}

#if defined(_DEBUG)
	User::Heap().Check();
#endif
	}

const CTzServer* CTzServerSession::TzServer() const
	{
	return static_cast<const CTzServer*>(Server());
	}

void CTzServerSession::CleanupTimeZonePointerArray(TAny* aArray)
	{
	RPointerArray<CTzLocalizedTimeZoneRecord>* array = static_cast<RPointerArray<CTzLocalizedTimeZoneRecord>* >(aArray);
	if (array)
		{
		array->ResetAndDestroy();
		array->Close();
		}
	}

void CTzServerSession::CleanupCityPointerArray(TAny* aArray)
	{
	RPointerArray<CTzLocalizedCityRecord>* array = static_cast<RPointerArray<CTzLocalizedCityRecord>* >(aArray);
	if (array)
		{
		array->ResetAndDestroy();
		array->Close();
		}
	}