--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fotaapplication/fotaserver/FotaServer/src/fotaupdate.cpp Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,1812 @@
+/*
+ * 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)
+ {
+ 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();
+ }
+
+
+// ---------------------------------------------------------------------------
+// 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 )
+ {
+ 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::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 );
+ }
+ 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
+ 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
+ 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);
+ }
+
+
+
+// ---------------------------------------------------------------------------
+// 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
+ 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;
+ }
+
+ naviPane->Pop();
+ 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];
+ 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];
+ 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];
+ 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];
+ 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
+ {
+ LaunchNotifierL( ESyncMLFwUpdStartQuery, iUpdateState.iProfileId );
+ }
+ 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
+ ,const 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;
+ 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
+ }
+