fotaapplication/fotaserver/FotaServer/src/fotaupdate.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:27:42 +0100
branchRCL_3
changeset 26 19bba8228ff0
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
 * Copyright (c) 2005-2006 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:   starts update sequence
 *
 */



// INCLUDE FILES
#include <StringLoader.h>
#include <fotaserver.rsg>
#include <centralrepository.h>
#include <AknUtils.h>
#include <AknBidiTextUtils.h> 
#include <biditext.h>
#include <gdi.h>
#include <fotaengine.h>
#include <apgtask.h>
#include <SyncMLNotifierParams.h>
#include <aknradiobuttonsettingpage.h> 
#include <akntitle.h>
#include <schtime.h>
#include <csch_cli.h>

#include "fotaupdate.h"
#include "fmsclient.h"
#include "FotaReminderDlg.h"
#include "FotasrvSession.h"
#include "fotaserverPrivateCRKeys.h"
#include "fotaserverPrivatePSKeys.h"





// ============== LOCAL FUNCTIONS ============================================



TInt WriteUpdateBitmapL( const TDesC& aText, const TDesC& aFile)
    {
    FLOG(_L("WriteUpdateBitmapL writing %S to %S w/ txtdir"),&aText,&aFile);

    TSize   screensize = CCoeEnv::Static()->ScreenDevice()->SizeInPixels();
    TInt                width  = screensize.iWidth - KBmpMargin*2;
    TInt                height =  screensize.iHeight;

    CArrayFixSeg<TPtrC>*   lines = new CArrayFixSeg<TPtrC>(5);
    CleanupStack::PushL(lines);
    CFbsBitmap*         bitmap = new ( ELeave ) CFbsBitmap;
    CleanupStack::PushL( bitmap );
    bitmap->Create(  TSize(width,height), EColor64K );
    CFbsBitmapDevice*   device = CFbsBitmapDevice::NewL( bitmap );
    CleanupStack::PushL( device );
    const CFont* font = AknLayoutUtils::FontFromId(EAknLogicalFontPrimaryFont);
    CFbsBitGc*          context;
    User::LeaveIfError( device->CreateContext( context ) );
    CleanupStack::PushL( context );
    TInt                ascent = font->AscentInPixels();
    TInt                descent = font->DescentInPixels();
    context->UseFont ( font );
    context->Clear(); // bg color

    // Visually ordered text
    HBufC* wrappedstring = AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(
            aText, width,*font, *lines);
    CleanupStack::PushL ( wrappedstring );
    TBool dirfound (ETrue);
    // direction of text, affects alignemnt
    TBidiText::TDirectionality direction = TBidiText::TextDirectionality(
            *wrappedstring, &dirfound );

    // Print visual text to bitmap
    for ( TInt i=0; i<lines->Count(); ++i ) 
        {
        TPtrC l = (*lines)[i];
        TInt top = (ascent+descent)*(i);
        TInt bot = (ascent+descent)*(i+1);
        TRect rect (0, top ,width, bot );
        CGraphicsContext::TTextAlign alignment = 
        direction==TBidiText::ELeftToRight ? CGraphicsContext::ELeft 
            : CGraphicsContext::ERight;
        context->DrawText(l, rect, ascent, alignment);
        }
    height = (ascent+descent)*lines->Count() + descent;
    bitmap->Resize( TSize(width,height));
    bitmap->Save( aFile );
    context->DiscardFont();
    CleanupStack::PopAndDestroy( wrappedstring );
    CleanupStack::PopAndDestroy( context );
    CleanupStack::PopAndDestroy( device );
    CleanupStack::PopAndDestroy( bitmap );
    CleanupStack::PopAndDestroy( lines );
    return 1;
    }


// ---------------------------------------------------------------------------
// PackageFileName  Creates pgk filename ,like 5.swupd
// ---------------------------------------------------------------------------
void PackageFileName( TInt aPkgid, TDes8& aFileName )
    {
    aFileName.AppendNum(aPkgid);
    aFileName.Append( KSwupdFileExt8 );
    }


// ---------------------------------------------------------------------------
// PackageFilePath  Creates pk file path, like c:\\private\\102072C4\\5.swupd
// ---------------------------------------------------------------------------
void PackageFilePath( TInt aPkgid, TDes8& aPath )
    {
    TBuf8<20> fn;
    PackageFileName ( aPkgid,fn);
    aPath.Append(KSwupdPath8);
    aPath.Append(fn);
    }

// ============================= MEMBER FUNCTIONS ============================


// ---------------------------------------------------------------------------
// CFotaUpdate::CFotaUpdate()
// ---------------------------------------------------------------------------
//
CFotaUpdate::CFotaUpdate() : CActive(EPriorityNormal) 
,iScheduledUpdate(NULL),iHandleUpdateAcceptLater(EFalse),iCentrep(NULL)
                {
                CActiveScheduler::Add( this ); 
                iNotifParams.iNoteType  = ESyncMLFwUpdUnknown;  
                iNotifParams.iIntParam  = 0;
                iChargeToMonitor = 0;
                iFinalizeLater = EFalse;
                }


// ---------------------------------------------------------------------------
// CFotaUpdate::~CFotaUpdate()
// ---------------------------------------------------------------------------
//
CFotaUpdate::~CFotaUpdate()
    {
    if(iScheduledUpdate)
        {
        delete iScheduledUpdate;
        iScheduledUpdate = NULL;	
        }
    iIntervalType.Close();  
    iInterval.Close();  
   if(iCentrep)
       {
       delete iCentrep;
       iCentrep = NULL;
       }
    }


// ---------------------------------------------------------------------------
// CFotaUpdate::NewL 
// ---------------------------------------------------------------------------
//
CFotaUpdate* CFotaUpdate::NewL (CFotaServer* aServer)
    {
    CFotaUpdate* ao = new (ELeave) CFotaUpdate();
    ao->iFotaServer = aServer;
    return ao;
    }

// ---------------------------------------------------------------------------
// CFotaUpdate::CheckUpdateResults
// Checks if there is update result file available (meaning that update just
// took place)
// ---------------------------------------------------------------------------
//
TBool CFotaUpdate::CheckUpdateResults( RFs& aRfs )
    {
    RFile   f;
    TInt    err;
    err = f.Open ( aRfs, KUpdateResultFile, EFileShareAny );
    f.Close();
    if ( err!=KErrNone )
        {
        return EFalse;
        }
    FLOG(_L(" CFotaUpdate::CheckUpdateResults  update result file Found! "));
    return ETrue;
    }


// ---------------------------------------------------------------------------
// CFotaUpdate::ExecuteUpdateResultFileL
// Read result code from update result file and update state accordingly. 
// Show notifier "Update succesful". Do some cleanup.
// ---------------------------------------------------------------------------
//
void CFotaUpdate::ExecuteUpdateResultFileL( RFs& aRfs )
    {
    FLOG(_L("CFotaUpdate::ExecuteUpdateResultFileL >>"));
    iFs = &aRfs;
    TInt                err;
    RFileReadStream     rstr;
    TInt                result;
    TInt                msglen;
    HBufC8*             message=NULL;
    HBufC16*            message16=NULL;
    TBool               deleteData ( EFalse );

    // Open update result file
    FLOG(_L("opening rstr 1/2  "));
    err = rstr.Open(*iFs,KUpdateResultFile ,EFileRead|EFileStream);
    FLOG(_L("opened  rstr 2/2  "));
    if(err) FLOG(_L("   update result file open err %d"), err);
    User::LeaveIfError (err );
    FLOG(_L("       0.1"));
    CleanupClosePushL( rstr );
    FLOG(_L("       0.2"));

    // Read resultcode 
    result = rstr.ReadUint32L();        FLOG(_L("       0.3"));
    msglen = rstr.ReadUint32L();        FLOG(_L("       0.4  result: %d  \
    msglen:%d "),  result, msglen);
    if(msglen != 0)
        {
        FLOG(_L("       0.5  reading msg"));
        message         = HBufC8::NewLC(msglen+1);
        TPtr8  ptrdesc  = message->Des();
        TRAPD ( err2, rstr.ReadL(ptrdesc) );
        if ( err2 != KErrNone && err2 != KErrEof)
            {
            FLOG(_L("  file read err %d"),err2); User::Leave( err2 ); 
            }

        message16 = HBufC16::NewLC (message->Des().Length());
        message16->Des().Copy( *message );
        FLOG(_L("   1 update result: %d"),  result) ;
        FLOG(_L("   2 dbg msg: %S"),message16);
        CleanupStack::PopAndDestroy( message16 );
        CleanupStack::PopAndDestroy( message );
        }

    FLOG(_L("       0.6 "));
    CleanupStack::PopAndDestroy( &rstr ); 

    // Map resultcode to FUMO result code
    RFotaEngineSession::TState  fstate  
    = RFotaEngineSession::EUpdateFailed;
    RFotaEngineSession::TResult fresult 
    = RFotaEngineSession::EResUpdateFailed;

    TDriveNumber drive;
    TBool toencrypt =   iFotaServer->NeedToEncryptL(drive);

    FLOG(_L("   3"));
    switch ( result )
        {
        case UPD_OK:
            {
            fstate = RFotaEngineSession::EUpdateSuccessfulNoData;
            fresult = RFotaEngineSession::EResSuccessful;
            deleteData = ETrue;
            LaunchNotifierL ( ESyncMLFwUpdResultNote, KErrNone, toencrypt );
            }
            break;
        case UPD_INSTALL_REQUEST_IS_INVALID:
            {
            fstate = RFotaEngineSession::EUpdateFailedNoData;
            fresult = RFotaEngineSession::EResUpdateFailed;
            deleteData = ETrue;
            LaunchNotifierL ( ESyncMLFwUpdResultNote, KErrNotFound, toencrypt );
            }
            break;
        case UPD_UPDATE_PACKAGE_IS_ABSENT:
            {
            fstate = RFotaEngineSession::EUpdateFailedNoData;
            fresult = RFotaEngineSession::EResUpdateFailed;
            }
            break;
        case UPD_UPDATE_PACKAGE_IS_CORRUPTED:
            {
            fstate = RFotaEngineSession::EUpdateFailedNoData;
            fresult = RFotaEngineSession::EResCorruptedFWUPD;
            deleteData = ETrue;
            LaunchNotifierL ( ESyncMLFwUpdResultNote, KErrNotSupported, toencrypt );
            }
            break;
        case UPD_UPDATE_PACKAGE_CONTENTS_IS_INVALID:
            {
            fstate = RFotaEngineSession::EUpdateFailedNoData;
            fresult = RFotaEngineSession::EResCorruptedFWUPD;
            deleteData = ETrue;
            LaunchNotifierL ( ESyncMLFwUpdResultNote, KErrNotSupported, toencrypt );
            }
            break;
        case UPD_UPDATE_PACKAGE_IS_NOT_COMPATIBLE_WITH_CURRENT_MOBILE_DEVICE:
            {
            fstate = RFotaEngineSession::EUpdateFailedNoData;
            fresult = RFotaEngineSession::EResPackageMismatch;
            deleteData = ETrue;
            LaunchNotifierL ( ESyncMLFwUpdResultNote, KErrNotSupported, toencrypt );
            }
            break;
        case UPD_FATAL_ERROR:
            {
            fstate = RFotaEngineSession::EUpdateFailedNoData;
            fresult = RFotaEngineSession::EResUpdateFailed;
            deleteData = ETrue;
            LaunchNotifierL ( ESyncMLFwUpdResultNote, KErrNotFound, toencrypt );
            }
            break;

        default:
            {
            FLOG(_L("   3.1 invalid result: %d"), result);
            LaunchNotifierL ( ESyncMLFwUpdResultNote, KErrNotFound, toencrypt );
            }
            break;      
        }

    // Find the state 60 (update  progressing) -> 100 (etc)
    RArray<TInt>    states;
    TPackageState   state;
    CleanupClosePushL (states);
    iFotaServer->iDatabase->OpenDBL();
    iFotaServer->iDatabase->GetAllL(states);

    FLOG(_L("   4.1 found %d states "),states.Count() );
    for(TInt i=0;i<states.Count(); ++i ) 
        {
        TPackageState   tmp;
        tmp = iFotaServer->iDatabase->GetStateL(  states[i]  );
        FLOG(_L("   5 got state "));
        if ( tmp.iState == RFotaEngineSession::EUpdateProgressing )
            {
            state = tmp;
            state.iState    = fstate;
            state.iResult   = fresult;
            FLOG(_L("   6 Updating state id %d  to %d ,result %d  ")
                    ,state.iPkgId, state.iState,state.iResult );
            iFotaServer->iDatabase->SetStateL(state,KNullDesC8
                    ,EFDBState|EFDBResult ) ;
            }
        }
    iFotaServer->iDatabase->CloseAndCommitDB();
    CleanupStack::PopAndDestroy(&states);


    // Delete request file
    err = BaflUtils::DeleteFile ( *iFs, KUpdateRequestFile );
    if ( err != KErrNone && err != KErrNotFound ) 
        {
        FLOG(_L("   6.1  req file deleted, err %d"), err);
        User::Leave(err); 
        } 

    // Write timestamp (shown to user in device management ui)
    if( fresult == RFotaEngineSession::EResSuccessful )
        {
        RFileWriteStream    wstr;
        TTime               time;
        User::LeaveIfError( wstr.Replace( *iFs, KUpdateTimeStampFileName
                ,EFileWrite ) );
        CleanupClosePushL ( wstr );
        time.HomeTime();
        TInt                year   = time.DateTime().Year();
        TInt                month  = time.DateTime().Month();    
        TInt                day    = time.DateTime().Day();    
        TInt                hour   = time.DateTime().Hour();    
        TInt                minute = time.DateTime().Minute();    
        wstr.WriteInt32L(year) ;
        wstr.WriteInt32L(month) ;
        wstr.WriteInt32L(day) ;
        wstr.WriteInt32L(hour) ;
        wstr.WriteInt32L(minute) ;   
        CleanupStack::PopAndDestroy (1); // wstr
        }
    // Delete package content
    if ( deleteData  && state.iPkgId > KErrNotFound )
        {
        iFotaServer->StoragePluginL()->DeleteUpdatePackageL( state.iPkgId ) ;
        }


    // Report state back to syncml server
    if ( state.iPkgId >= 0 )
        {
        FLOG(_L("   6.1 creating device mgmt session for profile %d")
                ,state.iProfileId);
        iFotaServer->CreateDeviceManagementSessionL( state );
        }
    else 
        {
        FLOG(_L(" No state found in 'update progress' mode! cannot report\
        status to DM server "));
        }

    FLOG(_L("CFotaUpdate::ExecuteUpdateResultFileL <<"));
    }

// ---------------------------------------------------------------------------
// CFotaUpdate::DeleteUpdateResultsL
// ---------------------------------------------------------------------------
//
void CFotaUpdate::DeleteUpdateResultFileL( RFs& aRfs )
    {
    FLOG(_L("CFotaUpdate::DeleteUpdateResultsL "));
    // Delete result file
    BaflUtils::DeleteFile( aRfs, KUpdateResultFile );
    BaflUtils::DeleteFile( aRfs, KUpdateRequestFile );
    BaflUtils::DeleteFile( aRfs, KUpdateBitmap );
    BaflUtils::DeleteFile( aRfs, KRestartingBitmap );
    }


// ---------------------------------------------------------------------------
// CFotaUpdate::RunL
//  Handles user selection (button press: accept/ cancel update)
// ---------------------------------------------------------------------------
//
void CFotaUpdate::RunL()
    {
    FLOG(_L( "[FotaServer] CFotaUpdate::RunL() >> %d"  ),iStatus.Int() );
    TBool       handled( EFalse );
    User::LeaveIfError(iNotifier.CancelNotifier(KSyncMLFwUpdNotifierUid));
    iNotifier.Close();

    if (iStatus.Int() == KErrNotFound )
        {
        FLOG(_L("Exiting...."));
        TApaTaskList taskList(iFotaServer->GetEikEnv()->WsSession());
        TApaTask task=taskList.FindApp(TUid::Uid(KOmaDMAppUid));
        if(task.Exists())
            {
            task.EndTask();
            }
        return;

        }
    // Handle update start query
    if ( iNotifParams.iNoteType == ESyncMLFwUpdStartQuery || iNotifParams.iNoteType == ESyncMLFwUpdForceQuery || iNotifParams.iNoteType == ESyncMLFwUpdPostponeLimitQuery)
        {
        FLOG(_L("   update start query"));
        // User pressed accept
        if ( iStatus.Int() == KErrNone )
            {
            handled = ETrue;
            HandleUpdateAcceptStartL();
            }
        // User pressed later
        else if ( iStatus.Int() == KErrCancel )
            {

            FLOG(_L("USER PRESSED LATER"));
            handled = ETrue;
            HandleUpdateAcceptLaterL();
            }
        }
    if ( iNotifParams.iNoteType == ESyncMLFwUpdStartQueryEnc )
        {
        FLOG(_L("   update start query"));

        if ( iStatus.Int() == KErrNone )
            {
            FLOG(_L(" user accepted query to decrypt memory"));
            handled = ETrue;
            TRAPD(err, iFotaServer->DoStartDecryptionL());
            
            if (err == KErrNotReady)
                {
                HandleUpdateErrorL(err);
                }
            }
        else if (iStatus.Int() == KErrCancel )
            {
            FLOG(_L("User pressed cancel. Don't decrypt. Stop."));
            handled = ETrue;
            LaunchNotifierL( ESyncMLFwUpdNoReminder , KErrNone );
            }

        }
    // Handle battery error
    if ( iNotifParams.iNoteType == ESyncMLFwUpdErrorNote )
        {

        if (iNotifParams.iIntParam == KErrBadPower || iNotifParams.iIntParam == KErrBadUsbPower)
            {
            FLOG(_L("       battery note"));
            if ( iStatus.Int() == KErrNone )
                {
                handled = ETrue;

                // Still check batt. (user might have connected charger)

                HandleErrorBasedonChargingTypeL();

                }
            else if (iNotifParams.iIntParam == KErrDeviceMemoryBusy)
                {
                FLOG(_L("Do nothing. Stop the update."));
                iFotaServer->FinalizeUpdateL();
                }
            else if (iNotifParams.iIntParam == KErrBadPowerForEnc)
                {
                if (iFinalizeLater)
                    {
                    FLOG(_L("Finalizing update now..."));
                    iFinalizeLater = EFalse;
                    iFotaServer->FinalizeUpdateL();
                    }
                }
            }
        }

    //  Handle update complete notification
    if ( iNotifParams.iNoteType == ESyncMLFwUpdResultNote )
        {
        handled = ETrue;
        DeleteUpdateResultFileL( iFotaServer->iFs );
        if (!iNotifParams.iEncryptReq)
            {
            FLOG(_L("Going to finalize update..."));
            iFotaServer->FinalizeUpdateL();
            }

        }
    if ( iNotifParams.iNoteType == ESyncMLFwUpdNoReminder )
        {
        FLOG(_L(" No Reminder selected"));
        if ( iStatus.Int() == KErrNone )
            {
            handled = ETrue;

            FindScheduleL( ETrue );
            iUpdateState.iState = RFotaEngineSession::EStartingUpdate;
            iFotaServer->iDatabase->OpenDBL();
            iFotaServer->iDatabase->SetStateL(iUpdateState ,KNullDesC8,EFDBState);
            iFotaServer->iDatabase->CloseAndCommitDB();

            // Report state back to syncml server
            if ( iUpdateState.iPkgId >= 0 && iUpdateState.iSendAlert )
                {
                FLOG(_L("   creating device mgmt session for profile %d")
                        ,iUpdateState.iProfileId);
                iFotaServer->CreateDeviceManagementSessionL( iUpdateState );
                }
            iFotaServer->FinalizeUpdateL();
            }
        }
    if ( iNotifParams.iNoteType == ESyncMLFwUpdResultNote && iNotifParams.iEncryptReq)
        {
        if (iStatus.Int() == KErrNone)
            {
            FLOG(_L("User wanted to start encryption..."));
            iFotaServer->DoStartEncryptionL();
            }
        else 
            {
            FLOG(_L("User do not want to start encryption."));
            }
        if (!iFinalizeLater)
            iFotaServer->FinalizeUpdateL();
        }
    if ( !handled ) 
        {
        FLOG(_L("CANNOT INTERPRET NOTIFIER RESULT CODE: %d"), iStatus.Int() );
        }

    FLOG(_L( "[FotaServer] CFotaUpdate::RunL() <<" ) );
    }





// ---------------------------------------------------------------------------
//  CFotaUpdate::HandleUpdateAcceptStartL()
//  Handles user selection of NOW
// ---------------------------------------------------------------------------
//
void CFotaUpdate::HandleUpdateAcceptStartL(TBool aSkipBatteryChk)
    {
    FLOG(_L("USER PRESSED ACCEPT"));

    TBool	enoughPower (EFalse);
    TInt usbchargingsupport =0;
    if (aSkipBatteryChk)
        {
        enoughPower = ETrue;
        }
    else
        {
        CRepository* centrep = NULL;
        //centrep = CRepository::NewLC( TUid::Uid(KFotaServerUid));
        TRAPD(err, centrep = CRepository::NewL( TUid::Uid(KFotaServerUid)));
        if(err)
            {
            FLOG(_L("reading from cenrep failed"));
            }

        if(centrep)
            {centrep->Get( KFotaUSBChargerEnabled , usbchargingsupport );
            if(usbchargingsupport != 0 && usbchargingsupport != 1)
                usbchargingsupport =0;
            delete centrep;
            } 
        centrep = NULL;
        enoughPower = CheckBatteryL(usbchargingsupport);
#if defined(__WINS__)
        enoughPower = ETrue;
#endif
        }
    // Failure due to low battery
    if ( !enoughPower )
        {
        FLOG(_L("Launching low battery notifier"));
        if(!usbchargingsupport)
            LaunchNotifierL( ESyncMLFwUpdErrorNote, KErrBadPower );
        else
            LaunchNotifierL( ESyncMLFwUpdErrorNote , KErrBadUsbPower );
        }            
    else
        {
        UpdateL();
        }   
    }


void CFotaUpdate::HandleUpdateErrorL(TInt aError, TInt aValue)
    {
    FLOG(_L("CFotaUpdate::HandleUpdateErrorL, error = %d, value = %d >>"), aError, aValue);

    switch (aError)
        {
        case KErrNotReady: //Called from within StartUpdate
            {
            LaunchNotifierL(ESyncMLFwUpdErrorNote,KErrDeviceMemoryBusy);
            }
            break;
        case KErrBadPower: //Called from fotaserver when battery power is not enough
            {
            iChargeToMonitor = aValue;
            CRepository* centrep = NULL;
            TRAPD(err, centrep = CRepository::NewL( TUid::Uid(KFotaServerUid)));
            if(err)
                {
                FLOG(_L("reading from cenrep failed"));
                }
            TInt usbchargingsupport =0;
            if(centrep)
                {centrep->Get( KFotaUSBChargerEnabled , usbchargingsupport );
                if(usbchargingsupport != 0 && usbchargingsupport != 1)
                    usbchargingsupport =0;
                delete centrep;
                } 
            centrep = NULL;
            FLOG(_L("Launching low battery notifier, usbsupport = %d, state = %d"), usbchargingsupport, iUpdateState.iState);
            if(!usbchargingsupport )
                {
                FLOG(_L("Here 1"));
                if (iUpdateState.iState == RFotaEngineSession::EStartingUpdate)
                    {
                    FLOG(_L("Here 2"));
                    LaunchNotifierL( ESyncMLFwUpdErrorNote, KErrBadPower );
                    }
                }
            else
                {
                LaunchNotifierL( ESyncMLFwUpdErrorNote , KErrBadUsbPower );
                }

            }
            break;
        default:
            {
            //Do nothing
            }
        }


    FLOG(_L("CFotaUpdate::HandleUpdateErrorL <<"));
    }

void CFotaUpdate::HandleEncryptionErrorL(TInt aError)
    {
    FLOG(_L("CFotaUpdate::HandleEncryptionErrorL, error = %d >>"), aError);

    if (aError == KErrBadPower)
        {
        iFinalizeLater = ETrue;
        LaunchNotifierL(ESyncMLFwUpdErrorNote, KErrBadPowerForEnc);
        }
    else 
        {
        FLOG(_L("Unknown error. Ignored"));
        }

    FLOG(_L("CFotaUpdate::HandleEncryptionErrorL <<"));
    }


// ---------------------------------------------------------------------------
//  CFotaUpdate::HandleUpdateAcceptLaterL
//  Handles user selection of Later
// ---------------------------------------------------------------------------
void CFotaUpdate::HandleUpdateAcceptLaterL()
    {
    TInt fotaUpdateAppName (EFotaUpdateDM);
    TInt err = RProperty::Get( KPSUidNSmlDMSyncApp, KNSmlCurrentFotaUpdateAppName, fotaUpdateAppName );
    FLOG(_L("Setting iHandleUpdateAcceptLater to True"));

    if (!err && ((fotaUpdateAppName == EFotaUpdateNSC) || (fotaUpdateAppName == EFotaUpdateNSCBg )))
        {
        iFotaServer->FinalizeUpdateL();		//make sure it is not called 2 times				
        }
    else
        {
        iHandleUpdateAcceptLater = ETrue;
        ShowReminderDialogL();				
        }
    }


// ---------------------------------------------------------------------------
//  CFotaUpdate::HandleErrorBasedonChargingTypeL
//  Handles the error based on charger type supported by the device
// ---------------------------------------------------------------------------

void CFotaUpdate::HandleErrorBasedonChargingTypeL()
    {
    FLOG(_L("CFotaUpdate::HandleErrorBasedonChargingTypeL >>"));

    if (iUpdateState.iState == RFotaEngineSession::EStartingUpdate)
        {
        if (iNotifParams.iIntParam == KErrBadUsbPower)
            {  
            FLOG(_L("handling usb charger error "));
            SetUpdateFailedStatesL();
            FLOG(_L("calling for monitoring  the battery"));
            iFotaServer->MonitorBattery(iChargeToMonitor);
            iFotaServer->FinalizeUpdateL();
            }
        else
            {
            TInt usbcharger = KErrNone; 
            TBool enoughPower = CheckBatteryL(usbcharger);

#if defined(__WINS__)
            //It will not come here, just used for testing.
            enoughPower = ETrue;
#endif

            if (enoughPower)
                {
                //User has connected the charger
                FLOG(_L("User has connected the charger"));
                UpdateL();
                }
            else
                {
                FLOG(_L("User hasn't connected the charger"));
                //User hasn't connected the charger, hence notify user to update later.
                SetUpdateFailedStatesL();
                //Call reminder here
                if(!iHandleUpdateAcceptLater)
                    {
                    FLOG(_L("calling HandleUpdateAcceptLaterL"));
                    HandleUpdateAcceptLaterL();
                    }
                iHandleUpdateAcceptLater = EFalse;
                }
            }
        }
    else //must be during encryption after update
        {
        if (iNotifParams.iIntParam == KErrBadUsbPower)
            {
            iFotaServer->MonitorBattery(iChargeToMonitor);
            }
        else
            {
            //nothing to do for dynamo charging
            }
        iFotaServer->FinalizeUpdateL();
        }
    FLOG(_L("CFotaUpdate::HandleErrorBasedonChargingTypeL <<"));
    }

// ---------------------------------------------------------------------------
//  CFotaUpdate::SetUpdateFailedStatesL
//  Set the state to update failed
// ---------------------------------------------------------------------------

void CFotaUpdate::SetUpdateFailedStatesL()
    {
    FLOG(_L("CFotaUpdate::SetUpdateFailedStatesL >>"));

    iUpdateState.iState = RFotaEngineSession::EStartingUpdate;
    iUpdateState.iResult= RFotaEngineSession::EResUpdateFailed;
    iFotaServer->iDatabase->OpenDBL();
    iFotaServer->iDatabase->SetStateL( iUpdateState ,KNullDesC8
            ,EFDBState|EFDBResult );
    iFotaServer->iDatabase->CloseAndCommitDB();

    FLOG(_L("CFotaUpdate::SetUpdateFailedStatesL <<"));

    }


// ---------------------------------------------------------------------------
// CFotaUpdate::DoCancel()
// ---------------------------------------------------------------------------
//
void CFotaUpdate::DoCancel()
    {
    FLOG(_L("CFotaUpdate::DoCancel() >>"));
    iNotifier.CancelNotifier(KSyncMLFwUpdNotifierUid);
    iNotifier.Close();
    FLOG(_L("CFotaUpdate::DoCancel() <<"));
    }

// ---------------------------------------------------------------------------
// CFotaUpdate::RunError(TInt aError)
// ---------------------------------------------------------------------------
//
TInt CFotaUpdate::RunError(TInt aError)
    {
    FLOG(_L("CFotaUpdate::RunError >> err %d"),aError);
    FLOG(_L("CFotaUpdate::RunError << err %d"),aError);
    return KErrNone;
    }

// ---------------------------------------------------------------------------
// CSyncMLNTestAppAO::LaunchNotifierL
// Shows one of the following queries: "update now?", "update success",
//  "update fail", "too low battery"
// ---------------------------------------------------------------------------
void CFotaUpdate::LaunchNotifierL( const TSyncMLFwUpdNoteTypes aNotetype
        ,const TInt aIntParam, const TBool aEnc )
    {
    FLOG(_L("CFotaUpdate::LaunchNotifierL() >>  prof.Id: %d")
            ,iUpdateState.iProfileId);
    if (!IsActive())
        {
        TSyncMLFwUpdNotifParams         params;
        params.iNoteType        = aNotetype;
        params.iIntParam        = aIntParam;
        params.iEncryptReq = aEnc;
        TSyncMLFwUpdNotifParamsPckg     pckg(params);
        iNotifParams.iNoteType  = params.iNoteType;
        iNotifParams.iIntParam  = params.iIntParam;
        iNotifParams.iEncryptReq = params.iEncryptReq;
        iDummyResponsePckg = TSyncMLFwUpdNotifRetValPckg();
        User::LeaveIfError( iNotifier.Connect() );
        iNotifier.StartNotifierAndGetResponse( iStatus,KSyncMLFwUpdNotifierUid
                , pckg, iDummyResponsePckg );
        SetActive();
        }
    FLOG(_L("CFotaUpdate::LaunchNotifierL() <<"));
    }


// ---------------------------------------------------------------------------
// CFotaUpdate::LaunchNotifierL
// Shows the postpone information note when postpone limit feature is enabled.
// ---------------------------------------------------------------------------
void CFotaUpdate::LaunchNotifierL( const TSyncMLFwUpdNoteTypes aNotetype
                                            ,const TInt aIntUserPostpone,const TInt aIntMaxPostpone,TIntervalType aIntervalType,const TInt aInterval)
    {
    FLOG(_L("CFotaUpdate::LaunchNotifierL() >>  prof.Id: %d aIntUserPostpone: %d aIntMaxPostpone %d")
                                            ,iUpdateState.iProfileId,aIntUserPostpone,aIntMaxPostpone);
    if (!IsActive())
        {
        TSyncMLFwUpdNotifParams         params;
        
        // Parameters to display the information note is displayed
    params.iNoteType        = aNotetype;
    params.iFotaUserPostponeCount = aIntUserPostpone;
    params.iFotaMaxPostponeCount = aIntMaxPostpone;
    params.iIntervalType = aIntervalType;
    params.iInterval = aInterval;
    
    /*
    if(iReminderString.Length() > 0)
        params.iSelectedReminder.Copy(iReminderString);
    
    TBuf<5> aTime;
    aTime.Zero();
    
    for(TInt i = 0; i<iReminderString.Length();i++)
        {
        TChar ch = iReminderString[i];
        if ( ch.IsDigit())            //separates digits from the string
            {  
            aTime.Append(ch); 
            }
        else
            {
            break;
            }
        }
    
    TInt val =1 ; 
    TLex  lex(aTime);
    TInt err = lex.Val(val); */

    TSyncMLFwUpdNotifParamsPckg     pckg(params);
    iNotifParams.iNoteType  = params.iNoteType;
    iNotifParams.iIntParam  = params.iIntParam;
    iDummyResponsePckg = TSyncMLFwUpdNotifRetValPckg();
    User::LeaveIfError( iNotifier.Connect() );
    iNotifier.StartNotifierAndGetResponse( iStatus,KSyncMLFwUpdNotifierUid
                                            , pckg, iDummyResponsePckg );
    SetActive();
        }
    FLOG(_L("CFotaUpdate::LaunchNotifierL() <<"));
    }




// ---------------------------------------------------------------------------
// CFotaUpdate::UpdateL
// Updates the fw: Creates input files for update agent and boots device to 
// update mode.
// ---------------------------------------------------------------------------
void CFotaUpdate::UpdateL()
    {
    FLOG(_L("CFotaUpdate::UpdateL() >>"));
    // Set state ........................................
    iUpdateState.iState  = RFotaEngineSession::EUpdateProgressing;
    iFotaServer->iDatabase->OpenDBL();
    iFotaServer->iDatabase->SetStateL( iUpdateState ,KNullDesC8, EFDBState );
    iFotaServer->iDatabase->CloseAndCommitDB();

    // Write update request for update agent..............
    FLOG(_L("CFotaUpdate::UpdateL  1 writing update.req "));
    TBuf8<150>           dp2filepath;
    HBufC16*             dp2;
    RFileWriteStream    wstr;
    CleanupClosePushL ( wstr );
    FLOG(_L("CFotaUpdate::UpdateL  2 getting pkg location"));
    iFotaServer->StoragePluginL()->GetUpdatePackageLocationL( 
            iUpdateState.iPkgId,  dp2filepath  );
    FLOG(_L("CFotaUpdate::UpdateL  3 craeting update.req") );
    User::LeaveIfError( wstr.Replace( iFotaServer->iFs
            ,KUpdateRequestFile, EFileWrite ) );
    wstr.WriteInt16L( 1 ); // version number is  1
    wstr.WriteInt32L( 1 ); // count   of cmds is 1
    wstr.WriteInt16L( 0 ); // requestid is 0

    dp2 = HBufC16::NewLC ( dp2filepath.Length( ) );
    dp2->Des().Copy( dp2filepath );
    wstr.WriteInt32L( dp2->Des().Length() + 1 ); // length of filename + null
    wstr.WriteL( dp2->Des() );
    wstr.WriteInt16L( 0 ); // null character
    CleanupStack::PopAndDestroy( dp2 );
    CleanupStack::PopAndDestroy( &wstr ); // wstr

    FLOG(_L("CFotaUpdate::UpdateL  4 craeting update.bmp") );

    // Write update graphic for update agent ...............
    HBufC*              updatetxt;
    HBufC*              restarttxt;
    updatetxt  = StringLoader::LoadLC( R_APPS_FOTA_UPDATING );
    restarttxt = StringLoader::LoadLC( R_APPS_FOTA_RESTARTING );
    WriteUpdateBitmapL( updatetxt->Des(), KUpdateBitmap );
    WriteUpdateBitmapL( restarttxt->Des(), KRestartingBitmap ); 
    CleanupStack::PopAndDestroy( restarttxt );
    CleanupStack::PopAndDestroy( updatetxt );
    TRAPD(error,FindScheduleL( ETrue)); //deleting the schedule (fix for failed update) 
    if(error)
        {
        FLOG(_L("CFotaUpdate::UpdateL  error in deleting previous schedule") );	

        }  
    // Simulate update agent by writing result file.
    CRepository* centrep( NULL);
    TInt err = KErrNone;
    TRAP(err, centrep = CRepository::NewL( KCRUidFotaServer ) );
    TInt simulate(KErrNotFound);
    if ( centrep ) 
        {
        err = centrep->Get( KSimulateUpdateAgent, simulate );
        }
    delete centrep;
    if ( simulate>0 )
        {   
        FLOG(_L("CFotaUpdate::UpdateL  5  - writing update.resp"));
        RFileWriteStream    respstr;
        CleanupClosePushL ( respstr );
        User::LeaveIfError( respstr.Replace( iFotaServer->iFs, KUpdateResultFile
                , EFileWrite ) );

        respstr.WriteUint32L(UPD_OK);
        respstr.WriteUint32L(15);
        respstr.WriteL(_L("UPDATE DONE!"));
        CleanupStack::PopAndDestroy( &respstr );
        }

    CRepository* centrep2 = NULL;
    TRAP( err, centrep2 = CRepository::NewL( KCRUidFotaServer ) )
    if (err==KErrNone ) 
        {
        centrep2->Set(  KFotaUpdateState, EFotaPendingGenAlert );
        if(iFOTAUICustomization)
            centrep2->Set(  KFOTAUserPostponeCount, 0 );
       }
     delete centrep2;
     
    // Boot to update mode 
    LaunchNotifierL( ESyncMLFwUpdRebootNote, KErrNone);

    FLOG(_L("   waiting 2 sec to keep 'restarting' visible"));
    User::After(TTimeIntervalMicroSeconds32(2000000));

    RStarterSession     starter;
    FLOG(_L("           starter->Connect"));
    User::LeaveIfError(starter.Connect());
    starter.Reset(RStarterSession::EFirmwareUpdate);
    starter.Close();
    FLOG(_L("CFotaUpdate::UpdateL() <<"));
    }   


// ---------------------------------------------------------------------------
// CFotaUpdate::CheckBatteryL()
// Cheks if there's enough battery power to update
// ---------------------------------------------------------------------------
//
TBool CFotaUpdate::CheckBatteryL(TBool aUSBChargingsupported)
    {
    TInt        chargingstatus( EChargingStatusError );
    TInt        batterylevel( 1 );
    TBool       enoughPower( EFalse );
    // Read battery
    FLOG(_L("   0.9 checking batt level"));
    RProperty   pw;
    User::LeaveIfError(pw.Attach(KPSUidHWRMPowerState,KHWRMBatteryLevel));
    User::LeaveIfError(pw.Get( batterylevel ));
    pw.Close();
    if(aUSBChargingsupported)
        {
        if ( batterylevel >= EBatteryLevelLevel2 ) 
            enoughPower = ETrue;

        //return enoughPower; 
        }
    else
        {
        User::LeaveIfError(pw.Attach(KPSUidHWRMPowerState,KHWRMChargingStatus));
        User::LeaveIfError(pw.Get( chargingstatus ));
        pw.Close();

        // Too low battery, power insufficient
        if ( batterylevel >= EBatteryLevelLevel2 ) 
            {
            enoughPower = ETrue;
            }
        // But charger is connected, power sufficient
        if ( chargingstatus != EChargingStatusError
                && chargingstatus != EChargingStatusNotConnected )
            {
            enoughPower = ETrue;
            }
        }

    if (!enoughPower)
        iChargeToMonitor = EBatteryLevelLevel2;
    FLOG(_L("   1.0 batt level: %d  (0..7), chargingstatus %d")
            ,batterylevel,chargingstatus);
    FLOG(_L("CFotaUpdate::checkBattery %d"), enoughPower?1:0 );
    return enoughPower;
    }


// ---------------------------------------------------------------------------
// CFotaUpdate::StartUpdateL
// Starts fw updating (shows a notifier to user). 
// ---------------------------------------------------------------------------
//
void CFotaUpdate::StartUpdateL( const TDownloadIPCParams &aParams )
    {
    FLOG(_L("CFotaUpdate::StartUpdateL(TDownloadIPCParams aParams) >> \
    pkig:%d"), aParams.iPkgId );
    TSmlProfileId profile(KErrNotFound);

    // Get update state from db
    iFotaServer->iDatabase->OpenDBL( );
    iUpdateState = iFotaServer->iDatabase->GetStateL( aParams.iPkgId );
    iFotaServer->iDatabase->CloseAndCommitDB( );

    FLOG(_L("   0 "));
    if ( iUpdateState.iPkgId == KErrNotFound )
        {
        FLOG(_L("  STATE NOT FOUND pkgid %d"), aParams.iPkgId);
        User::Leave(KErrNotFound);
        }

    // Resolve profile id
    RSyncMLSession sml;
    TInt                    tmp1;
    TSmlServerAlertedAction tmp2;
    TBool	                tmp3;
    TInt					tmp4;
    CleanupClosePushL( sml );
    sml.OpenL();
    // Use stored profile
    if ( aParams.iProfileId == KErrNotFound )
        {
        iFotaServer->GetProfileDataL( &sml,iUpdateState.iProfileId
                ,tmp1,tmp2,tmp3,tmp4);
        profile = iUpdateState.iProfileId;
        }
    // Use passed profile. If error, then try to use stored profile
    else
        {
        TRAPD(err, iFotaServer->GetProfileDataL( &sml,aParams.iProfileId
                ,tmp1,tmp2, tmp3, tmp4 ) );
        if ( err != KErrNone )
            {
            iFotaServer->GetProfileDataL( &sml,iUpdateState.iProfileId
                    ,tmp1,tmp2,tmp3,tmp4);
            profile = iUpdateState.iProfileId;
            }
        else
            {
            profile = aParams.iProfileId;
            }
        }
    CleanupStack::PopAndDestroy( &sml );

    // Must update package state with fresh params (it could be empty)
    TUint fields = EFDBState | EFDBPkgName|EFDBVersion;
    if ( profile != iUpdateState.iProfileId )
        {  
        fields |= EFDBProfileId;
        }

    iUpdateState.iProfileId     = profile;
    iUpdateState.iPkgName       = aParams.iPkgName;
    iUpdateState.iPkgVersion    = aParams.iPkgVersion;
    iUpdateState.iState         = RFotaEngineSession::EStartingUpdate;
    iUpdateState.iResult		= KErrNotFound;
    iUpdateState.iSendAlert     = EFalse; // HJHA-6MJCFE . This operation will
    // not reach any final state.
    iFotaServer->iDatabase->OpenDBL( );
    iFotaServer->iDatabase->SetStateL( iUpdateState, KNullDesC8, fields );
    iFotaServer->iDatabase->CloseAndCommitDB( );

    CRepository* centrep2 = NULL;
    TRAPD( err, centrep2 = CRepository::NewL( KCRUidFotaServer ) )
    if (err==KErrNone ) 
        {  TInt val;
        //
        centrep2->Get(  KFotaUpdateState, val );

        if(val == EFotaUpdateInterrupted)
            centrep2->Set(  KFotaUpdateState, EFotaDefault );
        }
    delete centrep2;

    FLOG(_L("CFotaUpdate::StartUpdateL  2"));
    //new code
    	 TInt client = iFotaServer->GetInstallUpdateClientL();
       if( CheckUpdateVariations() && 
   			client!= CFotaSrvSession::EOMADMAppUi &&  
         client != CFotaSrvSession::EFMSServer ) 
       {
       TInt callactive(EFalse);
       RFMSClient fmsclient;    
       TRAPD(err,fmsclient.OpenL());
       if(err == KErrNone)
           {
           CleanupClosePushL(fmsclient);
           FLOG(_L("CFotaUpdate::startupdate FMS for active call >>"));                
           TInt err1 = fmsclient.IsPhoneCallActive(callactive);
           FLOG(_L("IsPhoneCallActive returns %d  >>"),err1);       
           }
       if(callactive)
           {
           FLOG(_L(" active phone call found"));           
           
           FLOG(_L("putting call end Ao start pkgid=%d, profileid=%d"),iUpdateState.iPkgId,iUpdateState.iProfileId);
           TInt err1 = fmsclient.MonitorActivePhoneCallEnd(iUpdateState.iPkgId,iUpdateState.iProfileId);
           FLOG(_L("MonitorActivePhoneCallEnd returns %d  >>"),err1);    
           }
       else
           {
           FLOG(_L("CFotaUpdate::StartUpdateL  2"));
           
           TDriveNumber drive;

    TBool ret (EFalse);
    TRAPD(err2, ret = iFotaServer->NeedToDecryptL(iUpdateState.iPkgId, drive));
    if ( err2 == KErrNone )
        {
        if (!ret)
            {
            //Drive is not encrypted
			DisplayInstallationNoteTypeL();
            //LaunchNotifierL( ESyncMLFwUpdStartQuery, iUpdateState.iProfileId );
            }
        else
            {
            //Drive is encrypted.
            LaunchNotifierL( ESyncMLFwUpdStartQueryEnc, iUpdateState.iProfileId );
            }
        }
    else
        {
        HandleUpdateErrorL(err2);
        }
       
           }
       if(err == KErrNone) //fms opening error
           {
           CleanupStack::PopAndDestroy(&fmsclient);
           }
       }
   else
       {
       FLOG(_L("CFotaUpdate::StartUpdateL  2 DM UI Install update"));
       //LaunchNotifierL( ESyncMLFwUpdStartQuery, iUpdateState.iProfileId );
       
           TDriveNumber drive;

    TBool ret (EFalse);
    TRAP(err, ret = iFotaServer->NeedToDecryptL(iUpdateState.iPkgId, drive));
    if ( err == KErrNone )
        {
        if (!ret)
            {
            //Drive is not encrypted
			DisplayInstallationNoteTypeL();
            //LaunchNotifierL( ESyncMLFwUpdStartQuery, iUpdateState.iProfileId );
            }
        else
            {
            //Drive is encrypted.
            LaunchNotifierL( ESyncMLFwUpdStartQueryEnc, iUpdateState.iProfileId );
            }
        }
    else
        {
        HandleUpdateErrorL(err);
        }
       
       }                   

    //new code
    

    FLOG(_L("CFotaUpdate::StartUpdateL(TDownloadIPCParams aParams) << \
    pkig:%d"),aParams.iPkgId);
    }
	
	
void CFotaUpdate::DisplayInstallationNoteTypeL()
    {
    FLOG(_L("CFotaUpdate::DisplayInstallationNoteTypeL: >>"));
    
    //CRepository* centrep = NULL;
    TInt err = KErrNone;
    TInt CustomNotes = 0;
	if(iCentrep == NULL)
	{
    TRAP(err, iCentrep = CRepository::NewL(TUid::Uid(KFotaServerUid)));
    if(err)
        {
        FLOG(_L("DisplayInstallationNoteTypeL: reading from cenrep failed, returning ENormal"));
        LaunchNotifierL( ESyncMLFwUpdStartQuery, iUpdateState.iProfileId );
        return;
        }
	}
    
    err= iCentrep->Get( KFOTAUINotesCustomization, CustomNotes);    
    if (err)
        CustomNotes = 0;
    iFOTAUICustomization = CustomNotes;
    
    if(iFOTAUICustomization)
        {
        //TRAP(err, centrep = CRepository::NewL( TUid::Uid(KFotaServerUid)));
        //if(err)
        //    {
        //    FLOG(_L("DetermineNoteType: reading from cenrep failed, returning ETrue"));
        //    return ETrue;
        //    }
        
        TInt fotaUserPostpone = 0,fotaMaxPostpone = 3;
        if(iCentrep)
            {
            iCentrep->Get( KFOTAUserPostponeCount , fotaUserPostpone );
            iCentrep->Get( KFOTAMaxPostponeCount , fotaMaxPostpone );
            }
        iFOTAUserPostponeCount = fotaUserPostpone;
        iFOTAMaxPostponeCount = fotaMaxPostpone;

        if(iFOTAUserPostponeCount < iFOTAMaxPostponeCount)
            {
            FLOG(_L("DisplayInstallationNoteTypeL: returning EPostponeLimit"));
            LaunchNotifierL( ESyncMLFwUpdPostponeLimitQuery, iUpdateState.iProfileId );
            //return EPostponeLimit;
            }
        else
            {
            FLOG(_L("DisplayInstallationNoteTypeL: returning EForceStart"));
            LaunchNotifierL( ESyncMLFwUpdForceQuery, iUpdateState.iProfileId );
            //return EForceStart;
            }
        }
    else
        {
        FLOG(_L("DisplayInstallationNoteTypeL: returning ENormal"));
        LaunchNotifierL( ESyncMLFwUpdStartQuery, iUpdateState.iProfileId );
        //return ENormal;
        }
    
    }



// ---------------------------------------------------------------------------
// CFotaUpdate::CreateRadionButtonArrayLC
// Creates the array of radio buttons to display 
// on radio button setting page
// ---------------------------------------------------------------------------
//

CDesCArray* CFotaUpdate::CreateRadionButtonArrayLC( const TScheduleEntryInfo2 aScEntry,
        TInt& aSelectionIndex)
    {
    // selection defaults to 0
    FLOG(_L("CFotaUpdate::CreateRadionButtonArrayLC >>"));  
    aSelectionIndex = 0;
    CDesCArray* array = new (ELeave) CDesC16ArrayFlat(4);
    CleanupStack::PushL(array);
    for (TInt i=0;i<iInterval.Count();i++)   

        {    
        switch (iIntervalType[i])
            {
            case EHourly :
                {

                HBufC* string1 ;
                if(iInterval[i] == 1)
                    string1 = StringLoader::LoadLC(R_FOTA_RADIO_DIALOG_1HOUR_REMAINDER);
                else
                    string1 = StringLoader::LoadLC(R_QTN_FOTA_REMINDER_HOURS , iInterval[i] );

                array->AppendL( string1->Des() );
                CleanupStack::PopAndDestroy( string1 );
                if(aScEntry.Interval() == iInterval[i] && aScEntry.IntervalType()== EHourly ) 
                    aSelectionIndex = i; 
                }
                break; 

            case EDaily:
                {

                HBufC* string1; //= StringLoader::LoadLC(R_QTN_FOTA_REMINDER_DAYS , iInterval[i] );
                if(iInterval[i] == 1)
                    string1 = StringLoader::LoadLC(R_FOTA_RADIO_DIALOG_1DAY_REMAINDER);
                else
                    string1 = StringLoader::LoadLC(R_QTN_FOTA_REMINDER_DAYS , iInterval[i] );

                array->AppendL( string1->Des() );
                CleanupStack::PopAndDestroy( string1 );
                if(aScEntry.Interval() == iInterval[i] && aScEntry.IntervalType()== EDaily ) 
                    aSelectionIndex = i;
                }
                break;
            case EMonthly:
                {

                HBufC* string1 ;//== StringLoader::LoadLC(R_QTN_FOTA_REMINDER_MINUTES , iInterval[i] );
                if(iInterval[i] == 1)
                    string1 = StringLoader::LoadLC(R_QTN_FOTA_REMINDER_1_MINUTE);
                else
                    string1 = StringLoader::LoadLC(R_QTN_FOTA_REMINDER_MINUTES , iInterval[i] );

                array->AppendL( string1->Des() );
                CleanupStack::PopAndDestroy( string1 );
                if(aScEntry.Interval() == iInterval[i] && aScEntry.IntervalType()== EMonthly) 
                    aSelectionIndex = i;
                }
                break; 

                /*case EYearly:
    		     {
    		     tempChar.Num(iInterval[i]);
    		     HBufC* string1 = StringLoader::LoadLC(R_FOTA_RADIO_DIALOG_YEAR_REMAINDER , iInterval[i] );
               	 array->AppendL( string1->Des() );
               	 CleanupStack::PopAndDestroy( string1 );
               	 if(aScEntry.Interval() == iInterval[i] ) 
               	          aSelectionIndex = i;
    		     }
    		     break;*/
            }
        }

    if(iIntervalType[iIntervalType.Count()-1] == ENoReminderOn )
        {
        HBufC* string1 = StringLoader::LoadLC( R_FOTA_RADIO_DIALOG_NO_REMAINDER);
        array->AppendL( string1->Des() );
        CleanupStack::PopAndDestroy( string1 );
        }
    FLOG(_L("CFotaUpdate::CreateRadionButtonArrayLC <<"));  
    return array;
    }
// ---------------------------------------------------------------------------
// CFotaUpdate::ParseScheduleString()
// Parse the schedule string from cenrep
// ---------------------------------------------------------------------------
//
//
void CFotaUpdate::ParseScheduleStringL()
    {    
    FLOG(_L("CFotaUpdate::ParseScheduleString() >>")); 

    GetSchedulesInfoL();



    iInterval.Reset();
    iIntervalType.Reset();
    TBuf<5> aTime;
    TBuf<9> aSched,tempChar;
    aTime.Zero();
    aSched.Zero();


    //TText*sep =   (TText *)ksep.Ptr();
    TBufC<1>ksep(Ksep);
    TText *t = (TText *)ksep.Ptr();      //just for Initialization
    for(TInt i = 0; i<iscInfo.Length();i++)
        {

        TChar ch = iscInfo[i];
        if ( ch.IsDigit())            //separates digits from the string
            {  aTime.Append(ch); 

            }
        else
            {  
            aSched.Append(ch);             
            *t = ch;
            if (*t ==     'h' || *t =='H')      //hour
                { iIntervalType.Append(EHourly) ;
                TInt val =1 ; 
                TLex  lex(aTime);
                TInt err = lex.Val(val);
                if (err)
                    {
                    iInterval.Append(1);
                    }
                else
                    {
                    iInterval.Append(val); 	
                    }

                }
            else if (*t ==     'd'|| *t =='D')      //daily
                {iIntervalType.Append(EDaily);
                TInt val =1 ; 
                TLex  lex(aTime);
                TInt err = lex.Val(val);
                if (err)
                    {
                    iInterval.Append(1);
                    }
                else
                    {
                    iInterval.Append(val);  	
                    }

                }
            else if (*t ==     'm'||  *t =='M')   //minute
                {iIntervalType.Append( EMonthly);
                TInt val =1 ; 
                TLex  lex(aTime);
                TInt err = lex.Val(val);
                if (err)
                    {

                    iInterval.Append(1);
                    }
                else
                    {
                    iInterval.Append(val);  	
                    }

                }
            /* else if (*t ==     'y')   //year
                  {iIntervalType.Append( EYearly);
                    TInt val =1 ; 
               	    TLex  lex(aTime);
               	    TInt err = lex.Val(val);
               	    if (err)
               	    {

                        iInterval.Append(1);    
               	    }
               	    else
               	    {
               	     iInterval.Append(val); 	
               	    }

                  }*/
            else if (*t == ':')   //colon
                {
                aTime.Zero();
                aSched.Zero();
                }
            }
        }
    TBool  checkSchInfo =EFalse;

    if(iInterval.Count() == iIntervalType.Count() )
        {  
        for (TInt j =0 ;j< iInterval.Count();j++ )
            {                                                 //setting to default 1h:4h:1d:3d
            if(iInterval[j] < 0 || iIntervalType[j] > 3 ) 
                {   
                iInterval.Reset();    iIntervalType.Reset();
                iInterval.Append(1);  iIntervalType.Append(EHourly); 
                iInterval.Append(4);  iIntervalType.Append(EHourly); 
                iInterval.Append(1);  iIntervalType.Append(EDaily); 
                iInterval.Append(3);  iIntervalType.Append(EDaily);     
                checkSchInfo =ETrue;
                break;
                }
            }
        }
    else
        {        
        iInterval.Reset();    iIntervalType.Reset();
        iInterval.Append(1);  iIntervalType.Append(EHourly); 
        iInterval.Append(4);  iIntervalType.Append(EHourly);  //setting to default 1h:4h:1d:3d
        iInterval.Append(1);  iIntervalType.Append(EDaily); 
        iInterval.Append(3);  iIntervalType.Append(EDaily);     
        checkSchInfo =ETrue;
        }

    TPtrC16 lastFive =  iscInfo.Right(5);
    _LIT( KNoRem , "NROFF");
    TPtrC noRem( KNoRem );   //check for No Remainder
    if (lastFive != noRem || checkSchInfo)
        {
        iIntervalType.Append(ENoReminderOn);
        }
    else
        { 
        iIntervalType.Append(ENoReminderOff);

        }
    FLOG(_L("CFotaUpdate::ParseScheduleString() <<"));

    } 


// ---------------------------------------------------------------------------
// CFotaUpdate::GetSchedulesInfoL
// Get the schedule info from the cenrep
// ---------------------------------------------------------------------------
//
//
void CFotaUpdate::GetSchedulesInfoL()
    {

    CRepository* centrep = NULL;
    //TBuf<255> scInfo; 
    centrep = CRepository::NewLC( TUid::Uid(KFotaServerUid));
    if ( centrep )
        {TBuf<255> temp;
        if (centrep->Get( KFotaOptionsForReminderDuration , temp )==KErrNone && temp.Length() )
            {   FLOG(_L("CFotaUpdate::ParseScheduleString taking from cenrep <<"));
            temp.Trim();    //read from cenrep
            iscInfo.Copy(temp);
            }
        else
            {                               //else set to default
            iscInfo.Copy(KDefaultSched);  

            }
        CleanupStack::PopAndDestroy(centrep);
        }
    else
        {
        iscInfo.Copy(KDefaultSched);    //else set to default
        }	

    }

// ---------------------------------------------------------------------------
// CFotaUpdate::ShowReminderDialogL
// Prepare and display Reminder Dialog using RFotaReminderDlg
// on radio button setting page
// ---------------------------------------------------------------------------
//
void CFotaUpdate::ShowReminderDialogL()
    {
    // Push default content to navigation pane and change title
	if(iFOTAUICustomization)
	    {
	    //if(iFOTAUICustomization)
	    //    {
	        if(iCentrep)
	            {
	            // When User has pressed Later, Postpone limit has to be Incremented
	            iFOTAUserPostponeCount = iFOTAUserPostponeCount + 1;
	            iCentrep->Set( KFOTAUserPostponeCount , iFOTAUserPostponeCount );
	            }
	    //    }
	    
	    
	    if(iFOTAUserPostponeCount > iFOTAMaxPostponeCount)
	        {
	        // When User presses the end key during a Force Update Query or a Update Warning note, Force Update Query should be shown again.
	        TIntervalType   tIntervalType;    
	        TInt tInterval;
	        tIntervalType = (TIntervalType)EEndKeyReminder;
	        tInterval = 1;
	        CreateScheduleL ( iUpdateState.iPkgId, tIntervalType ,tInterval );
	        iFotaServer->FinalizeUpdateL();
	        return;
	        }
	    }
    CEikStatusPane* statusPane = iAvkonAppUi->StatusPane();
    CAknNavigationControlContainer* naviPane = NULL;
    HBufC* originalTitle;
    CAknTitlePane* titlePane = NULL;
    originalTitle = HBufC::NewLC( 50 ); //KNsmlMaxTitleSize

    if ( statusPane && statusPane->PaneCapabilities( 
            TUid::Uid(EEikStatusPaneUidTitle) ).IsPresent() )
        {
        naviPane = ( CAknNavigationControlContainer* )
        statusPane->ControlL( TUid::Uid(EEikStatusPaneUidNavi) );
        naviPane->PushDefaultL();
        titlePane = static_cast<CAknTitlePane*>
        ( statusPane->ControlL( TUid::Uid(
                EEikStatusPaneUidTitle) ) );
        if ( titlePane->Text() ) 
            {
            originalTitle->Des().Copy( *titlePane->Text() );
            HBufC* titleText = StringLoader::LoadLC(
                    R_QTN_DM_TITLE_SETTINGS_DIALOG );
            titlePane->SetTextL( *titleText );
            CleanupStack::PopAndDestroy( titleText );
            titleText = NULL;
            }
        }

    TApaTaskList taskList(iFotaServer->GetEikEnv()->WsSession());
    TApaTask task=taskList.FindApp(TUid::Uid(KFotaServerUid));

    if(task.Exists())
        task.BringToForeground();

    // Construct radio btn list and launch radio button dlg
    TScheduleEntryInfo2 en=FindScheduleL( EFalse );
    TInt radioSelectionIndex( KErrNotFound );
    TRAPD(error,ParseScheduleStringL());  
    if (error)
        {
        iInterval.Reset();    iIntervalType.Reset();
        iInterval.Append(1);  iIntervalType.Append(EHourly); 
        iInterval.Append(4);  iIntervalType.Append(EHourly); 
        iInterval.Append(1);  iIntervalType.Append(EDaily); 
        iInterval.Append(3);  iIntervalType.Append(EDaily); 
        iIntervalType.Append(ENoReminderOn);
        }
    if(iInterval.Count() > 4)
        {
        for(TInt i= 4;i <iInterval.Count();i++)
            iInterval.Remove(i);
        }  
    CDesCArray* itemArray = CreateRadionButtonArrayLC( en,radioSelectionIndex );

    TInt aEvent(KErrNone);
    CFotaReminderDlg* aFotaReminderDlg = CFotaReminderDlg::NewL(radioSelectionIndex,itemArray,aEvent );
    FLOG(_L("after creating fota reminder dialog"));   
    CleanupStack::PushL(aFotaReminderDlg);
    TInt presentPriotiry = CEikonEnv::Static()->RootWin().OrdinalPriority();
    TInt presentPosition = CEikonEnv::Static()->RootWin().OrdinalPosition();
    CEikonEnv::Static()->RootWin().SetOrdinalPosition(presentPosition, ECoeWinPriorityMedium);  //setting the priority to medium for activation on top of global notes

    TInt ret = aFotaReminderDlg->ExecuteLD(CAknSettingPage::EUpdateWhenChanged);
    CleanupStack::Pop(aFotaReminderDlg);	     							
    CleanupStack::PopAndDestroy( itemArray );

    CEikonEnv::Static()->RootWin().SetOrdinalPosition(presentPosition, presentPriotiry); //resetting to previous priority
    FLOG(_L("****Event key = %d"),aEvent);

    if (aEvent == EEventKey)
        {
        FLOG(_L("Exiting...."));
        TApaTaskList taskList(iFotaServer->GetEikEnv()->WsSession());
        TApaTask task=taskList.FindApp(TUid::Uid(KOmaDMAppUid));
        if(task.Exists())
            {
            task.EndTask();
            task.KillTask();
            }

        return;
        }
		if(naviPane)
    	naviPane->Pop();
    if(	titlePane )
    {	
    	if ( titlePane->Text() && originalTitle ) 
        {
        TRAP_IGNORE( titlePane->SetTextL( *originalTitle ) );
        }
    }
    CleanupStack::PopAndDestroy( originalTitle );
    task.SendToBackground();	

    CreateNewScheduleL(ret,radioSelectionIndex);	


    }

// ---------------------------------------------------------------------------
// CFotaUpdate::CreateNewScheduleL
// Creates the new schedule
// ---------------------------------------------------------------------------
//
void CFotaUpdate::CreateNewScheduleL(TInt aRet, TInt aRadioSelectionIndex)
    {

    TScheduleEntryInfo2 en=FindScheduleL( EFalse );
    TIntervalType   tIntervalType;    
    TInt tInterval; 
    if ( aRet && aRadioSelectionIndex== 0 ) 
        {
        FLOG(_L("Creating reminder: for 1st option"));
        tIntervalType = (TIntervalType)iIntervalType[aRadioSelectionIndex];				
        tInterval     = iInterval[aRadioSelectionIndex];
        if(iFOTAUICustomization)
                    LaunchNotifierL( ESyncMLFwUpdPostponeNote , iFOTAUserPostponeCount, iFOTAMaxPostponeCount, tIntervalType,tInterval);
        en=FindScheduleL( ETrue );
        CreateScheduleL ( iUpdateState.iPkgId, tIntervalType ,tInterval );
        iFotaServer->FinalizeUpdateL();
        }
    else if(aRet && aRadioSelectionIndex == 1 )
        {
        FLOG(_L("Creating reminder: 4 hours"));
        tIntervalType = (TIntervalType)iIntervalType[aRadioSelectionIndex];				
        tInterval     = iInterval[aRadioSelectionIndex];
        if(iFOTAUICustomization)
                    LaunchNotifierL( ESyncMLFwUpdPostponeNote , iFOTAUserPostponeCount, iFOTAMaxPostponeCount, tIntervalType,tInterval);
        en=FindScheduleL( ETrue );
        CreateScheduleL ( iUpdateState.iPkgId, tIntervalType ,tInterval );
        iFotaServer->FinalizeUpdateL();
        }
    else if(aRet && aRadioSelectionIndex == 2 )
        {
        FLOG(_L("Creating reminder: for 2nd option"));
        tIntervalType = (TIntervalType)iIntervalType[aRadioSelectionIndex];				
        tInterval     = iInterval[aRadioSelectionIndex];
        if(iFOTAUICustomization)
                    LaunchNotifierL( ESyncMLFwUpdPostponeNote , iFOTAUserPostponeCount, iFOTAMaxPostponeCount, tIntervalType,tInterval);
        en=FindScheduleL( ETrue );
        CreateScheduleL ( iUpdateState.iPkgId, tIntervalType ,tInterval );
        iFotaServer->FinalizeUpdateL();
        }
    else if(aRet && aRadioSelectionIndex == 3 )
        {
        FLOG(_L("Creating reminder: for 3rd option"));
        tIntervalType = (TIntervalType)iIntervalType[aRadioSelectionIndex];				
        tInterval     = iInterval[aRadioSelectionIndex];
        if(iFOTAUICustomization)
                    LaunchNotifierL( ESyncMLFwUpdPostponeNote , iFOTAUserPostponeCount, iFOTAMaxPostponeCount, tIntervalType,tInterval);
        en=FindScheduleL( ETrue );
        CreateScheduleL ( iUpdateState.iPkgId, tIntervalType ,tInterval );  
        iFotaServer->FinalizeUpdateL();
        }
    else if (!aRet || aRadioSelectionIndex == 4)
        {
        FLOG(_L("Deleting reminder, btn press %d"),aRet);
        TScheduleEntryInfo2 en=FindScheduleL( ETrue );

        if ( !aRet ) // cancel pressed
            {
			if(iFOTAUICustomization)
			    {
			    if(iCentrep)
			        {
			        	// When User has pressed Later and then does a cancel for the warning query, Postpone limit has to be decremented
			        iFOTAUserPostponeCount = iFOTAUserPostponeCount - 1;
			        iCentrep->Set( KFOTAUserPostponeCount , iFOTAUserPostponeCount );
			        }
			    }
			DisplayInstallationNoteTypeL();			
			}
        else			  // ok pressed
            {
            LaunchNotifierL( ESyncMLFwUpdNoReminder , KErrNone );
            //iFotaServer->FinalizeUpdateL();
            }
        }

    }

// ---------------------------------------------------------------------------
// CFotaUpdate::FindScheduleL
// Finds fotaupdate schedule (named [102072c4])
// ---------------------------------------------------------------------------
//
TScheduleEntryInfo2 CFotaUpdate::FindScheduleL( const TBool aDelete )
    {
    TScheduleEntryInfo2                     ret;
    TInt                                    err;    
    RScheduler                              sc;
    TTime                                   t; 
    TTsTime                                 time;
    TSchedulerItemRef                       scitem; 
    CArrayFixFlat<TSchedulerItemRef>*     	aSchRefArray = new CArrayFixFlat <TSchedulerItemRef>(5);
    TScheduleFilter                      	aFilter(EAllSchedules);
    User::LeaveIfError( sc.Connect() );                             // xx
    CleanupClosePushL( sc );
    CleanupStack::PushL(aSchRefArray);

    User::LeaveIfError( sc.GetScheduleRefsL( *aSchRefArray,aFilter) );  // xx
    FLOG(_L("Schedule items: "));
    for ( TInt i=0; i<aSchRefArray->Count(); ++i  )
        {
        TSchedulerItemRef it = (*aSchRefArray)[i];
        if ( it.iName == TUid::Uid(KFotaServerUid).Name()  )
            {
            TScheduleState2 sc_state;
            CArrayFixFlat<TScheduleEntryInfo2>*  sc_entries = new CArrayFixFlat <TScheduleEntryInfo2>(5);
            CArrayFixFlat<TTaskInfo>*            sc_tasks  = new CArrayFixFlat <TTaskInfo>(5);
            TTsTime                              sc_duetime;
            CleanupStack::PushL( sc_entries );
            CleanupStack::PushL( sc_tasks );
            FLOG (_L("%d. schedule handle: %d name:'%S'"),i,it.iHandle, &(it.iName) );

            err = sc.GetScheduleL ( it.iHandle , sc_state, *sc_entries,*sc_tasks,sc_duetime ); // xx

            TDateTime  dtm = sc_duetime.GetLocalTime().DateTime();
            FLOG(_L("   schedule duetime:%d:%d"), dtm.Hour(), dtm.Minute());

            if ( err ) FLOG(_L("     schedule  sc get err %d"),err);
            else 
                {
                for ( TInt k=0; k<sc_entries->Count();++k)
                    {
                    TScheduleEntryInfo2 sc_entry = (*sc_entries)[k];
                    ret = sc_entry;
                    TTime sctime = sc_entry.StartTime().GetLocalTime();
                    FLOG(_L("         schedule entry %d int-type:%d int:%d start: %d:%d"),k,sc_entry.IntervalType(),sc_entry.Interval(),sctime.DateTime().Hour(),sctime.DateTime().Minute());
                    }

                for ( TInt j=0; j<sc_tasks->Count();++j)
                    {
                    TTaskInfo sc_task = (*sc_tasks)[j];
                    FLOG(_L("         schedule task  %d  '%S'"),sc_task.iTaskId,&(sc_task.iName) );
                    if ( aDelete && sc_task.iName==TUid::Uid(KFotaServerUid).Name() )
                        {
                        FLOG(_L("          schedule DeleteTask %d"),sc_task.iTaskId);
                        User::LeaveIfError( sc.DeleteTask(sc_task.iTaskId) );       // xx
                        }
                    }
                }
            if ( aDelete )
                {
                FLOG(_L("     DeleteSchedule %d"),it.iHandle);
                User::LeaveIfError(sc.DeleteSchedule(it.iHandle ));                 // xx
                }
            CleanupStack::PopAndDestroy( sc_tasks );
            CleanupStack::PopAndDestroy( sc_entries );
            }
        }
    CleanupStack::PopAndDestroy( aSchRefArray );
    CleanupStack::PopAndDestroy(&sc);
    return ret;
    }



// ---------------------------------------------------------------------------
// CFotaUpdate::CreateScheduleL
// Creates fotaupdate schedule (named [102072c4])
// ---------------------------------------------------------------------------
//
TInt CFotaUpdate::CreateScheduleL ( const TInt aPackageId 
                                   ,TIntervalType  aIntervalType
                                   ,const TInt aInterval)
    {
    FLOG(_L("CFotaUpdate::CreateScheduleL ()") );
    const TInt KRepeatForever = 0;
    const TInt KTaskPriority = 1;
    _LIT(KFotaScheduleExe, "Z:\\sys\\bin\\fotaschedulehandler.exe");
    RScheduler                              sc;
    TTime                                   t; 
    TTsTime                                 time;
    TSchedulerItemRef                       scitem; 
    CArrayFixFlat<TScheduleEntryInfo2>*     scentries = new CArrayFixFlat <TScheduleEntryInfo2>(5);
    User::LeaveIfError( sc.Connect() );                                       // xx
    CleanupClosePushL( sc );
    CleanupStack::PushL(scentries );
    t.HomeTime(); 
    switch (aIntervalType)  //create schedule based on the interval type 
        {
        case EHourly :
            t = t + ((TTimeIntervalHours)aInterval);
            break;
        case EDaily  :
            t = t + ((TTimeIntervalDays) aInterval);
            break;
        case EMonthly :
            t = t + ((TTimeIntervalMinutes ) aInterval);
            break; 
        case EYearly  :
            t = t + ((TTimeIntervalYears ) aInterval);
            break;
		case EEndKeyReminder:
                        aIntervalType = (TIntervalType)EHourly;  
                        t = t + ((TTimeIntervalMinutes)aInterval);
                        break;
        default :
            User::Panic(KFotaPanic, KErrArgument);

        }  

    time.SetLocalTime( t );
    TScheduleEntryInfo2 scentry1(time, aIntervalType, aInterval, (TTimeIntervalMinutes)1440 ) ; // xx
    scentries->AppendL( scentry1 );

    scitem.iName = TUid::Uid(KFotaServerUid).Name();
    User::LeaveIfError( sc.Register(TFileName( KFotaScheduleExe ), 0 ) );    // xxx
    User::LeaveIfError( sc.CreatePersistentSchedule(scitem, *scentries) );   // xxx
    FLOG(_L("created schedule %d  %d:%d"),scitem.iHandle, t.DateTime().Hour(),t.DateTime().Minute() );
    TTaskInfo taskInfo;
    taskInfo.iName      = TUid::Uid(KFotaServerUid).Name();
    taskInfo.iRepeat    = KRepeatForever;
    taskInfo.iPriority  = KTaskPriority;

    TFotaScheduledUpdate fotareminder( aPackageId, scitem.iHandle );
    TPckg<TFotaScheduledUpdate>   fotareminderpkg(fotareminder);

    HBufC* data = HBufC::NewLC(fotareminderpkg.Length());
    data->Des().Copy(fotareminderpkg);

    User::LeaveIfError( sc.ScheduleTask(taskInfo, *data, scitem.iHandle) );  // xxx

    CleanupStack::PopAndDestroy( data );
    CleanupStack::PopAndDestroy( scentries );
    CleanupStack::PopAndDestroy(&sc);                                         // xx
    return scitem.iHandle;
	}
// --------------------------------------------------------------------------
// CFotaUpdate::CheckUpdateVariations
// Checks the Install update note display,when a phone call is active
// --------------------------------------------------------------------------
//
TBool CFotaUpdate::CheckUpdateVariations()
    {
    FLOG(_L("CFotaUpdate::CheckUpdateVariations >>"));
    CRepository* centrep( NULL);
    TRAPD(err, centrep = CRepository::NewL( KCRUidFotaServer ) );
    if (err) FLOG(_L("Error reading FotaServer cenrep... %d"),err);
    TInt supported(KErrNone);
    if (centrep ) 
        {
        err = centrep->Get( KFotaUpdateNoteDisplayAlways, supported );
        if (err) FLOG(_L("Error reading cenrep key... %d"),err);                
        delete centrep;
        centrep = NULL;
        }
    if(supported) //means note to be displayed when a call is active
        {
        return EFalse;
        }
    FLOG(_L("CFotaUpdate::CheckUpdateVariations <<"));
    return ETrue; //means note should not be displayed when a call is there
    }