calendarui/server/CalenSvr/src/CalenServer.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:32:31 +0100
branchRCL_3
changeset 66 bd7edf625bdd
child 67 1539a383d7b6
child 74 97232defd20e
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2004 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:   Provides class methods for creating Db , boot and missed alarm manager
*                implements CServer2 methods as part of IPC message interaction with client.
*
*/

#include <centralrepository.h>
#include <CalendarInternalCRKeys.h>
#include <calsession.h>
#include <calcalendarinfo.h>
#include <calenmulticalutil.h>
#include <CalenInterimUtils2.h>
#include <calensvrmissedalarmmanagerresource.rsg>
#include <data_caging_path_literals.hrh>
#include <bautils.h>
#include <pathinfo.h>
#include <calsession.h>

//debug
#include "calendarui_debug.h"

// INCLUDES
#include "CalenServer.h"

#include "CalSvrSession.h"
#include "CalSvrDef.h"
//#include "CalenSvrAlarmManager.h"
#include "CalenSvrBootManager.h"
#include "CalenSvrDBManager.h"
#include "calensvrmissedalarmmanager.h"
#include "calenmissedalarmconstants.h"

// LOCAL CONSTANTS AND MACROS

const TInt KCalenServerPriority(CActive::EPriorityStandard);
_LIT( KCalendarDatabaseFilePath, "c:calendar" );
const TInt KBufferStartingSize( 128 ); 
const TInt KBufferSizeIncrement( 64 );
const TInt KBuffLength = 128;


const TInt KComma( ',' );

_LIT(KPersonal,"Personal");


// ================= MEMBER FUNCTIONS =======================
//
// Construction and destruction 
//
// -----------------------------------------------------------------------------
// ?classname::?member_function
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
CCalenServer* CCalenServer::NewL()
    {
    TRACE_ENTRY_POINT;
    
    CCalenServer* server = new( ELeave )CCalenServer( KCalenServerPriority );

    CleanupStack::PushL(server);
    server->ConstructL();
    CleanupStack::Pop();
    
    TRACE_EXIT_POINT;
    return server;
    }

// -----------------------------------------------------------------------------
// ?classname::?member_function
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
CCalenServer::CCalenServer(TInt aPriority)
    : CServer2(aPriority, ESharableSessions)
    {
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// ?classname::?member_function
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
CCalenServer::~CCalenServer()
    {
    TRACE_ENTRY_POINT;
    if( iSession )
        {
        // stop listening for calendar file change notifications
        iSession->StopFileChangeNotification();
        delete iSession;
        }
    
    //delete iAlarmManager;
    delete iDBManager;
    delete iBootManager;
    delete iMissedAlarmHandler;
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// ?classname::?member_function
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCalenServer::ConstructL()
    {
    TRACE_ENTRY_POINT;
    
    TBool firstStartUp(EFalse);
    CheckForFirstStartUpL(firstStartUp);
    
    if(!firstStartUp)
        {
        TRAPD(error,CreateCalendarFilesL());
        if(error==KErrNone)
            {
            SetFirstStartUpL(ETrue);
            }
        }

    iBootManager = CCalenSvrBootManager::NewL( *this );
    iDBManager = CCalenSvrDBManager::NewL();
    //iAlarmManager = CCalenSvrAlarmManager::NewL();
    iMissedAlarmHandler = CCalenSvrMissedAlarmManager::NewL();
    
    
    // create cal session
    iSession = CCalSession::NewL();
    // start listening for calendar file change notifications
    iSession->StartFileChangeNotificationL(*this);

    StartL( KCalendarServerName );
    
    TRACE_EXIT_POINT;
    }

//
// CServer mandatory functions, e.g. session creation and error handling
//

// -----------------------------------------------------------------------------
// ?classname::?member_function
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
CSession2* CCalenServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const
    {
    TRACE_ENTRY_POINT;

    CCalSvrSession* session = new( ELeave )CCalSvrSession();

    CleanupStack::PushL( session );
    session->ConstructL( *const_cast<CCalenServer*>( this ) );
    CleanupStack::Pop( session );
    
    TRACE_EXIT_POINT;
    return session;
    }

// -----------------------------------------------------------------------------
// ?classname::?member_function
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CCalenServer::RunError(TInt aErr)
    /**
     * Handle leaves from ServiceL.
     * Any leave from a ServiceL() will land up here.
     **/
    {
    TRACE_ENTRY_POINT;
    
    // if it's a bad descriptor, panic the client
    if (aErr==KErrBadDescriptor)    // client had a bad descriptor
        {
        PanicClient(Message(), EBadDescriptor);
        // If client message is panicked, it is also completed.
        }
    else
        {
        // otherwise, complete the outstanding message with error
        Message().Complete(aErr);
        }
    ReStart(); // really means just continue reading client requests
    
    TRACE_EXIT_POINT;
    return KErrNone;
    }

// -----------------------------------------------------------------------------
// ?classname::?member_function
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCalenServer::PanicClient(const RMessage2& aMessage, TInt aPanic) const
    {
    TRACE_ENTRY_POINT;
    
    // FIXME: should we Panic Client, if client is running in 
    // phone thread ?
    // ok, go for it
    _LIT(KCalenSvrClientPanic, "CalenServer");
    aMessage.Panic(KCalenSvrClientPanic, aPanic);
    
    TRACE_EXIT_POINT;
    }

//
// Calendar server specific functionality
//

// -----------------------------------------------------------------------------
// ?classname::?member_function
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCalenServer::BootReadyL()
    {
    TRACE_ENTRY_POINT;
    iDBManager->BootReadyL();
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// ?classname::?member_function
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCalenServer::RegisterUserL(CCalenSvrDBManager::MCalenDBUser& aUser)
    {
    TRACE_ENTRY_POINT;
    iDBManager->RegisterUserL(aUser);
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// ?classname::?member_function
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCalenServer::UnregisterUserL(CCalenSvrDBManager::MCalenDBUser& aUser)
    {
    TRACE_ENTRY_POINT;
    iDBManager->UnregisterUserL(aUser);
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenServer::ServerMessage
// Returns the current IPC message.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
// 
const RMessage2 CCalenServer::ServerMessage() const
    {
    TRACE_ENTRY_POINT;

    TRACE_EXIT_POINT;
    return Message();
    }

// -----------------------------------------------------------------------------
// CCalenServer::CheckForFirstStartUpL
// checks for first start up by reading the information from cenrep key 
// -----------------------------------------------------------------------------
//
void CCalenServer::CheckForFirstStartUpL(TBool& aFirstStartUp)
    {
    TRACE_ENTRY_POINT;
    CRepository* cenRep = CRepository::NewLC(KCRUidCalendar);
    User::LeaveIfError(cenRep->Get(KCalendarStartupStatus, aFirstStartUp));
    CleanupStack::PopAndDestroy(cenRep);
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenServer::SetFirstStartUpL
// Sets first start up value to ETrue
// -----------------------------------------------------------------------------
//
void CCalenServer::SetFirstStartUpL(TBool aFirstStartUp)
    {
    TRACE_ENTRY_POINT;
    CRepository* cenRep = CRepository::NewLC(KCRUidCalendar);
    User::LeaveIfError(cenRep->Set(KCalendarStartupStatus, aFirstStartUp));
    CleanupStack::PopAndDestroy(cenRep);
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenServer::CreateCalendarFilesL
// Create default calendar files
// -----------------------------------------------------------------------------
//
TInt CCalenServer::CreateCalendarFilesL()
    {
    TRACE_ENTRY_POINT;
    
    CDesC16ArrayFlat* calendarNamesList = new (ELeave) CDesC16ArrayFlat(2);
    CleanupStack::PushL(calendarNamesList);
    // read calendar names from central repository
    ReadCalendarNamesFromResourceL(*calendarNamesList);
    
    RArray<TInt> calendarColors;
    // read calendar colors from central repository
    ReadCalendarColorsFromCenrepL(calendarColors);
    
    TInt calendarsCount = calendarNamesList->Count();
    TInt error(KErrNone);
    for (TInt index = 0; index < calendarsCount; index++)
        {
        // create cal session
        CCalSession* session = CCalSession::NewL();
        CleanupStack::PushL(session);
        
        // create and set metadata information from central repository
        CCalCalendarInfo* calendarInfo = CCalCalendarInfo::NewL();
        CleanupStack::PushL(calendarInfo);
        
        SetCalendarAddPropertiesL(*calendarInfo);
		
		calendarInfo->SetNameL(calendarNamesList->MdcaPoint(index));
        calendarInfo->SetColor(TRgb(calendarColors[index]));
        calendarInfo->SetEnabled(ETrue);

        if(!index)
            {
            TBuf<KMaxFileName> calendarFileName;
            calendarFileName.Append(KCalendarDatabaseFilePath);
            TRAPD(error,session->CreateCalFileL(calendarFileName,*calendarInfo));
			User::LeaveIfError(error);
            }
        else
            {
            HBufC* calFileName = 
                    CCalenMultiCalUtil::GetNextAvailableCalFileL();
            CleanupStack::PushL(calFileName);
            TRAPD(error,session->CreateCalFileL( calFileName->Des(),
                                        *calendarInfo));
			User::LeaveIfError(error);
            CleanupStack::PopAndDestroy(calFileName);
            }
        CleanupStack::PopAndDestroy(calendarInfo);
        CleanupStack::PopAndDestroy(session);
        }
    calendarColors.Close();
    CleanupStack::PopAndDestroy(calendarNamesList);
    TRACE_EXIT_POINT;
    return error;
    }

// -----------------------------------------------------------------------------
// CCalenServer::ReadCalendarNamesFromCenrepL
// Read calendar names from central repository
// -----------------------------------------------------------------------------
//
void CCalenServer::ReadCalendarNamesFromResourceL(CDesC16ArrayFlat& aCalendarNames)
    {
    TRACE_ENTRY_POINT;
    
    
    
    
    
        
    // personal
         HBufC* personalBuffer = KPersonal().AllocLC();    
        aCalendarNames.AppendL( personalBuffer->Des() );    
       CleanupStack::PopAndDestroy( personalBuffer );
       
   
   
    
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenServer::ReadCalendarColorsFromCenrepL
// Read calendar colors from central repository
// -----------------------------------------------------------------------------
//
void CCalenServer::ReadCalendarColorsFromCenrepL(RArray<TInt>& aCalendarColors)
    {
    TRACE_ENTRY_POINT;
    
    CRepository* repository = CRepository::NewL(KCRUidCalendar);
    CleanupStack::PushL(repository);

    TInt bufSize(KBufferStartingSize);
    TBool wasRead(EFalse);
    do
        {
        RBuf buf;
        CleanupClosePushL(buf);
        buf.CreateL(bufSize);
        // read calendar colors from cenrep
        TInt err = repository->Get(KCalendarDefaultColors, buf);
        if (err == KErrNone)
            {
            wasRead = ETrue;
            PopulateCalendarColorListL(buf, aCalendarColors);
            }
        else if (err == KErrOverflow)
            {
            bufSize += KBufferSizeIncrement;
            }
        else
            {
            User::Leave(err);
            }
        CleanupStack::PopAndDestroy(&buf);
        }
    while (!wasRead);

    CleanupStack::PopAndDestroy(repository);
    TRACE_EXIT_POINT;
    }

// -----------------------------------------------------------------------------
// CCalenServer::PopulateCalendarColorListL
// Populate calendar colors list from central repository buffer
// -----------------------------------------------------------------------------
//
void CCalenServer::PopulateCalendarColorListL( const TDesC& aRepositoryBuffer,
                        RArray<TInt>& aCalendarColors )
    {
    TRACE_ENTRY_POINT;
    
    TPtrC marker = aRepositoryBuffer;
    TInt calendarColorOffset;
    
  
    
    while ((calendarColorOffset = marker.Locate(TChar(KComma)))
            != KErrNotFound)
        {
        TLex lex(marker.Left(calendarColorOffset));
        TInt colorValue;
        User::LeaveIfError(lex.Val(colorValue));
        // append calendar color value to list
        aCalendarColors.Append(colorValue);
        // Set marker to one char after the comma.
        marker.Set(marker.Mid(calendarColorOffset + 1));
        if (marker.Locate(TChar(KComma)) == KErrNotFound)
            {
            lex = marker.Left(marker.Length());
            User::LeaveIfError(lex.Val(colorValue));
            aCalendarColors.Append(colorValue);
            }
        }
    TRACE_EXIT_POINT;
    }

// ----------------------------------------------------------------------------
// CCalenServer::SetCalendarAddPropertiesL
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenServer::SetCalendarAddPropertiesL(CCalCalendarInfo& aCalendarInfo)
    {
    TRACE_ENTRY_POINT

    // EFolderLUID
    TBuf8<KBuffLength> keyBuff;
    keyBuff.AppendNum(EFolderLUID);
    TRAPD(err,aCalendarInfo.PropertyValueL(keyBuff));

    if (KErrNotFound == err)
        {
        TUint calValue = 0;
        //Get the available offset value and set as property value.
        calValue = CCalenMultiCalUtil::GetNextAvailableOffsetL();
        TPckgC<TUint> calValuePckg(calValue);
        aCalendarInfo.SetPropertyL(keyBuff, calValuePckg);
        }
    
    // ECreationTime
    TTime currentTime;
    currentTime.HomeTime();
    
    keyBuff.Zero();
    keyBuff.AppendNum(ECreationTime);
    TRAP( err, aCalendarInfo.PropertyValueL( keyBuff ) );

    if (KErrNotFound == err)
        {
        TPckgC<TTime> pkgCreationTime(currentTime);
        aCalendarInfo.SetPropertyL(keyBuff, pkgCreationTime);
        }
    
    // EModificationTime
    keyBuff.Zero();
    keyBuff.AppendNum(EModificationTime);

    //At creation modification time will be same as creation time
    TPckgC<TTime> pkgModificationTime(currentTime);
    aCalendarInfo.SetPropertyL(keyBuff, pkgModificationTime);
    
    
    // ESyncStatus
    keyBuff.Zero();
    keyBuff.AppendNum(ESyncStatus);

    TBool status = ETrue;
    TPckgC<TBool> pkgSyncStatus(status);
    aCalendarInfo.SetPropertyL(keyBuff, pkgSyncStatus);
    
    // EIsSharedFolder
    keyBuff.Zero();
    keyBuff.AppendNum(EIsSharedFolder);

    TPckgC<TBool> pkgIsSharedFolder(ETrue);
    aCalendarInfo.SetPropertyL(keyBuff, pkgIsSharedFolder);
    
    // EGlobalUUID
    keyBuff.Zero();
    keyBuff.AppendNum(EGlobalUUID);
    TRAP(err,aCalendarInfo.PropertyValueL(keyBuff));
    
    if (KErrNotFound == err)
        {
        CCalenInterimUtils2* interimUtils = CCalenInterimUtils2::NewL();
        CleanupStack::PushL( interimUtils );
        HBufC8* guuid = interimUtils->GlobalUidL();
        TPtr8 guuidPtr = guuid->Des();
        CleanupStack::PushL( guuid );
        aCalendarInfo.SetPropertyL(keyBuff, guuidPtr);
        CleanupStack::PopAndDestroy( guuid );
        CleanupStack::PopAndDestroy( interimUtils );
        }

    // EOwnerName
    keyBuff.Zero();
    keyBuff.AppendNum(EOwnerName);
    TRAP(err,aCalendarInfo.PropertyValueL(keyBuff));
    
    if (KErrNotFound == err)
        {
        _LIT8( KCalendarOwnerName, "myself" );
        aCalendarInfo.SetPropertyL(keyBuff, KCalendarOwnerName);
        }
    
    // EMarkAsDelete
    keyBuff.Zero();
    keyBuff.AppendNum(EMarkAsDelete);
    TPckgC<TBool> pkgMarkAsDelete(EFalse);
    aCalendarInfo.SetPropertyL(keyBuff, pkgMarkAsDelete);

    TRACE_EXIT_POINT    
    }

// ----------------------------------------------------------------------------
// CCalenServer::CalendarInfoChangeNotificationL
// Handle calendar file change notifications
// ----------------------------------------------------------------------------
void CCalenServer::CalendarInfoChangeNotificationL( 
        RPointerArray<CCalFileChangeInfo>& aCalendarInfoChangeEntries)
    {
    TRACE_ENTRY_POINT;

    // get the file change count
    TInt calenInfoChangeCount = aCalendarInfoChangeEntries.Count();
    RArray<TInt> calendarColors;
    // read calendar colors from central repository
    ReadCalendarColorsFromCenrepL(calendarColors);

    for(TInt index = 0;index < calenInfoChangeCount;index++)
        {
        // default calendar is deleted/updated.
        if( !aCalendarInfoChangeEntries[index]->FileNameL().CompareF(KCalendarDatabaseFilePath) )
            {
            MCalFileChangeObserver::TChangeType changeType = 
            aCalendarInfoChangeEntries[index]->ChangeType();
            switch(changeType)
                {
                case MCalFileChangeObserver::ECalendarFileDeleted:
                    {
                    // create cal session
                    CCalSession* session = CCalSession::NewL();
                    CleanupStack::PushL(session);
                    
                    // create and set metadata information from central repository
                    CCalCalendarInfo* calendarInfo = CCalCalendarInfo::NewL();
                    CleanupStack::PushL(calendarInfo);
                    
                    // EFolderLUID
                    TBuf8<KBuffLength> keyBuff;
                    keyBuff.AppendNum(EFolderLUID);
                    TRAPD(err,calendarInfo->PropertyValueL(keyBuff));

                    //First set the folder uid as 100000 for default calendar.
                    // Later set the other properties
                    if (KErrNotFound == err)
                        {
                        TUint calValue = 0;
                        //Get the available offset value and set as property value.
                        calValue = 100000;
                        TPckgC<TUint> calValuePckg(calValue);
                        calendarInfo->SetPropertyL(keyBuff, calValuePckg);
                        }
                    SetCalendarAddPropertiesL(*calendarInfo);
                    calendarInfo->SetNameL(KCalendarDatabaseFilePath);
                    calendarInfo->SetColor(TRgb(calendarColors[0]));
                    calendarInfo->SetEnabled(ETrue);
                    TBuf<KMaxFileName> calendarFileName;
                    calendarFileName.Append(KCalendarDatabaseFilePath);
                    //create the default calendar.
                    TRAPD(error,session->CreateCalFileL(calendarFileName,*calendarInfo));
                    User::LeaveIfError(error);
                    CleanupStack::PopAndDestroy(calendarInfo);
                    CleanupStack::PopAndDestroy(session);
                    }
                break;
                case MCalFileChangeObserver::ECalendarInfoUpdated:
                    {
                    // create cal session
                    CCalSession* session = CCalSession::NewL();
                    CleanupStack::PushL(session);
                    session->OpenL(KCalendarDatabaseFilePath);
                    
                    CCalCalendarInfo* calendarInfo = session->CalendarInfoL();
                    CleanupStack::PushL(calendarInfo);

                    TBuf8<KBuffLength> keyBuff;
                    keyBuff.AppendNum(EMarkAsDelete);

                    TBool markAsdelete;
                    TPckgC<TBool> pkgMarkAsDelete(markAsdelete);
                    TRAPD(err,pkgMarkAsDelete.Set(calendarInfo->PropertyValueL(keyBuff)));
                    markAsdelete = pkgMarkAsDelete();
                    if( markAsdelete )
                        {
                        // Mark the CalFile as visible.
                        calendarInfo->SetEnabled( ETrue );
                        TBuf8<KBuffLength> keyBuff;

                        // Set the modification time as home time.
                        keyBuff.Zero();
                        keyBuff.AppendNum(EModificationTime);
                        TTime modificationTime;
                        modificationTime.HomeTime();
                        TPckgC<TTime> pkgModificationTime(modificationTime);
                        calendarInfo->SetPropertyL(keyBuff, pkgModificationTime);
                        
                        // Set the SyncStatus to ETrue
                        keyBuff.Zero();
                        keyBuff.AppendNum( ESyncStatus );
                        TBool syncstatus( ETrue );
                        TPckgC<TBool> pckgSyncStatusValue( syncstatus );
                        calendarInfo->SetPropertyL( keyBuff, pckgSyncStatusValue );
                        
                        // Mark the meta property as SoftDeleted
                        keyBuff.Zero();
                        keyBuff.AppendNum(EMarkAsDelete);
                        TPckgC<TBool> pkgSoftDelete( EFalse );
                        calendarInfo->SetPropertyL(keyBuff, pkgSoftDelete);

                        session->SetCalendarInfoL( *calendarInfo );
                        }
                    CleanupStack::PopAndDestroy(calendarInfo);
                    CleanupStack::PopAndDestroy(session);
                    }
                }
            }
        }
    TRACE_EXIT_POINT;
    }
// End of File