genericservices/taskscheduler/SCHSVR/SSCH_SES.CPP
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 // User includes
       
    17 #include "SSCH_STD.H"
       
    18 #include "CSCHCODE.H"
       
    19 #include "SCHCLI.H"
       
    20 #include "SchLogger.h"
       
    21 #include "SCHMAN.H"
       
    22 #include "SCHEDULE.H"
       
    23 #include <schtask.h>
       
    24 
       
    25 // Constants
       
    26 const TInt KSchedulerArrayGranularity = 1; 
       
    27 _LIT(KSchedulerPanic, "Task Scheduler");
       
    28 
       
    29 void PanicClient(TInt aPanic, const RMessage2& aMessage)
       
    30 //
       
    31 // Toast the client
       
    32 //
       
    33 	{
       
    34 	//Note that panic also completes the message so don't complete anywhere else
       
    35 	aMessage.Panic(KSchedulerPanic,aPanic);
       
    36 	}
       
    37 	
       
    38 CSchSession::CSchSession(CTaskScheduler& aScheduler)
       
    39 //
       
    40 // C'Tor - must pass client to CSession
       
    41 //
       
    42 	:	CSession2(), 
       
    43 		iTaskScheduler(&aScheduler), 
       
    44 		iClient(NULL)
       
    45 	{
       
    46 	}
       
    47 
       
    48 CSchSession::~CSchSession()
       
    49 	{
       
    50 	if (iClient)
       
    51 		{
       
    52 		iClient->DecUsers();
       
    53 		if (!iClient->Users())
       
    54 			{
       
    55 			iClient->Remove();
       
    56 			delete iClient;
       
    57 			iClient = NULL;
       
    58 			}
       
    59 		}
       
    60 	if(!iPendingNotification.IsNull())
       
    61 		iPendingNotification.Complete(KErrCancel);	
       
    62 	}
       
    63 	
       
    64 void CSchSession::ServiceError(const RMessage2& aMessage,TInt aError)
       
    65 //
       
    66 // Handle an error or leave from CMySession::ServiceL()
       
    67 // A bad descriptor error implies a badly programmed client, so panic it;
       
    68 // otherwise use the default handling (report the error to the client)
       
    69 //
       
    70 	{
       
    71 	if (aError==KErrBadDescriptor)
       
    72 		PanicClient(EPanicBadDescriptor,aMessage);
       
    73 	CSession2::ServiceError(aMessage,aError);
       
    74 	}
       
    75 
       
    76 void CSchSession::ServiceL(const RMessage2& aMessage)
       
    77 //
       
    78 //	Handle messages for this session.
       
    79 //	all API functions are synchronous so complete here too
       
    80 //
       
    81 	{
       
    82 	
       
    83 	iClientMessage = BSUL::CClientMessage::NewL(aMessage);
       
    84 	
       
    85 	//Validate the message
       
    86 	TRAPD(error, iClientMessage->ValidateL());
       
    87 	
       
    88 	if(error == KErrNone)
       
    89 		{
       
    90 		TRAP(error, DoServiceL());
       
    91 		}
       
    92 	
       
    93    	// don't complete message if we have paniced client (ie message is NULL)
       
    94    	iClientMessage->CompleteRequestL(error);
       
    95 
       
    96    	delete iClientMessage;
       
    97    	iClientMessage = NULL;   	
       
    98 	}
       
    99 
       
   100 void CSchSession::DoServiceL()
       
   101 //
       
   102 //	Handle messages for this session.
       
   103 //	all API functions are synchronous so complete here too
       
   104 //
       
   105 	{
       
   106 	switch (iClientMessage->Function())
       
   107 		{
       
   108 #if defined (_DEBUG)
       
   109 	case ESchDbgMarkHeap:
       
   110 		__UHEAP_MARK;
       
   111 		break;
       
   112 	case ESchDbgCheckHeap:
       
   113 		__UHEAP_CHECK(iClientMessage->GetIntL(0));
       
   114 		break;
       
   115 	case ESchDbgMarkEnd:
       
   116 		{
       
   117 		TInt count = iClientMessage->GetIntL(0);
       
   118 		
       
   119 		//Three allocations are made for this message so add 3 to count
       
   120 		//CClientMessage::NewL
       
   121 		//CIntParameter::NewL
       
   122 		//RPointerArray::AppendL	
       
   123 		__UHEAP_MARKENDC(count + 3);
       
   124 		}
       
   125 		break;
       
   126 	case ESchDbgFailNext:
       
   127 		__UHEAP_FAILNEXT(iClientMessage->GetIntL(0));
       
   128 		break;
       
   129 	case ESchDbgResetHeap:
       
   130 		__UHEAP_RESET;
       
   131 		break;
       
   132 	case ESchFaultServer:
       
   133 		{
       
   134 		// make sure we complete the message first before Killing this server
       
   135 		iClientMessage->CompleteRequestL(KErrNone);
       
   136 		RProcess().Kill(0);
       
   137 		return;
       
   138 		}
       
   139 #endif
       
   140     case ERegisterClient:
       
   141 		RegisterClientL();
       
   142     	break;
       
   143 	case ECreateTimeSchedule:
       
   144 		CreateTimeScheduleL();
       
   145     	break;
       
   146 	case ECreateConditionSchedule:
       
   147 		CreateConditionScheduleL();
       
   148     	break;
       
   149 	case EScheduleTask:
       
   150 		ScheduleTaskL();
       
   151     	break;
       
   152 	case EDeleteTask:
       
   153 		DeleteTaskL();
       
   154 		break;
       
   155 	case EDeleteSchedule:
       
   156 		{
       
   157 		CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(0));
       
   158 		CheckPersistsInBackupL(*schedule);
       
   159 		//check that user has permission to delete this schedule.
       
   160 		schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   161 		iTaskScheduler->RemoveScheduleL(iClientMessage->GetIntL(0));
       
   162     	break;
       
   163 		}
       
   164 	case EDisableSchedule:
       
   165 		{
       
   166 		CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(0));
       
   167 		CheckPersistsInBackupL(*schedule);
       
   168 		//check that user has permission to disable this schedule.
       
   169 		schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   170 		iTaskScheduler->DisableScheduleL(iClientMessage->GetIntL(0));
       
   171     	break;
       
   172 		}
       
   173 	case EEnableSchedule:
       
   174 		{
       
   175 		CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(0));
       
   176 		CheckPersistsInBackupL(*schedule);
       
   177 		//check that user has permission to enable this schedule.
       
   178 		schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   179 		iTaskScheduler->EnableScheduleL(iClientMessage->GetIntL(0));
       
   180     	break;
       
   181 		}
       
   182 	case EEditTimeSchedule:
       
   183 		EditTimeScheduleL();
       
   184     	break;
       
   185 	case EEditConditionSchedule:
       
   186 		EditConditionScheduleL();
       
   187     	break;
       
   188 	case EGetScheduleRefs:
       
   189 		GetScheduleRefsL();
       
   190 		break;
       
   191 	case ECountSchedules:
       
   192 		CountSchedulesL();
       
   193 		break;
       
   194 	case EGetScheduleInfo:
       
   195 		GetScheduleInfoL();
       
   196 		break;
       
   197 	case EGetTimeScheduleData:
       
   198 		GetTimeScheduleDataL();
       
   199 		break;
       
   200 	case EGetConditionScheduleData:
       
   201 		GetConditionScheduleDataL();
       
   202 		break;
       
   203 	case EGetTaskData:
       
   204 		GetTaskDataL();
       
   205 		break;
       
   206 	case EGetTaskRefs:
       
   207 		GetTaskRefsL();
       
   208     	break;	
       
   209 	case ECountTasks:
       
   210 		CountTasksL();
       
   211 		break;
       
   212 	case EGetTask:
       
   213 		GetTaskInfoL();
       
   214 		break;
       
   215 	case EGetSchedulerItemRefAndNextDueTime:
       
   216 		GetScheduleItemRefAndDueTimeL();
       
   217 		break;
       
   218 	case EGetTaskDataSize:
       
   219 		GetTaskDataSizeL();
       
   220 		break;
       
   221 	case EGetScheduleType:
       
   222 		GetScheduleTypeL();
       
   223 		break;
       
   224 	default:
       
   225 		User::Leave(EPanicIllegalFunction);
       
   226 		break;
       
   227 		
       
   228         }//switch 
       
   229 
       
   230 	}
       
   231 
       
   232 //private functions
       
   233 void CSchSession::RegisterClientL()
       
   234 	{
       
   235 	TFileName writeBuf;
       
   236 
       
   237 	iClientMessage->ReadL(0,writeBuf);
       
   238 
       
   239 	// should return existing client if there is one
       
   240 	CClientProxy* client = iTaskScheduler->AddClientL(writeBuf, iClientMessage->GetIntL(1));
       
   241 	client->IncUsers();
       
   242 	if	(iClient)
       
   243 		{
       
   244 		iClient->DecUsers();
       
   245 		if	(!iClient->Users())
       
   246 			{
       
   247 			LOGSTRING2("CSchSession::RegisterClientL - removing existing client %S", &iClient->ExecutorFileName());
       
   248 			iClient->Remove();
       
   249 			delete iClient;
       
   250 			}
       
   251 		}
       
   252 	iClient = client;
       
   253 	}
       
   254 
       
   255 void CSchSession::CreateTimeScheduleL()
       
   256 	{
       
   257 	// get settings
       
   258 	TScheduleSettings2 settings;
       
   259 	TPScheduleSettings pS(settings);
       
   260 	iClientMessage->ReadL(0, pS);
       
   261 	
       
   262 	//WriteDeviceData needed to create persistent schedules
       
   263 	if(settings.iPersists)
       
   264 		{
       
   265 		// backup or restore in progress, so don't allow functions that might write to store
       
   266 		if (iTaskScheduler->BUROperationInProgress() != EBUROperationNoActivity)
       
   267 			{
       
   268 			User::Leave(KErrServerBusy);
       
   269 			}
       
   270 
       
   271 		CheckCapabilityL();
       
   272 		}	
       
   273 
       
   274 	//Verify that the length of the condition list passed in is as expected
       
   275 	if(iClientMessage->GetDesLengthL(1) != 
       
   276 				(settings.iEntryCount * sizeof(TScheduleEntryInfo2)))
       
   277 		{
       
   278 		User::Leave(KErrBadDescriptor);
       
   279 		}
       
   280 
       
   281 	// get entries
       
   282 	CArrayFixFlat<TScheduleEntryInfo2>* entries 
       
   283 		= new(ELeave) CArrayFixFlat<TScheduleEntryInfo2>(settings.iEntryCount);
       
   284 	CleanupStack::PushL(entries);
       
   285 	entries->ResizeL(settings.iEntryCount);
       
   286 	TPtr8 entriesPtr(REINTERPRET_CAST(TUint8*,&(entries->At(0))), settings.iEntryCount * sizeof(TScheduleEntryInfo2));
       
   287 	iClientMessage->ReadL(1, entriesPtr);
       
   288 
       
   289 	// create schedule
       
   290 	const TInt handle = iTaskScheduler->GenerateId();
       
   291 	if	(handle == KErrOverflow)
       
   292 		User::Leave(KErrOverflow);
       
   293 
       
   294 	// write back ID
       
   295 	TPInt id(handle);
       
   296 	iClientMessage->WriteL(2,id);
       
   297 
       
   298 	// get security info
       
   299 	TSecurityInfo securityInfo(iClientMessage->Message());	
       
   300 
       
   301 	// Create schedule and add to scheduler
       
   302 	CSchedule* newschedule = CSchedule::NewLC(handle, 
       
   303 										settings.iName, 
       
   304 										settings.iPersists, 
       
   305 										*entries,
       
   306 										securityInfo);
       
   307 	iTaskScheduler->AddScheduleL(*newschedule);
       
   308 	CleanupStack::Pop(newschedule);
       
   309 	CleanupStack::PopAndDestroy(entries);
       
   310 	}
       
   311 
       
   312 void CSchSession::CreateConditionScheduleL()
       
   313 	{
       
   314 	// get settings
       
   315 	TScheduleSettings2 settings;
       
   316 	TPScheduleSettings pS(settings);
       
   317 	iClientMessage->ReadL(0, pS);
       
   318 
       
   319 	//WriteDeviceData needed to create persistent schedules
       
   320 	if(settings.iPersists)
       
   321 		{
       
   322 		// backup or restore in progress, so don't allow functions that might write to store
       
   323 		if (iTaskScheduler->BUROperationInProgress() != EBUROperationNoActivity)
       
   324 			{
       
   325 			User::Leave(KErrServerBusy);
       
   326 			}
       
   327 
       
   328 		CheckCapabilityL();
       
   329 		}
       
   330 
       
   331 	//Verify that the length of the condition list passed in is as expected
       
   332 	if(iClientMessage->GetDesLengthL(1) != 
       
   333 				(settings.iEntryCount * sizeof(TTaskSchedulerCondition)))
       
   334 		{
       
   335 		User::Leave(KErrBadDescriptor);
       
   336 		}
       
   337 
       
   338 	// get entries
       
   339 	CArrayFixFlat<TTaskSchedulerCondition>* entries 
       
   340 		= new(ELeave) CArrayFixFlat<TTaskSchedulerCondition>(settings.iEntryCount);
       
   341 	CleanupStack::PushL(entries);
       
   342 	entries->ResizeL(settings.iEntryCount);
       
   343 	TPtr8 entriesPtr(REINTERPRET_CAST(TUint8*,&(entries->At(0))), settings.iEntryCount * sizeof(TTaskSchedulerCondition));
       
   344 	iClientMessage->ReadL(1, entriesPtr);
       
   345 	
       
   346 	// get time
       
   347 	TTsTime defaultRunTime;
       
   348 	TPckg<TTsTime> pTime(defaultRunTime);
       
   349 	iClientMessage->ReadL(2, pTime);
       
   350 
       
   351 	// create schedule
       
   352 	const TInt handle = iTaskScheduler->GenerateId();
       
   353 	if	(handle == KErrOverflow)
       
   354 		User::Leave(KErrOverflow);
       
   355 
       
   356 	// write back ID
       
   357 	TPInt id(handle);
       
   358 	iClientMessage->WriteL(3,id);
       
   359 	
       
   360 	// get security info
       
   361 	TSecurityInfo securityInfo(iClientMessage->Message());	
       
   362 
       
   363 	// Create schedule and add to scheduler
       
   364 	CSchedule* newschedule 
       
   365 		= CSchedule::NewLC(handle, 
       
   366 							settings.iName, 
       
   367 							settings.iPersists, 
       
   368 							*entries,
       
   369 							defaultRunTime,
       
   370 							securityInfo);
       
   371 	iTaskScheduler->AddScheduleL(*newschedule);
       
   372 	CleanupStack::Pop(newschedule);
       
   373 	CleanupStack::PopAndDestroy(entries);
       
   374 	}
       
   375 
       
   376 void CSchSession::EditTimeScheduleL()
       
   377 	{
       
   378 	CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(1));
       
   379 	
       
   380 	CheckPersistsInBackupL(*schedule);
       
   381 	//check that user has permission to edit this schedule.
       
   382 	schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   383 	
       
   384 	//check that this is a time schedule!
       
   385 	if(schedule->Type() != ETimeSchedule)
       
   386 		User::Leave(KErrArgument);
       
   387 		
       
   388 	// Get entry count
       
   389 	const TInt count = iClientMessage->GetIntL(0);
       
   390 	
       
   391 	//Verify that the length of the condition list passed in is as expected
       
   392 	if(iClientMessage->GetDesLengthL(2) != (count * sizeof(TScheduleEntryInfo2)))
       
   393 		{
       
   394 		User::Leave(KErrBadDescriptor);
       
   395 		}
       
   396 
       
   397 	// Get new entry list
       
   398 	CArrayFixFlat<TScheduleEntryInfo2>* entries 
       
   399 		= new(ELeave) CArrayFixFlat<TScheduleEntryInfo2> (KSchedulerArrayGranularity);	
       
   400 	CleanupStack::PushL(entries);
       
   401 	entries->ResizeL(count);
       
   402 	TPtr8 entriesPtr(REINTERPRET_CAST(TUint8*, &(entries->At(0))), count*sizeof(TScheduleEntryInfo2));
       
   403 
       
   404 	iClientMessage->ReadL(2, entriesPtr);
       
   405 
       
   406 	// Give it to scheduler along with schedule id
       
   407 	iTaskScheduler->EditScheduleL(iClientMessage->GetIntL(1), *entries);
       
   408 	CleanupStack::PopAndDestroy(entries);
       
   409 	}
       
   410 
       
   411 void CSchSession::EditConditionScheduleL()
       
   412 	{
       
   413 	CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(1));
       
   414 	
       
   415 	CheckPersistsInBackupL(*schedule);
       
   416 	//check that user has permission to edit this schedule.
       
   417 	schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   418 	
       
   419 	//check that this is a condition schedule!
       
   420 	if(schedule->Type() != EConditionSchedule)
       
   421 		User::Leave(KErrArgument);
       
   422 
       
   423 	// Get entry count
       
   424 	const TInt count = iClientMessage->GetIntL(0);
       
   425 	
       
   426 	//Verify that the length of the condition list passed in is as expected
       
   427 	if(iClientMessage->GetDesLengthL(2) != (count * sizeof(TTaskSchedulerCondition)))
       
   428 		{
       
   429 		User::Leave(KErrBadDescriptor);
       
   430 		}
       
   431 
       
   432 	// Get new entry list
       
   433 	CArrayFixFlat<TTaskSchedulerCondition>* entries 
       
   434 		= new(ELeave) CArrayFixFlat<TTaskSchedulerCondition> (KSchedulerArrayGranularity);	
       
   435 	CleanupStack::PushL(entries);
       
   436 	entries->ResizeL(count);
       
   437 	TPtr8 entriesPtr(REINTERPRET_CAST(TUint8*, &(entries->At(0))), count*sizeof(TTaskSchedulerCondition));
       
   438 	iClientMessage->ReadL(2, entriesPtr);
       
   439 
       
   440 	// get time
       
   441 	TTsTime defaultRunTime;
       
   442 	TPckg<TTsTime> pTime(defaultRunTime);
       
   443 	iClientMessage->ReadL(3, pTime);
       
   444 
       
   445 	// Give it to scheduler along with schedule id
       
   446 	iTaskScheduler->EditScheduleL(iClientMessage->GetIntL(1), *entries, defaultRunTime);
       
   447 	CleanupStack::PopAndDestroy(entries);
       
   448 	}
       
   449 
       
   450 void CSchSession::ScheduleTaskL()
       
   451 	{
       
   452 	// If client is registered, it is allowed to schedule tasks
       
   453 	if(iClient != NULL)
       
   454 		{
       
   455 		TTaskInfo taskInfo;
       
   456 		TPTaskInfo pI(taskInfo);
       
   457 		iClientMessage->ReadL(0, pI);
       
   458 
       
   459 		CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(1));
       
   460 	
       
   461 		CheckPersistsInBackupL(*schedule);
       
   462 
       
   463 		//check that user has permission to schedule a task using this schedule.
       
   464 		schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   465 	
       
   466 		taskInfo.iTaskId = schedule->GenerateTaskId();
       
   467 
       
   468 		if (taskInfo.iTaskId == KErrOverflow)
       
   469 			{
       
   470 			User::Leave(KErrOverflow);
       
   471 			}
       
   472 		// panic client if this is a condition schedule and client is asking for 
       
   473 		// repeats.  This doesnt make sense.	
       
   474 		if (schedule->Type() == EConditionSchedule && taskInfo.iRepeat != 0)
       
   475 			User::Leave(KErrArgument); 
       
   476 
       
   477 		// Create a new scheduled task with associated task data
       
   478 		TInt len = iClientMessage->GetDesLengthL(3);
       
   479 		HBufC* taskdata = HBufC::NewLC(len);
       
   480 
       
   481 		TPtr pData(taskdata->Des());
       
   482 		iClientMessage->ReadL(3, pData);	
       
   483 	
       
   484 		CScheduledTask* newTask = new(ELeave) CScheduledTask(taskInfo, 
       
   485 											taskdata, 
       
   486 											schedule->Type(), 
       
   487 											schedule->SecurityInfo());
       
   488 		CleanupStack::Pop(taskdata); //taskdata now owned by newTask
       
   489 		CleanupStack::PushL(newTask);
       
   490 		// Have to store the associated task, so that in the case where the
       
   491 		// tasks need to be restored from a backup, we can ensure that the
       
   492 		// task is associated with the correct schedule.
       
   493 		newTask->SetScheduleId(schedule->Id());
       
   494 
       
   495 		//If the schedule that the task is associated with is persistent then set the flag
       
   496 		if(schedule->Persists())
       
   497 			{
       
   498 			newTask->SetPersists();
       
   499 			}
       
   500 		LOGSTRING("CSchSession::ScheduleTaskL - writing back task id to client");
       
   501 		TPInt id(taskInfo.iTaskId);
       
   502 		iClientMessage->WriteL(2,id);
       
   503 	
       
   504 		TScheduledTask* task = new(ELeave) TScheduledTask(*newTask,*iClient);
       
   505 	
       
   506 		// Now that task has been created sucessfully, we can add newTask to Client
       
   507 		iClient->AddTask(*newTask); // task info is owned by client: schedule just keeps a reference
       
   508 		CleanupStack::Pop(newTask);
       
   509 
       
   510 		schedule->AddTask(*task);	//add new task - its now owned by schedule
       
   511 
       
   512 		LOGSTRING("CSchSession::ScheduleTaskL - scheduling task with task scheduler");
       
   513 		// If this leaves we need to still remove task from client and schedule. 
       
   514 		// No easy way to do this via CleanupStack
       
   515 		TRAPD(err, iTaskScheduler->ScheduleTaskL(*schedule, *iClient));
       
   516 		if(err)
       
   517 			{
       
   518 			schedule->RemoveTask(task);
       
   519 			iClient->RemoveTask(newTask);
       
   520 			User::Leave(err);	
       
   521 			}
       
   522 		}
       
   523 	else
       
   524 		//Client hasnt been registered so it isn't allowed to schedule task, panic client
       
   525 		{
       
   526 		iClientMessage->PanicClient(KSchedulerPanic,EPanicNotRegistered);
       
   527 		}
       
   528 	}
       
   529 
       
   530 void CSchSession::DeleteTaskL()
       
   531 	{
       
   532 	const TInt taskId = iClientMessage->GetIntL(0);
       
   533 	
       
   534 	const TInt scheduleId = (taskId/KScheduleIdDifferential)*KScheduleIdDifferential;
       
   535 
       
   536 	//check that user has permission to delete a task using this schedule.
       
   537 	CSchedule* schedule = iTaskScheduler->FindL(scheduleId);
       
   538 	CheckPersistsInBackupL(*schedule);
       
   539 	schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   540 	
       
   541 	iTaskScheduler->DeleteTaskL(scheduleId, taskId);
       
   542 	}
       
   543 
       
   544 //retrieval functions
       
   545 void CSchSession::CountSchedulesL()
       
   546 	{
       
   547 	TScheduleFilter filter = STATIC_CAST(TScheduleFilter, iClientMessage->GetIntL(1));
       
   548 	//GetScheduleRefs filters on clients schedule permssion as well.
       
   549 	TInt count = iTaskScheduler->GetScheduleRefsL(NULL,filter, iClientMessage->Message());
       
   550 	TPInt pCount(count);
       
   551 	iClientMessage->WriteL(0,pCount);
       
   552 	}
       
   553 
       
   554 void CSchSession::GetScheduleRefsL()
       
   555 	{
       
   556 	//client calls CountSchedules() first to get expected count. still 
       
   557 	//need to check it's valid though...
       
   558 	
       
   559 	const TInt expectedCount = iClientMessage->GetIntL(0);
       
   560 	TScheduleFilter filter = STATIC_CAST(TScheduleFilter, iClientMessage->GetIntL(1));
       
   561 
       
   562 	CArrayFixFlat<TSchedulerItemRef>* refArray 
       
   563 		= new(ELeave) CArrayFixFlat<TSchedulerItemRef>(KSchedulerArrayGranularity);
       
   564 	CleanupStack::PushL(refArray);
       
   565 	
       
   566 	//GetScheduleRefs filters on clients schedule permssion as well.
       
   567 	TInt count = iTaskScheduler->GetScheduleRefsL(refArray, filter, iClientMessage->Message());
       
   568 	if	((expectedCount<count) || (count == 0))
       
   569 		User::Leave(KErrArgument);
       
   570 
       
   571 	TPtrC8 pS(REINTERPRET_CAST(TUint8*, &refArray->At(0)),sizeof(TSchedulerItemRef)*expectedCount);
       
   572 	iClientMessage->WriteL(2, pS);
       
   573 	CleanupStack::PopAndDestroy();//info array
       
   574 	}
       
   575 
       
   576 void CSchSession::GetTimeScheduleDataL()
       
   577 	{
       
   578 	//client input:handle at info at aMessage.Int0()
       
   579 	//info at aMessage.Ptr1()
       
   580 	//info contains: exepcted entry count
       
   581 	//scheduler output: entries at aM.Ptr2()
       
   582 	TInt handle = iClientMessage->GetIntL(0);
       
   583 
       
   584 	TScheduleInfo info;
       
   585 	TPScheduleInfo pS(info);
       
   586 	iClientMessage->ReadL(1, pS);
       
   587 
       
   588 	CSchedule* schedule = iTaskScheduler->FindL(handle);
       
   589 
       
   590 	//check that user has permission to get this schedules info.
       
   591 	schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   592 	
       
   593 	if (schedule->Type() != ETimeSchedule)
       
   594 		User::Leave(KErrArgument); //calling wrong API
       
   595 
       
   596 	CArrayFixFlat<TScheduleEntryInfo2>* entries 
       
   597 		= new(ELeave) CArrayFixFlat<TScheduleEntryInfo2> (KSchedulerArrayGranularity);
       
   598 	CleanupStack::PushL(entries);
       
   599 	schedule->EntriesL(*entries);
       
   600 	if ((entries->Count())!=info.iEntryCount)
       
   601 		User::Leave(KErrArgument);
       
   602 	//write entries
       
   603 	TPtrC8 pE(REINTERPRET_CAST(TUint8*, &entries->At(0)),sizeof(TScheduleEntryInfo2)*info.iEntryCount);
       
   604 	iClientMessage->WriteL(2, pE);	
       
   605 
       
   606 	CleanupStack::PopAndDestroy(entries);//entry array
       
   607 	}
       
   608 
       
   609 void CSchSession::GetConditionScheduleDataL()
       
   610 	{
       
   611 	//client input:handle at info at aMessage.Int0()
       
   612 	//info at aMessage.Ptr1()
       
   613 	//info contains: exepcted entry count
       
   614 	//scheduler output: entries at aM.Ptr2()
       
   615 	TInt handle = iClientMessage->GetIntL(0);
       
   616 
       
   617 	TScheduleInfo info;
       
   618 	TPScheduleInfo pS(info);
       
   619 	iClientMessage->ReadL(1, pS);
       
   620 
       
   621 	CSchedule* schedule = iTaskScheduler->FindL(handle);
       
   622 	
       
   623 	//check that user has permission to get this schedules info.
       
   624 	schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   625 	
       
   626 	if (schedule->Type() != EConditionSchedule)
       
   627 		User::Leave(KErrArgument); //calling wrong API
       
   628 
       
   629 	CArrayFixFlat<TTaskSchedulerCondition>* conditions 
       
   630 		= new(ELeave) CArrayFixFlat<TTaskSchedulerCondition> (KSchedulerArrayGranularity);
       
   631 	CleanupStack::PushL(conditions);
       
   632 	schedule->ConditionsL(*conditions);
       
   633 	if ((conditions->Count())!=info.iEntryCount)
       
   634 		User::Leave(KErrArgument);
       
   635 	//write entries
       
   636 	TPtrC8 pE(REINTERPRET_CAST(TUint8*, &conditions->At(0)),sizeof(TTaskSchedulerCondition)*info.iEntryCount);
       
   637 	iClientMessage->WriteL(2, pE);	
       
   638 
       
   639 	//write time
       
   640 	TTsTime defaultTime(schedule->DefaultRunTimeL());
       
   641 	TPBTime pDefaultTime(defaultTime);
       
   642 	iClientMessage->WriteL(3, pDefaultTime);
       
   643 
       
   644 	CleanupStack::PopAndDestroy(conditions);//condition array
       
   645 	}
       
   646 
       
   647 void CSchSession::GetScheduleTypeL()
       
   648 	{
       
   649 	TScheduleType type;
       
   650 	TInt handle = iClientMessage->GetIntL(0);
       
   651 	CSchedule* schedule = iTaskScheduler->FindL(handle);
       
   652 	
       
   653 	//check that user has permission to get this schedules info.
       
   654 	schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   655 	
       
   656 	type = schedule->Type();	
       
   657 	TPInt pType(type);
       
   658 	iClientMessage->WriteL(1,pType);
       
   659 	}
       
   660 	
       
   661 void CSchSession::GetTaskDataL()
       
   662 	{//client input:handle at info at aMessage.Int0()
       
   663 	//info at aMessage.Ptr1()
       
   664 	//info contains: exepcted entry count, expected task count
       
   665 	//scheduler output: tasks at aM.Ptr2()
       
   666 	TInt handle = iClientMessage->GetIntL(0);
       
   667 
       
   668 	TScheduleInfo info;
       
   669 	TPScheduleInfo pS(info);
       
   670 	iClientMessage->ReadL(1, pS);
       
   671 
       
   672 	CSchedule* schedule = iTaskScheduler->FindL(handle);
       
   673 
       
   674 	//check that user has permission to get this task info (based on owning
       
   675 	// schedules info).
       
   676 	schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   677 	
       
   678 	CArrayFixFlat<TTaskInfo>* tasks 
       
   679 		= new(ELeave) CArrayFixFlat<TTaskInfo> (KSchedulerArrayGranularity);
       
   680 	CleanupStack::PushL(tasks);
       
   681 	schedule->TasksL(*tasks);
       
   682 	if ((tasks->Count())!=info.iTaskCount)
       
   683 		User::Leave(KErrArgument);
       
   684 	//write tasks if there are any
       
   685 	if (info.iTaskCount>0)
       
   686 		{
       
   687 		TPtrC8 pT(REINTERPRET_CAST(TUint8*, &tasks->At(0)),sizeof(TTaskInfo)*info.iTaskCount);
       
   688 		iClientMessage->WriteL(2, pT);	
       
   689 		}
       
   690 	CleanupStack::PopAndDestroy(tasks);//task array
       
   691 	}
       
   692 
       
   693 void CSchSession::GetScheduleInfoL()
       
   694 	{
       
   695 	CSchedule* schedule = iTaskScheduler->FindL(iClientMessage->GetIntL(0));
       
   696 	
       
   697 	//check that user has permission to get this schedules info.
       
   698 	schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   699 	
       
   700 	TScheduleInfo info;
       
   701 	if (schedule->Type() == ETimeSchedule)
       
   702 		schedule->GetInfo(info, EFalse);
       
   703 	else
       
   704 		schedule->GetInfo(info, ETrue);
       
   705 		
       
   706 	TPBScheduleInfo pInfo(info);
       
   707 	iClientMessage->WriteL(1, pInfo);
       
   708 	TTsTime dueTime(schedule->DueTime());
       
   709 	TPBTime pDueTime(dueTime);
       
   710 	iClientMessage->WriteL(2, pDueTime);
       
   711 	}
       
   712 
       
   713 void CSchSession::GetTaskRefsL()
       
   714 	{
       
   715 	//taskrefs for all, 
       
   716 	//or just the ones I scheduled, 
       
   717 	//or just the pending ones, 
       
   718 	//or just the pending ones I scheduled
       
   719 	
       
   720 	TInt expectedCount = iClientMessage->GetIntL(0);
       
   721 	TScheduleFilter sFilter = STATIC_CAST(TScheduleFilter, iClientMessage->GetIntL(1));
       
   722 	TTaskFilter tFilter = STATIC_CAST(TTaskFilter, iClientMessage->GetIntL(2));
       
   723 	CArrayFixFlat<TSchedulerItemRef>* refs 
       
   724 		= new (ELeave) CArrayFixFlat<TSchedulerItemRef> (KSchedulerArrayGranularity);
       
   725 	CleanupStack::PushL(refs);
       
   726 	
       
   727 	//GetTaskRefs filters on clients schedule permssion as well.
       
   728 	TInt actualCount = iTaskScheduler->GetTaskRefsL(refs, sFilter, tFilter,iClient, iClientMessage->Message());
       
   729 	
       
   730 	// Must find enough tasks.
       
   731 	if((actualCount != expectedCount) || (refs->Count() == 0))
       
   732 		User::Leave(KErrArgument);
       
   733 	
       
   734 	// Write array back to client
       
   735 	TPtrC8 pR(REINTERPRET_CAST(TUint8*,&refs->At(0)),sizeof(TSchedulerItemRef)*expectedCount);
       
   736 	iClientMessage->WriteL(3, pR);
       
   737 	CleanupStack::PopAndDestroy();//refs
       
   738 	}
       
   739 
       
   740 void CSchSession::CountTasksL()
       
   741 	{
       
   742 	//count either all of 'em or just mine
       
   743 	
       
   744 	TScheduleFilter sFilter = STATIC_CAST(TScheduleFilter, iClientMessage->GetIntL(1));
       
   745 	TTaskFilter tFilter = STATIC_CAST(TTaskFilter, iClientMessage->GetIntL(2));
       
   746 
       
   747 	//GetTaskRefs filters on clients schedule permssion as well.
       
   748 	TInt count = iTaskScheduler->GetTaskRefsL(NULL, sFilter, tFilter,iClient, iClientMessage->Message());
       
   749 
       
   750 	TPInt pCount(count);
       
   751 	iClientMessage->WriteL(0,pCount);
       
   752 	}
       
   753 
       
   754 void CSchSession::GetTaskInfoL()
       
   755 	{
       
   756 	// Get task
       
   757 	TInt taskId				= iClientMessage->GetIntL(0);
       
   758 	TInt scheduleId			= (taskId/KScheduleIdDifferential)*KScheduleIdDifferential;
       
   759 	CSchedule* schedule		= iTaskScheduler->FindL(scheduleId);
       
   760 	
       
   761 	//check that user has permission to get this task info (based on owning 
       
   762 	//schedules info).
       
   763 	schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   764 	
       
   765 	TScheduledTask* task = schedule->Task(taskId);
       
   766 	if	(!task)
       
   767 		User::Leave(KErrNotFound);
       
   768 
       
   769 	TPBTaskInfo pI(task->Info());
       
   770 
       
   771 	iClientMessage->WriteL(1, pI);//write info	
       
   772 	
       
   773 	// If there isn't enough room to hold the task data in the client buffer then
       
   774 	// indicate by returning KErrArgument
       
   775 	TInt clientBufferSize = iClientMessage->GetIntL(2);
       
   776 	if	(clientBufferSize < task->Data().Length())
       
   777 		User::Leave(KErrArgument);
       
   778 	iClientMessage->WriteL(3, task->Data());
       
   779 	}
       
   780 
       
   781 void CSchSession::GetScheduleItemRefAndDueTimeL()
       
   782 	{
       
   783 	// Get CSchedule object
       
   784 	TInt taskId = iClientMessage->GetIntL(0);
       
   785 	TInt scheduleId = (taskId/KScheduleIdDifferential)*KScheduleIdDifferential;
       
   786 	CSchedule* schedule = iTaskScheduler->FindL(scheduleId);
       
   787 
       
   788 	//check that user has permission to get this schedules info.
       
   789 	schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   790 	
       
   791 	TSchedulerItemRef ref;
       
   792 	ref.iHandle	= schedule->Id();
       
   793 	ref.iName	= schedule->Name();
       
   794 
       
   795 	TPBSchedulerItemRef pRef(ref);
       
   796 	iClientMessage->WriteL(1, pRef);
       
   797 	
       
   798 	TTsTime dueTime(schedule->DueTime());
       
   799 	TPBTime pDueTime(dueTime);
       
   800 	iClientMessage->WriteL(2, pDueTime);
       
   801 	}
       
   802 
       
   803 void CSchSession::GetTaskDataSizeL()
       
   804 	{
       
   805 	TInt taskId = iClientMessage->GetIntL(0);
       
   806 	TInt scheduleId = (taskId/KScheduleIdDifferential)*KScheduleIdDifferential;
       
   807 	CSchedule* schedule = iTaskScheduler->FindL(scheduleId);
       
   808 
       
   809 	//check that user has permission to get this task info (based on owning 
       
   810 	//schedules info).
       
   811 	schedule->CheckAccessAllowedL(iClientMessage->Message());
       
   812 	
       
   813 	TScheduledTask* task = schedule->Task(taskId);
       
   814 	if	(!task)
       
   815 		User::Leave(KErrNotFound);
       
   816 
       
   817 	TInt size = task->Data().Length();
       
   818 	TPInt pSize(size);
       
   819 	iClientMessage->WriteL(1,pSize);
       
   820 	}
       
   821 
       
   822 void  CSchSession::CheckCapabilityL()
       
   823 	{
       
   824 	if( !( iClientMessage->Message().HasCapability(ECapabilityWriteDeviceData)
       
   825 		|| (PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement)==0 ))) // Enforcement off
       
   826 		User::Leave(KErrPermissionDenied);	
       
   827 	}
       
   828 	
       
   829 void CSchSession::CheckPersistsInBackupL(const CSchedule& aSchedule)
       
   830 	{
       
   831 	// backup or restore in progress, so don't allow functions that might write to store	
       
   832 	if ((iTaskScheduler->BUROperationInProgress() != EBUROperationNoActivity) && (aSchedule.Persists()))
       
   833 		{
       
   834 		User::Leave(KErrServerBusy);
       
   835 		}
       
   836 	}
       
   837