sl@0: // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: // User includes sl@0: #include "SchLogger.h" sl@0: #include "SCHEDULE.H" sl@0: #include sl@0: #include "SCHCLI.H" sl@0: #include "SCHENTRY.H" sl@0: #include "SchTimer.h" sl@0: #include "SCHEXEC.H" sl@0: // Constants sl@0: const TInt KMaxTasksPerSchedule = 9999; sl@0: sl@0: //TScheduledTask sl@0: TScheduledTask::TScheduledTask(CScheduledTask& aTask, CClientProxy& aClient) sl@0: : iTask(aTask), sl@0: iClient(aClient) sl@0: { sl@0: } sl@0: sl@0: void TScheduledTask::OnDue(const TTsTime& aValidUntil) sl@0: { sl@0: LOGSTRING("TScheduledTask::OnDue - start"); sl@0: iTask.OnDue(aValidUntil); sl@0: iClient.ReadyToExecute(); sl@0: LOGSTRING("TScheduledTask::OnDue - end"); sl@0: } sl@0: sl@0: const HBufC& TScheduledTask::Data() const sl@0: { sl@0: return iTask.Data(); sl@0: } sl@0: sl@0: const TTaskInfo& TScheduledTask::Info() const sl@0: { sl@0: return iTask.Info(); sl@0: } sl@0: sl@0: const CClientProxy& TScheduledTask::Client() const sl@0: { sl@0: return iClient; sl@0: } sl@0: sl@0: void TScheduledTask::RemoveInfo() sl@0: { sl@0: LOGSTRING("TScheduledTask::RemoveInfo - start"); sl@0: iClient.RemoveTask(&iTask); sl@0: LOGSTRING("TScheduledTask::RemoveInfo - end"); sl@0: } sl@0: sl@0: void TScheduledTask::DecRepeat() sl@0: { sl@0: iTask.DecRepeat(); sl@0: } sl@0: sl@0: TInt TScheduledTask::Offset() sl@0: { sl@0: return (_FOFF(TScheduledTask, iLink)); sl@0: } sl@0: /*************************************************************************/ sl@0: //CSchedule functions sl@0: /*************************************************************************/ sl@0: CSchedule* CSchedule::NewLC(TInt aHandle, sl@0: const TDesC& aName, sl@0: TBool aPersists, sl@0: const CArrayFixFlat& aEntries, sl@0: const TSecurityInfo& aSecurityInfo) sl@0: { sl@0: CSchedule* self = new(ELeave) CSchedule(aSecurityInfo, aHandle, aPersists); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aName, aEntries); sl@0: return self; sl@0: } sl@0: sl@0: CSchedule* CSchedule::NewLC(TInt aHandle, sl@0: const TDesC& aName, sl@0: TBool aPersists, sl@0: const CArrayFixFlat& aEntries, sl@0: const TTsTime& aDefaultRunTime, sl@0: const TSecurityInfo& aSecurityInfo) sl@0: { sl@0: CSchedule* self = new(ELeave) CSchedule(aSecurityInfo, aHandle, aPersists); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aName, aEntries,aDefaultRunTime); sl@0: return self; sl@0: } sl@0: sl@0: CSchedule* CSchedule::NewL(CFileStore& aStore, TStreamId& aStreamId) sl@0: { sl@0: CSchedule* self = new(ELeave) CSchedule; sl@0: CleanupStack::PushL(self); sl@0: self->RestoreL(aStore, aStreamId);//get self from root sl@0: CleanupStack::Pop();//self sl@0: return self; sl@0: } sl@0: sl@0: CSchedule::CSchedule(const TSecurityInfo& aSecurityInfo, TInt aHandle, TBool aPersists) sl@0: : iId(aHandle), sl@0: iPersists(aPersists), sl@0: iEnabled(ETrue), sl@0: iTaskList(TScheduledTask::Offset()), sl@0: iEntryList(TScheduleEntry::Offset()), sl@0: iSecurityInfo(aSecurityInfo) sl@0: { sl@0: } sl@0: sl@0: CSchedule::CSchedule() sl@0: : iTaskList(TScheduledTask::Offset()), sl@0: iEntryList(TScheduleEntry::Offset()) sl@0: { sl@0: } sl@0: sl@0: CSchedule::~CSchedule() sl@0: { sl@0: LOGSTRING("CSchedule::~CSchedule - start"); sl@0: sl@0: delete iName; sl@0: RemoveTasks(EFalse); sl@0: RemoveEntries(); sl@0: RemoveConditions(); sl@0: sl@0: LOGSTRING("CSchedule::~CSchedule - end"); sl@0: } sl@0: sl@0: void CSchedule::ConstructL(const TDesC& aName, sl@0: const CArrayFixFlat& aEntries) sl@0: { sl@0: iName = aName.AllocL(); sl@0: AddEntriesL(aEntries); sl@0: } sl@0: sl@0: void CSchedule::ConstructL(const TDesC& aName, sl@0: const CArrayFixFlat& aEntries, sl@0: const TTsTime& aDefaultRunTime) sl@0: { sl@0: iName = aName.AllocL(); sl@0: AddConditionsL(aEntries); sl@0: sl@0: // we plug the default time in as the start time of a schedule entry sl@0: TScheduleEntryInfo2 info(aDefaultRunTime, EDaily, 1, 60*24); sl@0: TScheduleEntry* entry = ScheduleEntryFactory::CreateL(info); sl@0: iEntryList.AddLast(*entry); sl@0: } sl@0: sl@0: void CSchedule::RestoreL(CFileStore& aStore, TStreamId& aId) sl@0: { sl@0: RStoreReadStream scheduleStream; sl@0: scheduleStream.OpenLC(aStore, aId); sl@0: InternalizeL(scheduleStream); sl@0: CleanupStack::PopAndDestroy(&scheduleStream); sl@0: } sl@0: sl@0: TInt CSchedule::Offset() sl@0: { sl@0: return (_FOFF(CSchedule, iLink)); sl@0: } sl@0: sl@0: TBool CSchedule::ClientInSchedule(const TDesC& aClientName) sl@0: // sl@0: // returns true if the client is part of a task associated with this schedule sl@0: // sl@0: { sl@0: TSglQueIter tasks(iTaskList); sl@0: tasks.SetToFirst(); sl@0: // sl@0: TScheduledTask* task; sl@0: while ((task=tasks++)!=NULL) sl@0: { sl@0: if (task->Client().ExecutorFileName().MatchF(aClientName) == 0) sl@0: return ETrue; sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: // sl@0: //Task methods sl@0: // sl@0: sl@0: void CSchedule::AddTask(TScheduledTask& aTask) sl@0: { sl@0: iTaskList.AddFirst(aTask); sl@0: } sl@0: sl@0: void CSchedule::RemoveTasks(TBool aFromClient) sl@0: { sl@0: LOGSTRING("CSchedule::RemoveTasks - start"); sl@0: sl@0: TScheduledTask* task; sl@0: TSglQueIter taskIter(iTaskList); sl@0: taskIter.SetToFirst(); sl@0: while ((task = taskIter++) != NULL) sl@0: { sl@0: if (aFromClient) sl@0: { sl@0: task->RemoveInfo(); sl@0: } sl@0: RemoveTask(task); sl@0: } sl@0: sl@0: LOGSTRING("CSchedule::RemoveTasks - end"); sl@0: } sl@0: sl@0: void CSchedule::RemoveTask(TScheduledTask* aTask) sl@0: { sl@0: LOGSTRING("CSchedule::RemoveTask - start"); sl@0: sl@0: LOGSTRING2("CSchedule::RemoveTask - Schedule id: %d", iId); sl@0: iTaskList.Remove(*aTask); sl@0: delete aTask; sl@0: LOGSTRING("CSchedule::RemoveTask - end"); sl@0: } sl@0: sl@0: void CSchedule::NotifyTasks() sl@0: { sl@0: LOGSTRING("CSchedule::NotifyTasks - start"); sl@0: sl@0: TScheduledTask* task; sl@0: TSglQueIter taskIter(iTaskList); sl@0: taskIter.SetToFirst(); sl@0: TTsTime time; sl@0: while((task = taskIter++) != NULL) sl@0: { sl@0: if (iDueTime.IsUtc()) sl@0: time.SetUtcTime(iDueTime.GetUtcTime() + iValidityPeriod); sl@0: else sl@0: time.SetLocalTime(iDueTime.GetLocalTime()+iValidityPeriod); sl@0: sl@0: task->OnDue(time); sl@0: if (task->Info().iRepeat > 0) sl@0: task->DecRepeat(); sl@0: if (task->Info().iRepeat == 0) sl@0: RemoveTask(task); sl@0: } sl@0: sl@0: LOGSTRING("CSchedule::NotifyTasks - end"); sl@0: } sl@0: sl@0: TInt CSchedule::GenerateTaskId() sl@0: { sl@0: LOGSTRING("CSchedule::GenerateTaskId - start"); sl@0: sl@0: TInt id = iId; sl@0: TScheduledTask* task = Task(id); sl@0: while (task!=NULL) sl@0: { sl@0: if ((id-iId) > KMaxTasksPerSchedule) sl@0: return KErrOverflow; sl@0: id++; sl@0: task = Task(id); sl@0: } sl@0: LOGSTRING("CSchedule::GenerateTaskId - end"); sl@0: return id; sl@0: } sl@0: sl@0: TScheduledTask* CSchedule::Task(const TInt aTaskId) sl@0: { sl@0: TSglQueIter tasks(iTaskList); sl@0: tasks.SetToFirst(); sl@0: // sl@0: TScheduledTask* task; sl@0: while ((task=tasks++)!=NULL) sl@0: { sl@0: if (task->Info().iTaskId == aTaskId) sl@0: return task; sl@0: } sl@0: return NULL; sl@0: } sl@0: sl@0: void CSchedule::TasksL(CArrayFixFlat& aTasks) sl@0: { sl@0: LOGSTRING("CSchedule::TasksL - start"); sl@0: TSglQueIter taskIter(iTaskList); sl@0: taskIter.SetToFirst(); sl@0: TScheduledTask* task; sl@0: while ((task = taskIter++) != NULL) sl@0: { sl@0: aTasks.AppendL(task->Info()); sl@0: } sl@0: LOGSTRING("CSchedule::TasksL - end"); sl@0: } sl@0: sl@0: // sl@0: //Externalize/Internalize methods sl@0: // sl@0: void CSchedule::ExternalizeL(RWriteStream& aWriteStream) const sl@0: { sl@0: LOGSTRING("CSchedule::ExternalizeL - start"); sl@0: sl@0: aWriteStream.WriteInt32L(iId); sl@0: aWriteStream << *iName; sl@0: aWriteStream.WriteInt32L(iPersists); sl@0: aWriteStream.WriteInt32L(iEnabled); sl@0: sl@0: TInt count=0; sl@0: // Count the number of schedule entries so that sl@0: // we can write the count (in the stream) in advance sl@0: // of the entries themselves. sl@0: TSglQueIter iter(iEntryList); sl@0: iter.SetToFirst(); sl@0: sl@0: TScheduleEntry* entry; sl@0: while((entry=iter++)!=NULL) sl@0: count++; sl@0: aWriteStream.WriteInt32L(count); sl@0: sl@0: // Write the entries sl@0: iter.SetToFirst(); sl@0: while((entry=iter++)!=NULL) sl@0: { sl@0: entry->Info().ExternalizeL(aWriteStream); sl@0: } sl@0: sl@0: //write conditions sl@0: count = iConditions.Count(); sl@0: aWriteStream.WriteInt32L(count); sl@0: for(TInt ii = 0; ii(aReadStream.ReadInt32L()); sl@0: TTaskSchedulerCondition condition(category, key, state, type); sl@0: User::LeaveIfError(iConditions.Append(condition)); sl@0: } sl@0: sl@0: // read in security Info sl@0: aReadStream >> iSecurityInfo; sl@0: sl@0: LOGSTRING("CSchedule::InternalizeL - end"); sl@0: } sl@0: sl@0: // sl@0: //Entries methods sl@0: // sl@0: sl@0: void CSchedule::EntriesL(CArrayFixFlat& aEntries) sl@0: { sl@0: LOGSTRING("CSchedule::EntriesL - start"); sl@0: TSglQueIter entryIter(iEntryList); sl@0: entryIter.SetToFirst(); sl@0: TScheduleEntry* entry; sl@0: while ((entry = entryIter++) != NULL) sl@0: { sl@0: aEntries.AppendL(entry->Info()); sl@0: } sl@0: LOGSTRING("CSchedule::EntriesL - end"); sl@0: } sl@0: sl@0: void CSchedule::AddEntriesL(const CArrayFixFlat& aEntries) sl@0: { sl@0: LOGSTRING("CSchedule::AddEntriesL - start"); sl@0: TInt count = aEntries.Count(); sl@0: TScheduleEntryInfo2 entryInfo2; sl@0: TTsTime ttsTime; //temporary needed due to gccxml compiler sl@0: TDateTime dateTime; sl@0: sl@0: for (TInt i = 0;i& aEntries) sl@0: { sl@0: // remove the original entries sl@0: RemoveEntries(); sl@0: AddEntriesL(aEntries); sl@0: } sl@0: sl@0: void CSchedule::RemoveEntries() sl@0: { sl@0: LOGSTRING("CSchedule::RemoveEntries - start"); sl@0: sl@0: TScheduleEntry* entry; sl@0: TSglQueIter iter(iEntryList); sl@0: iter.SetToFirst(); sl@0: while ((entry = iter++) != NULL) sl@0: { sl@0: iEntryList.Remove(*entry); sl@0: delete entry; sl@0: } sl@0: sl@0: LOGSTRING("CSchedule::RemoveEntries - end"); sl@0: } sl@0: sl@0: //Condition methods sl@0: void CSchedule::AddConditionsL(const CArrayFixFlat& aConditions) sl@0: { sl@0: TInt count = aConditions.Count(); sl@0: for (TInt i = 0;i& aConditions) sl@0: { sl@0: // remove the original conditions sl@0: RemoveConditions(); sl@0: AddConditionsL(aConditions); sl@0: } sl@0: sl@0: void CSchedule::ConditionsL(CArrayFixFlat& aConditions) sl@0: { sl@0: TInt count = iConditions.Count(); sl@0: for (TInt i = 0;i entryIter(iEntryList); sl@0: entryIter.SetToFirst(); sl@0: TScheduleEntry* entry = entryIter; sl@0: if (entry == NULL) sl@0: User::Leave(KErrArgument); sl@0: return entry->DueTime(); sl@0: } sl@0: sl@0: // This method is called when ever a new task is scheduled or a change to an sl@0: // existing schedule is made. When one of the schedule entries in this schedule sl@0: // has become due, this is called with aNotFirstTime = ETrue. All this does is sl@0: // move the next due time into the next time frame. sl@0: void CSchedule::CalculateDueTime(TBool aNotFirstTime) sl@0: { sl@0: // Sort the list of entries sl@0: TSglQueIter iter(iEntryList); sl@0: iter.SetToFirst(); sl@0: TScheduleEntry* entry; sl@0: TTime currentTTime; sl@0: TTsTime currentTTsTime; sl@0: //make sure we reset iDueTime to max so that only the minimum is calculated. sl@0: TTsTime maxTime(Time::MaxTTime(), ETrue); sl@0: TTsTime dueTime; sl@0: iDueTime = maxTime; sl@0: while ((entry = iter++)!=NULL) sl@0: { sl@0: currentTTime.UniversalTime(); sl@0: currentTTsTime.SetUtcTime(currentTTime); sl@0: // This works out when the schedule is next due based on the input time sl@0: // and also updates the due time if it is home time based sl@0: dueTime = entry->NextScheduledTime(currentTTsTime); sl@0: if(aNotFirstTime && dueTime.GetUtcTime() <= currentTTime) sl@0: { sl@0: // We don't want this schedule to run straight away so seed the sl@0: // next due initial time-frame by incrementing the validity sl@0: currentTTime += entry->Info().ValidityPeriod(); sl@0: currentTTime += TTimeIntervalMicroSeconds32(1); // push into the next boundary sl@0: sl@0: if (dueTime.IsUtc()) sl@0: currentTTsTime.SetUtcTime(currentTTime); sl@0: else sl@0: currentTTsTime.SetLocalTime(currentTTime + dueTime.GetOffset()); sl@0: sl@0: dueTime = entry->NextScheduledTime(currentTTsTime); sl@0: } sl@0: if(dueTime.GetUtcTime() < iDueTime.GetUtcTime()) //find earliest due time from all entries sl@0: { sl@0: iDueTime = dueTime; sl@0: iValidityPeriod = entry->Info().ValidityPeriod(); sl@0: } sl@0: } sl@0: } sl@0: sl@0: // if aCalculateForConditions is true then entrycount corresponds sl@0: // to number of conditions; sl@0: void CSchedule::GetInfo(TScheduleInfo& aInfo, TBool aCalculateForConditions) sl@0: { sl@0: aInfo.iState.SetName(Name()); sl@0: aInfo.iState.SetDueTime(iDueTime); sl@0: aInfo.iState.SetPersists(Persists()); sl@0: aInfo.iState.SetEnabled(Enabled()); sl@0: TInt taskCount = 0; sl@0: sl@0: TSglQueIter taskIter(*Tasks()); sl@0: taskIter.SetToFirst(); sl@0: while (taskIter++ != NULL) sl@0: { sl@0: taskCount++; sl@0: } sl@0: aInfo.iTaskCount = taskCount; sl@0: TInt entryCount = 0; sl@0: if(!aCalculateForConditions) sl@0: { sl@0: TSglQueIter entryIter(iEntryList); sl@0: entryIter.SetToFirst(); sl@0: while (entryIter++ != NULL) sl@0: { sl@0: entryCount++; sl@0: } sl@0: } sl@0: else sl@0: entryCount = iConditions.Count(); sl@0: aInfo.iEntryCount = entryCount; sl@0: } sl@0: sl@0: const RArray& CSchedule::Conditions() const sl@0: { sl@0: return iConditions; sl@0: } sl@0: sl@0: TBool CSchedule::IsAccessAllowed(const RMessagePtr2& aMessage) const sl@0: { sl@0: // Access allowed if message SID is the same as the schedule creator sl@0: // or if client has WriteDeviceData sl@0: return aMessage.SecureId()==iSecurityInfo.iSecureId sl@0: || aMessage.HasCapability(ECapabilityWriteDeviceData) sl@0: || PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement)==0; // Enforcement off sl@0: } sl@0: sl@0: const TSecurityInfo& CSchedule::SecurityInfo() const sl@0: { sl@0: return iSecurityInfo; sl@0: } sl@0: sl@0: TBool CSchedule::IsUpdatable() sl@0: { sl@0: if(HasTasks() && Enabled() ) sl@0: return ETrue; sl@0: else sl@0: return EFalse; sl@0: }