--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/email/imum/Utils/Src/ImumMboxScheduler.cpp Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,596 @@
+/*
+* Copyright (c) 2002 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:
+* Alwaysonline email scheduler class.
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32base.h>
+
+#include "ImumMboxScheduler.h"
+#include "ImumInSettingsData.h"
+#include "ImumInSettingsKeys.h"
+#include "ImumInternalApiImpl.h"
+#include "ImumUtilsLogging.h"
+
+// EXTERNAL DATA STRUCTURES
+// EXTERNAL FUNCTION PROTOTYPES
+// CONSTANTS
+const TInt KImumSecondsIn24Hours = 86400;
+const TInt KImumDaysInWeek = 7;
+
+// MACROS
+// LOCAL CONSTANTS AND MACROS
+// MODULE DATA STRUCTURES
+// LOCAL FUNCTION PROTOTYPES
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::CImumMboxScheduler()
+// ----------------------------------------------------------------------------
+//
+CImumMboxScheduler::CImumMboxScheduler(
+ CImumInternalApiImpl& aMailboxApi,
+ const TMsvId aMailboxId )
+ :
+ iMailboxApi( aMailboxApi ),
+ iDays( 0 ),
+ iStartTime( 0 ),
+ iStopTime( 0 ),
+ iMailboxId( aMailboxId )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::CImumMboxScheduler, 0, KLogInApi );
+
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::~CImumMboxScheduler()
+// ----------------------------------------------------------------------------
+//
+CImumMboxScheduler::~CImumMboxScheduler()
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::~CImumMboxScheduler, 0, KLogInApi );
+
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::ConstructL()
+// ----------------------------------------------------------------------------
+//
+void CImumMboxScheduler::ConstructL()
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::ConstructL, 0, KLogInApi );
+
+ // Load the data from the settings for further use
+ TInt64 days;
+ TMsvEntry mbox = iMailboxApi.MailboxUtilitiesL().GetMailboxEntryL(
+ iMailboxId, MImumInMailboxUtilities::ERequestReceiving );
+ iMailboxApi.SettingsStorerL().LoadAlwaysOnlineSettingsL(
+ mbox.iMtmData2, mbox.iMtm, days, iStartTime, iStopTime, iActive );
+
+ // First check if all of the days are unchecked, which should not happen
+ // at all, but just in case
+ iDays = !days ? TImumDaSettings::EFlagSetAllDays : days;
+ iActive = ( iActive != EMailAoOff ) ?
+ MImumInMailboxUtilities::EFlagTurnedOn : 0;
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::NewL()
+// ----------------------------------------------------------------------------
+//
+CImumMboxScheduler* CImumMboxScheduler::NewL(
+ CImumInternalApiImpl& aMailboxApi,
+ const TMsvId aMailboxId )
+ {
+ IMUM_STATIC_CONTEXT( CImumMboxScheduler::NewL, 0, utils, KLogInApi );
+
+ CImumMboxScheduler* self = NewLC( aMailboxApi, aMailboxId );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::NewLC()
+// ----------------------------------------------------------------------------
+//
+CImumMboxScheduler* CImumMboxScheduler::NewLC(
+ CImumInternalApiImpl& aMailboxApi,
+ const TMsvId aMailboxId )
+ {
+ IMUM_STATIC_CONTEXT( CImumMboxScheduler::NewLC, 0, utils, KLogInApi );
+
+ CImumMboxScheduler* self =
+ new ( ELeave ) CImumMboxScheduler( aMailboxApi, aMailboxId );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+
+ return self;
+ }
+
+/******************************************************************************
+
+ Public scheduling functions
+
+******************************************************************************/
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::AlwaysOnlineOn()
+// ----------------------------------------------------------------------------
+//
+TInt64 CImumMboxScheduler::QueryAlwaysOnlineStateL()
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::QueryAlwaysOnlineStateL, 0, KLogInApi );
+
+ TBool ok = EFalse;
+ TInt64 flags = 0;
+
+ if ( iActive )
+ {
+ // Get hometime
+ TTime clock;
+ TTimeIntervalSeconds homeTime;
+ TTimeIntervalSeconds startTime;
+ TTimeIntervalSeconds stopTime;
+ PrepareScheduling( clock, homeTime, startTime, stopTime );
+
+ flags = MImumInMailboxUtilities::EFlagTurnedOn;
+
+ ok = AlwaysOnlineOn( clock, homeTime, startTime, stopTime );
+
+ if ( ok )
+ {
+ flags |= MImumInMailboxUtilities::EFlagWaitingToConnect;
+ }
+ }
+
+ return flags;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::SecondsToNextMark()
+// ----------------------------------------------------------------------------
+//
+TInt64 CImumMboxScheduler::SecondsToNextMark(
+ TTimeIntervalSeconds& aSeconds )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::SecondsToNextMark, 0, KLogInApi );
+
+ // Get hometime
+ aSeconds = 0;
+ TTime clock;
+ TTimeIntervalSeconds homeTime;
+ TTimeIntervalSeconds startTime;
+ TTimeIntervalSeconds stopTime;
+ PrepareScheduling( clock, homeTime, startTime, stopTime );
+
+ // At first it needs to be checked, that either previous or current day
+ // is selected.
+ TValidConnectionDay validDay = GetValidConnectionDay( clock );
+ TBool timeToConnect = ( validDay != ENoConnection );
+
+ // Next step is to check, is it time for connection or disconnection
+ if ( timeToConnect )
+ {
+ timeToConnect = IsValidTimeToConnect(
+ validDay, homeTime, startTime, stopTime );
+ }
+
+ TInt connectStatus = !timeToConnect ?
+ MImumInMailboxUtilities::EFlagWaitingToConnect : 0;
+
+ // Finally calculate the time to next mark
+ CalculateSecondsToNextMark(
+ connectStatus, aSeconds, clock, homeTime, startTime, stopTime );
+
+ return connectStatus | iActive;
+ }
+
+/******************************************************************************
+
+ Private scheduling tools
+
+******************************************************************************/
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::PrepareScheduling()
+// ----------------------------------------------------------------------------
+//
+void CImumMboxScheduler::PrepareScheduling(
+ TTime& aClock,
+ TTimeIntervalSeconds& aHome,
+ TTimeIntervalSeconds& aStart,
+ TTimeIntervalSeconds& aStop )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::PrepareScheduling, 0, KLogInApi );
+
+ // Get the hometime and set the day flags
+ aClock.HomeTime();
+
+ // First, all the times has to be converted to seconds, to guarrantee
+ // proper comparisions for the times
+ Times2Seconds( aClock, aHome, aStart, aStop );
+
+ // Start and stop times needs to be reordered so, that the
+ // start time is before stop time in proportion to hometime
+ OrganizeStartAndStopTimes( aHome, aStart, aStop );
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::AlwaysOnlineOn()
+// ----------------------------------------------------------------------------
+//
+TBool CImumMboxScheduler::AlwaysOnlineOn(
+ const TTime& aClock,
+ TTimeIntervalSeconds& aHome,
+ TTimeIntervalSeconds& aStart,
+ TTimeIntervalSeconds& aStop )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::AlwaysOnlineOn, 0, KLogInApi );
+
+ TValidConnectionDay validDay = GetValidConnectionDay( aClock );
+ TBool result = EFalse;
+
+ // Connecting can be ok, if either previous or current day are checked
+ if ( validDay != ENoConnection )
+ {
+
+ result = IsValidTimeToConnect(
+ validDay, aHome, aStart, aStop );
+ }
+
+
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::GetValidConnectionDay()
+//
+// The connection is allowed in following cases:
+// Day: Mo Tu We Th Fr Sa Su
+// Checked: 0 0 0 1 1 0 0
+// Allowed: F F F T T T F
+// ----------------------------------------------------------------------------
+//
+CImumMboxScheduler::TValidConnectionDay
+ CImumMboxScheduler::GetValidConnectionDay(
+ const TTime& aClock )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::TValidConnectionDay, 0, KLogInApi );
+
+ // Get current and previous day and make sure it is selected
+ TDay currentDay = aClock.DayNoInWeek();
+ TDay previousDay = GetPrevDay( currentDay );
+ TValidConnectionDay result;
+
+
+ // Connection can be made anyday
+ if ( iDays.Flag( currentDay ) && iDays.Flag( previousDay ) )
+ {
+
+ result = EConnectionAnyDay;
+ }
+ // Connection can be established when start time is at current day
+ else if ( iDays.Flag( currentDay ) )
+ {
+
+ result = EConnectionCurrentDay;
+ }
+ // Connection can be established, if the connection begins from
+ // checked day
+ else if ( iDays.Flag( previousDay ) )
+ {
+
+ result = EConnectionPreviousDayOnly;
+ }
+ // Connection is not allowed
+ else
+ {
+
+ result = ENoConnection;
+ }
+
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::GetNextDay()
+// ----------------------------------------------------------------------------
+//
+TDay CImumMboxScheduler::GetNextDay(
+ const TDay aToday,
+ const TInt aNth )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::GetNextDay, 0, KLogInApi );
+
+ return static_cast<TDay>( ( aToday + aNth ) % KImumDaysInWeek );
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::GetPrevDay()
+// ----------------------------------------------------------------------------
+//
+TDay CImumMboxScheduler::GetPrevDay(
+ const TDay aToday,
+ const TInt aNth )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::GetPrevDay, 0, KLogInApi );
+
+ TInt weekIncrease = ( ( aNth / KImumDaysInWeek ) + 1 ) * KImumDaysInWeek;
+ return static_cast<TDay>( ( weekIncrease + aToday - aNth ) % KImumDaysInWeek );
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::IsValidTimeToConnect()
+// ----------------------------------------------------------------------------
+//
+TBool CImumMboxScheduler::IsValidTimeToConnect(
+ const TValidConnectionDay aValidDay,
+ TTimeIntervalSeconds& aHome,
+ TTimeIntervalSeconds& aStart,
+ TTimeIntervalSeconds& aStop )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::IsValidTimeToConnect, 0, KLogInApi );
+
+ TBool result = EFalse;
+
+ // Combine the possible combinations.
+ // Connection in current day is possible, only if the current day or
+ // all days are selected
+ TBool currentDay = ( aValidDay == EConnectionCurrentDay ||
+ aValidDay == EConnectionAnyDay );
+ // Connection can extended from previous day, only if previous day is
+ // set or all days are set
+ TBool previousDay = ( aValidDay == EConnectionPreviousDayOnly ||
+ aValidDay == EConnectionAnyDay );
+
+ // First it is needed to check that are the times even set
+ // If the times are equal, the times can be considered to be valid for
+ // all the day
+ if ( currentDay && aStart == aStop )
+ {
+ result = ETrue;
+ }
+ // It's allowed to make the connection in following situations homeTime
+ // is between startTime and stopTime, and the connection is allowed
+ // for the day. The connection is not allowed to be open during
+ // the last minute (aHome < aStop), but connection should be
+ // made at the start of the scheduling (aStart <= aHome).
+ else if ( aStart <= aHome && aHome < aStop )
+ {
+ // If connection extends from previous day and only extended connection
+ // is allowed
+ if ( previousDay && aStart.Int() < 0 )
+ {
+
+ result = ETrue;
+ }
+ // If previous day is not checked and connection extends over day
+ // make sure that the correct time is used
+ else if ( currentDay && aStart.Int() >= 0 )
+ {
+
+ result = ETrue;
+ }
+ else
+ {
+
+ result = EFalse;
+ }
+ }
+ // Neither of the statements were fulfilled, do not allow connection
+ else
+ {
+
+ result = EFalse;
+ }
+
+ return result;
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::AdjustHomeTime()
+// ----------------------------------------------------------------------------
+//
+TDateTime CImumMboxScheduler::AdjustHomeTime(
+ const TTime& aClock )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::AdjustHomeTime, 0, KLogInApi );
+
+ // Zero time is the beginning of the day
+ TTime zeroTime( 0 );
+
+ TDateTime dtHome = aClock.DateTime();
+ TDateTime dtZero = zeroTime.DateTime();
+
+ dtZero.SetHour( dtHome.Hour() );
+ dtZero.SetMinute( dtHome.Minute() );
+ dtZero.SetSecond( dtHome.Second() );
+
+ return dtZero;
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::Times2Seconds()
+//
+// This function converts home-, start- and stop times to secondes from the
+// beginning of the day
+// ----------------------------------------------------------------------------
+//
+void CImumMboxScheduler::Times2Seconds(
+ const TTime& aClock,
+ TTimeIntervalSeconds& aHome,
+ TTimeIntervalSeconds& aStart,
+ TTimeIntervalSeconds& aStop )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::Times2Seconds, 0, KLogInApi );
+
+
+ TTime zeroTime( 0 );
+ TTime adjustedHomeTime = AdjustHomeTime( aClock );
+ TTime selectedTimeStart( iStartTime );
+ TTime selectedTimeStop( iStopTime );
+ adjustedHomeTime.SecondsFrom( zeroTime, aHome );
+ selectedTimeStart.SecondsFrom( zeroTime, aStart );
+ selectedTimeStop.SecondsFrom( zeroTime, aStop );
+
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::OrganizeStartAndStopTimes()
+// ----------------------------------------------------------------------------
+//
+void CImumMboxScheduler::OrganizeStartAndStopTimes(
+ TTimeIntervalSeconds& aHome,
+ TTimeIntervalSeconds& aStart,
+ TTimeIntervalSeconds& aStop )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::OrganizeStartAndStopTimes, 0, KLogInApi );
+
+ // The start-, stop- and home times needs to be reordered so that the
+ // start is always before stop, in other words, start time is smaller
+ // than stop time.
+ //
+ // Following cases need to be considered:
+ // aStart < aStop (OK) - aStart > aStop (NOK)
+ // aHome < aStart < aStop ( aHome < aStop ) < aStart (start-24h)
+ // aStart < aHome < aStop aStop < aHome < aStart (end+24h)
+ // aStart < aStop < aHome aStop < aStart < aHome (end+24h)
+ if ( aStart > aStop )
+ {
+ // If we're between the the start and stop times,
+ // move this
+ if ( aHome < aStop )
+ {
+ // Set starting time to previous day
+ aStart = ( aStart.Int() - KImumSecondsIn24Hours );
+ }
+ else
+ {
+ // Set ending time to next day
+ aStop = ( aStop.Int() + KImumSecondsIn24Hours );
+ }
+ }
+
+
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::CalculateSecondsToNextMark()
+// ----------------------------------------------------------------------------
+//
+void CImumMboxScheduler::CalculateSecondsToNextMark(
+ TInt64 aConnectionStatus,
+ TTimeIntervalSeconds& aSeconds,
+ const TTime& aClock,
+ const TTimeIntervalSeconds& aHome,
+ const TTimeIntervalSeconds& aStart,
+ const TTimeIntervalSeconds& aStop )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::CalculateSecondsToNextMark, 0, KLogInApi );
+
+ // If all day is selected, next stop should be the midnight of the next
+ // (un)scheduled day depending on should the connection be on or off
+ if ( aStart == aStop )
+ {
+
+ aSeconds = CalcSecsToNextScheduledDay(
+ aClock, aHome,
+ aConnectionStatus == MImumInMailboxUtilities::EFlagWaitingToConnect );
+
+ }
+ // To calculate seconds, it needs to checked, should the connection be now
+ // on or off. If between, the connection should be on and seconds should
+ // be calculated to next disconnect time
+ else if ( aConnectionStatus != MImumInMailboxUtilities::EFlagWaitingToConnect )
+ {
+
+ CalcSecsToMark( aSeconds, aClock, aHome, aStop, EFalse );
+
+ }
+ //
+ else
+ {
+
+ CalcSecsToMark( aSeconds, aClock, aHome, aStart, ETrue );
+
+ }
+
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::CalcSecsToMark()
+// ----------------------------------------------------------------------------
+//
+void CImumMboxScheduler::CalcSecsToMark(
+ TTimeIntervalSeconds& aSeconds,
+ const TTime& aClock,
+ const TTimeIntervalSeconds& aHome,
+ const TTimeIntervalSeconds& aBonus,
+ const TBool aScheduledDay )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::CalcSecsToMark, 0, KLogInApi );
+
+ // If extending to next day, calculate seconds to next day
+ if ( aHome > aBonus )
+ {
+ aSeconds = CalcSecsToNextScheduledDay( aClock, aHome, aScheduledDay );
+ aSeconds = aSeconds.Int() + aBonus.Int();
+ }
+ else
+ {
+ aSeconds = aBonus.Int() - aHome.Int();
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CImumMboxScheduler::CalcSecsToNextScheduledDay()
+// ----------------------------------------------------------------------------
+//
+TTimeIntervalSeconds CImumMboxScheduler::CalcSecsToNextScheduledDay(
+ const TTime& aClock,
+ const TTimeIntervalSeconds& aHome,
+ const TBool aScheduledDay )
+ {
+ IMUM_CONTEXT( CImumMboxScheduler::CalcSecsToNextScheduledDay, 0, KLogInApi );
+
+ TTimeIntervalSeconds seconds = 0;
+ TBool hit = EFalse;
+ TDay today = aClock.DayNoInWeek();
+ TDay dayAfter = GetNextDay( today );
+ TInt dayCount = KErrNotFound;
+
+ while ( dayAfter != today && !hit )
+ {
+ dayCount++;
+ hit = ( iDays.Flag( dayAfter ) == aScheduledDay );
+ dayAfter = GetNextDay( dayAfter );
+ }
+
+
+ seconds = KImumSecondsIn24Hours - aHome.Int() +
+ dayCount * KImumSecondsIn24Hours;
+
+
+ return seconds;
+ }
+
+// End of File
+