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