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