appfw/apparchitecture/apgrfx/APGTASK.CPP
changeset 0 2e3d3ce01487
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // Copyright (c) 1997-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 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    17 #if !defined(__APA_INTERNAL_H__)
       
    18 #include "apainternal.h"
       
    19 #endif
       
    20 #include "apaidpartner.h"
       
    21 #endif //SYMBIAN_ENABLE_SPLIT_HEADERS
       
    22 #include "APGTASK.H"
       
    23 #include "APGWGNAM.H"
       
    24 #include <w32std.h>
       
    25 
       
    26 
       
    27 //
       
    28 // class TApatask
       
    29 //
       
    30 
       
    31 
       
    32 	
       
    33 EXPORT_C TApaTask::TApaTask(RWsSession& aWsSession)
       
    34 	: iWsSession(aWsSession), iWgId(0)
       
    35 /** Constructs an empty task object, taking a reference to a window server session.
       
    36 
       
    37 An object of this type is constructed by an instance of the TApaTaskList class.
       
    38 
       
    39 The object represents a task when it is assigned a task's window group ID.
       
    40 
       
    41 @param aWsSession The window server session.
       
    42 @see TApaTaskList */
       
    43 	{
       
    44 	}
       
    45 
       
    46 EXPORT_C void TApaTask::SetWgId(TInt aWgId)
       
    47 /** Sets this task's window group ID.
       
    48 
       
    49 @param aWgId The ID to be assigned. */
       
    50 	{
       
    51 	iWgId=aWgId;
       
    52 	}
       
    53 
       
    54 EXPORT_C TInt TApaTask::WgId() const
       
    55 /** Gets the ID of this task's window group.
       
    56 
       
    57 @return The window group ID. For an empty task object, this is zero. */
       
    58 	{
       
    59 	return iWgId;
       
    60 	}
       
    61 
       
    62 EXPORT_C TBool TApaTask::Exists() const
       
    63 /** Tests whether this TApaTask object is empty. This object represents the
       
    64 state of the task at the time at which it was constructed and is not subsequently
       
    65 updated. Therefore, this does not indicate that the task itself exists and should not 
       
    66 be used to test whether or not a particular task is running or not.
       
    67 
       
    68 @return True, if the task is not empty; false, otherwise.
       
    69 @see TApaTaskList::FindDoc()
       
    70 @see TApaTaskList::FindApp()
       
    71 @see TApaTaskList::FindByPos() */
       
    72 	{
       
    73 	return(iWgId>0);
       
    74 	}
       
    75 
       
    76 EXPORT_C TThreadId TApaTask::ThreadId() const
       
    77 /** Gets the ID of this task's thread
       
    78 
       
    79 @return The thread ID. */
       
    80 	{
       
    81 	TThreadId threadId;
       
    82 	if (iWsSession.GetWindowGroupClientThreadId(iWgId,threadId)==KErrNotFound)
       
    83 		{
       
    84 		threadId=TThreadId(KNullThreadId);
       
    85 		}
       
    86 	return(threadId);
       
    87 	}
       
    88 
       
    89 EXPORT_C void TApaTask::BringToForeground()
       
    90 /** Brings this task to the foreground.
       
    91 
       
    92 If the task uses the View architecture, then the task's top view is activated. */
       
    93 	{
       
    94 	iWsSession.SetWindowGroupOrdinalPosition(iWgId,0);
       
    95 	SendSystemEvent(EApaSystemEventBroughtToForeground);
       
    96 	}
       
    97 
       
    98 EXPORT_C void TApaTask::SendToBackground()
       
    99 /** Sends this task to the background.
       
   100 
       
   101 The task whose window group is at the next ordinal position is brought up 
       
   102 to the foreground. In addition, the new foreground task's top view is activated, 
       
   103 if it uses the View architecture. */
       
   104 	{
       
   105 	iWsSession.SetWindowGroupOrdinalPosition(iWgId,-1);
       
   106 	}
       
   107 
       
   108 EXPORT_C void TApaTask::EndTask()
       
   109 /** Requests normal closing of this task. 
       
   110 
       
   111 @capability PowerMgmt is required to close system tasks. */
       
   112 	{
       
   113 	RProcess client;
       
   114 	if (client.HasCapability(ECapabilityPowerMgmt))
       
   115 		{
       
   116 		SendSystemEvent(EApaSystemEventSecureShutdown, EEventPowerMgmt);
       
   117 		}
       
   118 	
       
   119 	// Always send the old shutdown message for backward compatibility. Will not shut down system tasks.
       
   120 	SendSystemEvent(EApaSystemEventShutdown); 
       
   121 	}
       
   122 	
       
   123 EXPORT_C void TApaTask::KillTask()
       
   124 /** Kills this task. 
       
   125 @capability PowerMgmt
       
   126 */
       
   127 	{
       
   128 	RThread thread;
       
   129 	TInt err=thread.Open(ThreadId());
       
   130 	if (!err)
       
   131 		{
       
   132 		RProcess process;
       
   133 		thread.Process(process);
       
   134 		process.Terminate(0);
       
   135 		process.Close();
       
   136 		thread.Close();
       
   137 		}
       
   138 	} //lint !e1762 Suppress Member function 'TApaTask::KillTask(void)' could be made const
       
   139 
       
   140 
       
   141 EXPORT_C TInt TApaTask::SwitchOpenFile(const TDesC& aFilename)
       
   142 /** Requests the task to close its existing document, and to open an existing document.
       
   143 
       
   144 An application (task) may handle the request by overriding CEikAppUi::OpenFileL() if required.
       
   145 
       
   146 @param aFilename The name of the document to be opened.
       
   147 @return KErrNone, if the request was successfully sent to the task; otherwise one of the other
       
   148 system-wide error codes. */
       
   149 	{
       
   150 	TInt err=CheckSwitchFile();
       
   151 	if (!err)
       
   152 #if defined(_UNICODE)
       
   153 		{
       
   154 		TPtrC8 messageBuffer((TUint8*) aFilename.Ptr(),aFilename.Length()<<1);
       
   155 		err=SendMessage(KUidApaMessageSwitchOpenFile,messageBuffer);
       
   156 		}
       
   157 #else
       
   158 		err=SendMessage(KUidApaMessageSwitchOpenFile,aFilename);
       
   159 #endif
       
   160 	return err;
       
   161 	}
       
   162 
       
   163 EXPORT_C TInt TApaTask::SwitchCreateFile(const TDesC& aFilename)
       
   164 /** Requests the task to close its existing document, and to create and open a new 
       
   165 document.
       
   166 
       
   167 An application (task) may handle the request by overriding CEikAppUi::CreateFileL() if required.
       
   168 
       
   169 @param aFilename The name of the new document.
       
   170 @return KErrNone, if the request was successfully sent to the task; otherwise one of the other
       
   171 system-wide error codes. */
       
   172 	{
       
   173 	TInt err=CheckSwitchFile();
       
   174 	if (!err)
       
   175 #if defined(_UNICODE)
       
   176 		{
       
   177 		TPtrC8 messageBuffer((TUint8*) aFilename.Ptr(),aFilename.Length()<<1);
       
   178 		err=SendMessage(KUidApaMessageSwitchCreateFile,messageBuffer);
       
   179 		}
       
   180 #else
       
   181 		err=SendMessage(KUidApaMessageSwitchCreateFile,aFilename);
       
   182 #endif
       
   183 	return err;
       
   184 	}
       
   185 
       
   186 TInt TApaTask::CheckSwitchFile() const
       
   187 	//
       
   188 	// private - checks whether the task will respond to a switch files event
       
   189 	//
       
   190 	{
       
   191 	HBufC* buf=HBufC::NewMax(CApaWindowGroupName::EMaxLength);
       
   192 	if (!buf)
       
   193 		return KErrNoMemory;
       
   194 	TInt err=KErrNone;
       
   195 	TPtr des=buf->Des();
       
   196 	err=iWsSession.GetWindowGroupNameFromIdentifier(iWgId, des);
       
   197 	if (!err)
       
   198 		{
       
   199 		CApaWindowGroupName* wgName=CApaWindowGroupName::New(iWsSession, buf); // takes ownership (if it succeeds)
       
   200 		if (!wgName)
       
   201 			{
       
   202 			delete buf;
       
   203 			return KErrNoMemory;
       
   204 			}
       
   205 		if (wgName->IsBusy())
       
   206 			err=KErrNotReady;
       
   207 		if (!(wgName->RespondsToSwitchFilesEvent()))
       
   208 			err=KErrNotSupported;
       
   209 		delete wgName;
       
   210 		}
       
   211 	else
       
   212 		delete buf;
       
   213 	return err;   
       
   214 	}
       
   215 
       
   216 EXPORT_C TInt TApaTask::SendMessage(TUid aUid,const TDesC8& aParams)
       
   217 /** Sends a message to this task's window group.
       
   218 
       
   219 The message is handled by the UI framework, specifically by CEikAppUI::ProcessMessageL(). 
       
   220 
       
   221 
       
   222 @param aUid The UID identifying the message. By default, the UI framework 
       
   223 recognizes only two messages, KUidApaMessageSwitchOpenFileValue and KUidApaMessageSwitchCreateFileValue.
       
   224 @param aParams The message. The format and meaning of the message depends on 
       
   225 the specific type as identified by the UID.
       
   226 @return KErrNone, if successful; otherwise, one of the other system-wide error 
       
   227 codes.
       
   228 @see CEikAppUi::ProcessMessageL()
       
   229 @see TEventCode
       
   230 @see TWsEvent
       
   231 @see RWindowGroup::FetchMessage() */
       
   232 	{
       
   233 	return iWsSession.SendMessageToWindowGroup(iWgId,aUid,aParams);
       
   234 	}
       
   235 
       
   236 EXPORT_C void TApaTask::SendKey(TInt aKeyCode,TInt aModifiers)
       
   237 /** Sends a key event encapsulating the specified character code and specified modifier 
       
   238 keys state to the task's window group.
       
   239 
       
   240 Key events are handled by the UI framework, specifically by CCoeAppui::HandleWsEventL().
       
   241 
       
   242 @capability SwEvent
       
   243 @param aKeyCode The character code.
       
   244 @param aModifiers State of the modifier keys. 
       
   245 @see CCoeAppUi::HandleWsEventL() */
       
   246 	{
       
   247 	TKeyEvent key;
       
   248 	key.iCode=aKeyCode;
       
   249 	key.iModifiers=aModifiers;
       
   250 	key.iRepeats=0;
       
   251 	key.iScanCode=0;
       
   252 	SendKey(key);
       
   253 	}
       
   254 
       
   255 EXPORT_C void TApaTask::SendKey(const TKeyEvent& aKey)
       
   256 /** Sends the specified key event to the task's window group.
       
   257 
       
   258 Key events are handled by the UI framework, specifically by CCoeAppui::HandleWsEventL().
       
   259 
       
   260 @capability SwEvent
       
   261 @param aKey The key event.
       
   262 @see CCoeAppUi::HandleWsEventL()
       
   263 @see TKeyEvent */
       
   264 	{
       
   265 	TWsEvent event;
       
   266 	event.SetType(EEventKey);
       
   267 	*event.Key()=aKey;
       
   268 	event.SetTimeNow();
       
   269 	iWsSession.SendEventToWindowGroup(iWgId,event);
       
   270 	}
       
   271 
       
   272 EXPORT_C void TApaTask::SendSystemEvent(TApaSystemEvent aEvent)
       
   273 /** Sends a system event to this task's window group.
       
   274 
       
   275 Events are handled by the UI framework, specifically by CEikAppUi::HandleSystemEventL().
       
   276 
       
   277 @capability SwEvent
       
   278 @param aEvent The event type.
       
   279 @see CEikAppUi
       
   280 @see CCoeAppUi::HandleSystemEventL()
       
   281 @see TApaSystemEvent */
       
   282 	{
       
   283 	SendSystemEvent(aEvent, EEventUser); 
       
   284 	}
       
   285 
       
   286 void TApaTask::SendSystemEvent(TApaSystemEvent aEvent, TEventCode aType)
       
   287 /** 
       
   288 @internalTechnology
       
   289 */
       
   290 	{
       
   291 	TWsEvent event;
       
   292 	event.SetType(aType);
       
   293 	*(TApaSystemEvent*)(event.EventData())=aEvent;
       
   294 	event.SetTimeNow();
       
   295 	iWsSession.SendEventToWindowGroup(iWgId,event);
       
   296 	}
       
   297 
       
   298 //
       
   299 // class TApaTaskList
       
   300 //
       
   301 
       
   302 
       
   303 	
       
   304 EXPORT_C TApaTaskList::TApaTaskList(RWsSession& aWsSession)
       
   305 	: iWsSession(aWsSession)
       
   306 /** Constructs the task list object, taking a reference to a window server session.
       
   307 
       
   308 @param aWsSession The window server session. */
       
   309 	{
       
   310 	}
       
   311 
       
   312 EXPORT_C TApaTask TApaTaskList::FindApp(const TDesC& aAppName)
       
   313 /** Searches for a task that has the specified caption.
       
   314 
       
   315 The result of the search depends on the number of tasks that have the specified 
       
   316 caption.
       
   317 
       
   318 If there is only one task, then that task is returned.
       
   319 
       
   320 If there is more than one task, then the task returned depends on whether 
       
   321 the first one found is in the foreground:
       
   322 
       
   323 if the first task found is in the foreground, then the task returned by this 
       
   324 function is the one with the highest window group ordinal value, i.e. the 
       
   325 task which is furthest from the foreground.
       
   326 
       
   327 if the first task found is not in the foreground, then that is the task that 
       
   328 is returned.
       
   329 
       
   330 If no matching task is found, then the object returned is an empty task, and 
       
   331 calling TApaTask::Exists() on it returns false.
       
   332 
       
   333 @param aAppName The caption.
       
   334 @return A task having the specified caption, or an empty task. */
       
   335 	{
       
   336 	TApaTask task(iWsSession);
       
   337 	TInt wgId=0;
       
   338 	TInt matchId=0;
       
   339 	TInt fgWgId=FindByPos(0).WgId();
       
   340 	CApaWindowGroupName::FindByCaption(aAppName, iWsSession, wgId);
       
   341 	if (wgId==fgWgId)
       
   342 		{
       
   343 		while (wgId>=0)
       
   344 			{
       
   345 			matchId=wgId;
       
   346 			CApaWindowGroupName::FindByCaption(aAppName, iWsSession, wgId);
       
   347 			}
       
   348 		}
       
   349 	else 
       
   350 		matchId=wgId;
       
   351 	task.SetWgId(matchId);
       
   352 	return(task);
       
   353 	}
       
   354 
       
   355 EXPORT_C TApaTask TApaTaskList::FindDoc(const TDesC& aDocName)
       
   356 /** Searches for the task that is handling the specified document.
       
   357 
       
   358 @param aDocName The name of the document.
       
   359 @return The task that is handling the specified document. If no such task exists, 
       
   360 then this is an empty task, i.e. a subsequent call to TApaTask::Exists() returns 
       
   361 false. */
       
   362 	{
       
   363 	TInt wgId=0;
       
   364 	CApaWindowGroupName::FindByDocName(aDocName, iWsSession, wgId);
       
   365 	TApaTask task(iWsSession);
       
   366 	task.SetWgId(wgId);
       
   367 	return(task);
       
   368 	}
       
   369 
       
   370 EXPORT_C TApaTask TApaTaskList::FindByPos(TInt aPos)
       
   371 /** Searches for a task by the ordinal position of its window group.
       
   372 
       
   373 @param aPos The ordinal position of a task's window group. A zero value refers 
       
   374 to the foreground task.
       
   375 @return The task at the specified position. If there is no task at the specified 
       
   376 position, or the specified position is invalid, then the object returned is 
       
   377 an empty task, and calling TApaTask::Exists() on it returns false. */
       
   378 	{
       
   379 	TApaTask task(iWsSession);
       
   380 	TRAP_IGNORE(FindByPosL(task,aPos));
       
   381 	return(task);
       
   382 	}
       
   383 
       
   384 void TApaTaskList::FindByPosL(TApaTask& aTask,TInt aPos)
       
   385 	{
       
   386 	TInt wgId=0;
       
   387 	const TInt count=iWsSession.NumWindowGroups(0);
       
   388 	if (count)
       
   389 		{
       
   390 		CArrayFixFlat<TInt>* wgIdArray=new(ELeave) CArrayFixFlat<TInt>(count);
       
   391 		CleanupStack::PushL(wgIdArray);
       
   392 		CApaWindowGroupName* wgName=CApaWindowGroupName::NewL(iWsSession);
       
   393 		CleanupStack::PushL(wgName);
       
   394 		User::LeaveIfError(iWsSession.WindowGroupList(0,wgIdArray)); // priority 0 == mostly normal apps but some may be hidden window groups
       
   395 
       
   396 		for (TInt ii=0; ii<wgIdArray->Count(); ii++) // must ask for count each time as this may change
       
   397 			{ 
       
   398 			wgId=(*wgIdArray)[ii];
       
   399 			wgName->ConstructFromWgIdL(wgId);
       
   400 			if(wgName->Hidden())
       
   401 				{
       
   402 				wgIdArray->Delete(ii--); // array element removed so now need to do this index again
       
   403 				}
       
   404 			}
       
   405 		
       
   406 		if (aPos>=count || aPos<0)
       
   407 			aPos=count-1;
       
   408 
       
   409 		if(aPos<wgIdArray->Count())
       
   410 			wgId=(*wgIdArray)[aPos];
       
   411 
       
   412 		CleanupStack::PopAndDestroy(2);	// wgIdArray, wgName
       
   413 		}
       
   414 	aTask.SetWgId(wgId);
       
   415 	}
       
   416 
       
   417 
       
   418 EXPORT_C TApaTask TApaTaskList::FindApp(TUid aAppUid)
       
   419 /** Searches for a task running the specified application.
       
   420 
       
   421 The result of the search depends on the number of tasks that are running the 
       
   422 specified application.
       
   423 
       
   424 If there is only one task, then that task is returned.
       
   425 
       
   426 If there is more than one task, then the task returned depends on whether 
       
   427 the first one found is in the foreground:
       
   428 
       
   429 if the first task found is in the foreground, then the task returned by this 
       
   430 function is the one with the highest window group ordinal value, i.e. the 
       
   431 task which is furthest from the foreground.
       
   432 
       
   433 if the first task found is not in the foreground, then that is the task that 
       
   434 is returned.
       
   435 
       
   436 If no matching task is found, then the object returned is an empty task, and 
       
   437 calling TApaTask::Exists() on it returns false.
       
   438 
       
   439 @param aAppUid The application specific UID.
       
   440 @return A task having the specified caption, or an empty task. */
       
   441 	{
       
   442 	TApaTask task(iWsSession);
       
   443 	TInt wgId=0;
       
   444 	TInt matchId=0;
       
   445 	TInt fgWgId=FindByPos(0).WgId();
       
   446 	CApaWindowGroupName::FindByAppUid(aAppUid,iWsSession,wgId);
       
   447 	if (wgId==fgWgId)
       
   448 		{
       
   449 		while (wgId>=0)
       
   450 			{
       
   451 			matchId=wgId;
       
   452 			CApaWindowGroupName::FindByAppUid(aAppUid,iWsSession,wgId);
       
   453 			}
       
   454 		}
       
   455 	else 
       
   456 		matchId=wgId;
       
   457 	task.SetWgId(matchId);
       
   458 	return task;
       
   459 	}
       
   460 
       
   461 EXPORT_C TInt TApaTaskList::CycleTasks(TUid aAppUid,TCycleDirection aDirection)
       
   462 /** Brings the next task in the set of tasks running the specified application to 
       
   463 the foreground.
       
   464 
       
   465 If there is only one task, then no change occurs.
       
   466 
       
   467 If the foremost task in the set is not the foreground task, then this is made 
       
   468 the foreground task.
       
   469 
       
   470 Thereafter, successive calls to this function bring the next task in the set 
       
   471 to the foreground. The direction of the cycling can be specified and has the 
       
   472 following effect:
       
   473 
       
   474 for the forwards direction, the foreground task is sent to the background; 
       
   475 the next foremost task is made the foreground task.
       
   476 
       
   477 for the backwards direction, the task with the highest window group ordinal 
       
   478 value, i.e. the task in the set which is furthest from the foreground, is 
       
   479 brought to the foreground. The task that was the foremost task in the set 
       
   480 is moved back by one position.
       
   481 
       
   482 If the task brought to the foreground uses the View architecture, then the 
       
   483 its top view is activated.
       
   484 
       
   485 @param aAppUid The application specific UID. 
       
   486 @param aDirection The direction of cycling.
       
   487 @return KErrNone, if successful; KErrNotFound, if there are no tasks running 
       
   488 the specified application. */
       
   489 	{
       
   490 	TInt sendToBgWgId=KErrNotFound;
       
   491 	TInt wgId=0;
       
   492 	TInt fgWgId=FindByPos(0).WgId();
       
   493 	CApaWindowGroupName::FindByAppUid(aAppUid,iWsSession,wgId);
       
   494 	TInt matchId=wgId;
       
   495 	if (wgId==fgWgId)											// If first match is at foreground
       
   496 		{
       
   497 		if (aDirection==EBackwards)
       
   498 			{
       
   499 			while (wgId>=0)										// Go for last match
       
   500 				{
       
   501 				matchId=wgId;
       
   502 				CApaWindowGroupName::FindByAppUid(aAppUid,iWsSession,wgId);
       
   503 				}
       
   504 			}
       
   505 		else
       
   506 			{
       
   507 			CApaWindowGroupName::FindByAppUid(aAppUid,iWsSession,wgId);
       
   508 			if (wgId<0)											// If no other match
       
   509 				return KErrNone;
       
   510 			sendToBgWgId=matchId;
       
   511 			matchId=wgId;										// Go for second match
       
   512 			}
       
   513 		}
       
   514 	if (matchId>=0)
       
   515 		{
       
   516 		iWsSession.SetWindowGroupOrdinalPosition(matchId,0);
       
   517 		if (sendToBgWgId>=0)
       
   518 			iWsSession.SetWindowGroupOrdinalPosition(sendToBgWgId,-1);	// Send it to background
       
   519 		return KErrNone;
       
   520 		}
       
   521 	return KErrNotFound;
       
   522 	}
       
   523