kernel/eka/ewsrv/ws_main.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1995-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 "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 // e32\ewsrv\ws_main.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "ws_std.h"
       
    19 #include <e32hal.h>
       
    20 #include <hal.h>
       
    21 #include <e32math.h>
       
    22 #include <domainmanager.h>
       
    23 #ifdef __WINS__
       
    24 #include <e32wins.h>
       
    25 #endif
       
    26 
       
    27 GLREF_D CKeyTranslator *KeyTranslator;
       
    28 GLREF_D CKeyRepeat* KeyRepeat;
       
    29 
       
    30 // password notifier support functions
       
    31 LOCAL_C void RenderPassword(RConsole *aCon, TInt aPWLeft, const TDesC& aPW);
       
    32 
       
    33 _LIT(KShellProcessName, "ESHELL");
       
    34 _LIT(KShellCommandLine, "/p");
       
    35 
       
    36 //
       
    37 // class CKeyRepeat
       
    38 //
       
    39 
       
    40 CKeyRepeat::CKeyRepeat(TInt aPriority) : CTimer(aPriority)
       
    41 //
       
    42 // Constructor. Set default repeat delay and rate
       
    43 //
       
    44     {
       
    45     iDelay=EDefaultKeyRepeatDelay;
       
    46     iRate=EDefaultKeyRepeatRate;
       
    47     }
       
    48 
       
    49 void CKeyRepeat::ConstructL()
       
    50     {
       
    51 
       
    52     CTimer::ConstructL();
       
    53     CActiveScheduler::Add(this);
       
    54     }
       
    55 
       
    56 void CKeyRepeat::RunL()
       
    57 //
       
    58 // Send a repeat keypress to the window
       
    59 //
       
    60     {
       
    61 
       
    62     After(iRate);
       
    63 	CWsWindow::KeyPress(iKeyData);
       
    64     }
       
    65 
       
    66 void CKeyRepeat::Request(TKeyData& aKeyData)
       
    67 //
       
    68 // Request a repeat event
       
    69 //
       
    70     {
       
    71 
       
    72     iKeyData=aKeyData;
       
    73 	Cancel();
       
    74     After(iDelay);
       
    75     }
       
    76 
       
    77 void CKeyRepeat::SetRepeatTime(TInt aDelay,TInt aRate)
       
    78     {
       
    79 
       
    80     iDelay=aDelay;
       
    81     iRate=aRate;
       
    82     }
       
    83 
       
    84 void CKeyRepeat::RepeatTime(TInt& aDelay,TInt& aRate)
       
    85     {
       
    86 
       
    87     aDelay=iDelay;
       
    88     aRate=iRate;
       
    89     }
       
    90 
       
    91 //
       
    92 // class CWsSession
       
    93 //
       
    94 
       
    95 CWsSession::CWsSession()
       
    96 	{
       
    97 	iTestFast = (UserSvr::DebugMask(2)&0x00000002) ? 1 : 0;
       
    98 	}
       
    99 
       
   100 CWsSession::~CWsSession()
       
   101 //
       
   102 // Destructor
       
   103 //
       
   104 	{
       
   105 
       
   106 	delete iWindow;
       
   107 	}
       
   108 
       
   109 //
       
   110 // class CWsServer
       
   111 //
       
   112 
       
   113 void CWsServer::New()
       
   114 //
       
   115 // Create a new CWsServer.
       
   116 //
       
   117 	{
       
   118 
       
   119 	CWsServer *pS=new CWsServer(EPriority);
       
   120 	__ASSERT_ALWAYS(pS!=NULL,Fault(ECreateServer));
       
   121 	pS->SetPinClientDescriptors(EFalse); // don't pin because client interface can't cope with errors if pin fails under real or simulated OOM
       
   122 	TInt r=pS->Start(KE32WindowServer);
       
   123 	__ASSERT_ALWAYS(r==KErrNone,Fault(EStartServer));
       
   124 	RProcess::Rendezvous(KErrNone);
       
   125 
       
   126 	}
       
   127 
       
   128 CWsServer::CWsServer(TInt aPriority)
       
   129 //
       
   130 // Constructor.
       
   131 //
       
   132 	: CServer2(aPriority)
       
   133 	{
       
   134 	}
       
   135 
       
   136 CSession2* CWsServer::NewSessionL(const TVersion& aVersion,const RMessage2&) const
       
   137 //
       
   138 // Create a new client for this server.
       
   139 //
       
   140 	{
       
   141 
       
   142 	TVersion v(KW32MajorVersionNumber,KW32MinorVersionNumber,KE32BuildVersionNumber);
       
   143 	TBool r=User::QueryVersionSupported(v,aVersion);
       
   144 	if (!r)
       
   145 		User::Leave(KErrNotSupported);
       
   146 	return new(ELeave) CWsSession;
       
   147 	}
       
   148 
       
   149 void CWsSession::ServiceL(const RMessage2& aMessage)
       
   150 //									    
       
   151 // Handle messages for this session.
       
   152 //
       
   153 	{
       
   154 
       
   155 	iCurMsg = aMessage;
       
   156 	CWsWindow::WaitOnService();
       
   157 	CWsWindow* pW=iWindow;
       
   158 	TInt r=EPrematureOperation;
       
   159 	TBool delayCompletion=EFalse;
       
   160 	switch (aMessage.Function())
       
   161 		{
       
   162 	case EConsoleCreate:
       
   163 		{
       
   164 		if (pW)
       
   165 			{
       
   166 			delete pW;
       
   167 			iWindow=NULL;
       
   168 			}
       
   169 		pW=new CWsWindow;
       
   170 		if (!pW)
       
   171 			{ 
       
   172 			r=EWindowOutOfMemory;
       
   173 			break;
       
   174 			}
       
   175 		iWindow=pW;
       
   176 		pW->iAllowResize=ETrue;
       
   177 		pW->iIsVisible=ETrue;
       
   178 		pW->iOnTop=EFalse;
       
   179 		pW->SetCursorHeight(50);
       
   180 		pW->iKQueue.SetOffset(_FOFF(SWsKey,iLink));
       
   181 		break;
       
   182 		}
       
   183 	case EConsoleSet:
       
   184 		{
       
   185 		if (!pW)
       
   186 			{
       
   187 			pW=new(ELeave) CWsWindow;
       
   188 			iWindow=pW;
       
   189 			pW->iAllowResize=ETrue;
       
   190 			pW->iIsVisible=ETrue;
       
   191 			pW->iOnTop=EFalse;
       
   192 			pW->SetCursorHeight(50);
       
   193 			pW->iKQueue.SetOffset(_FOFF(SWsKey,iLink));
       
   194 			}
       
   195 		pW->iAllowSlide=ETrue;
       
   196 		TFileName name;
       
   197 		iCurMsg.ReadL(0, name);
       
   198 		pW->iTitle=name;
       
   199 		TPckgBuf<TSize> size;
       
   200 		iCurMsg.ReadL(1, size);
       
   201 		TRAP(r,pW->CreateL(size()));
       
   202 		if (r != KErrNone)
       
   203 			{
       
   204 			delete pW;
       
   205 			iWindow=NULL;			
       
   206 			}
       
   207 		break;
       
   208 		}
       
   209 	case EConsoleClearScreen:
       
   210 		{
       
   211 		if (pW)
       
   212 			{
       
   213 			pW->Clear();
       
   214 			r=KErrNone;
       
   215 			}
       
   216 		break;
       
   217 		}
       
   218 	case EConsoleClearToEndOfLine:
       
   219 		{
       
   220 		if (pW)
       
   221 			{
       
   222 			pW->ClearToEndOfLine();
       
   223 			r=KErrNone;
       
   224 			}
       
   225 		break;
       
   226 		}
       
   227 	case EConsoleSetTitle:
       
   228 		{
       
   229 		if (pW)
       
   230 			{
       
   231 			TFileName name;
       
   232 			iCurMsg.ReadL(0, name);
       
   233 			pW->SetTitle(name);
       
   234 			r=KErrNone;
       
   235 			}
       
   236 		break;
       
   237 		}
       
   238 	case EConsoleSetSize:
       
   239 		{
       
   240 		if (pW)
       
   241 			{
       
   242 			TPckgBuf<TSize> size;
       
   243 			iCurMsg.ReadL(0, size);
       
   244 //			pW->SetSize(size());
       
   245 //			r=KErrNone;
       
   246 			r=KErrNotSupported;
       
   247 			}
       
   248 		break;
       
   249 		}
       
   250 	case EConsoleSetWindowPosAbs:
       
   251 		{
       
   252 		if (pW)
       
   253 			{
       
   254 			TPckgBuf<TPoint> point;
       
   255 			iCurMsg.ReadL(0, point);
       
   256 			pW->SetWindowPosAbs(point());
       
   257 			r=KErrNone;
       
   258 			}
       
   259 		break;
       
   260 		}
       
   261 	case EConsoleSetCursorHeight:
       
   262 		{
       
   263 		if (pW)
       
   264 			{
       
   265 			pW->SetCursorHeight(aMessage.Int0());
       
   266 			r=KErrNone;
       
   267 			}
       
   268 		break;
       
   269 		}
       
   270 	case EConsoleSetCursorPosAbs:
       
   271 		{
       
   272 		if (pW)
       
   273 			{
       
   274 			TPckgBuf<TPoint> point;
       
   275 			iCurMsg.ReadL(0, point);
       
   276 			pW->SetCursorPosAbs(point());
       
   277 			r=KErrNone;
       
   278 			}
       
   279 		break;
       
   280 		}
       
   281 	case EConsoleSetCursorPosRel:
       
   282 		{
       
   283 		if (pW)
       
   284 			{
       
   285 			TPckgBuf<TPoint> point;
       
   286 			iCurMsg.ReadL(0, point);
       
   287 			pW->SetCursorPosRel(point());
       
   288 			r=KErrNone;
       
   289 			}
       
   290 		break;
       
   291 		}
       
   292 	case EConsoleCursorPos:
       
   293 		{
       
   294 		if (pW)
       
   295 			{
       
   296 			TPckgBuf<TPoint> point;
       
   297 			point()=pW->CursorPosition();
       
   298 			aMessage.WriteL(0,point);
       
   299 			r=KErrNone;
       
   300 			}
       
   301 		break;
       
   302 		}
       
   303 	case EConsoleSize:
       
   304 		{
       
   305 		if (pW)
       
   306 			{
       
   307 			TPckgBuf<TSize> size;
       
   308 			size()=pW->Size();
       
   309 			aMessage.WriteL(0,size);
       
   310 			r=KErrNone;
       
   311 			}
       
   312 		break;
       
   313 		}
       
   314 	case EConsoleScreenSize:
       
   315 		{
       
   316 		if (pW)
       
   317 			{
       
   318 			TPckgBuf<TSize> size;
       
   319 			size()=CWsWindow::ScreenSize;
       
   320 			aMessage.WriteL(0,size);
       
   321 			r=KErrNone;
       
   322 			}
       
   323 		break;
       
   324 		}
       
   325 	case EConsoleControl:
       
   326 		{
       
   327 		if (pW)
       
   328 			{
       
   329 			TBool indicator=ETrue;
       
   330 			TInt offset=0;
       
   331 			TBuf<0x100> b;
       
   332 			do
       
   333 				{
       
   334 				iCurMsg.ReadL(0,b,offset);
       
   335 				for (const TText* pB=b.Ptr();pB<b.Ptr()+b.Length();pB++)
       
   336 					{
       
   337 					switch(*pB)
       
   338 						{
       
   339 					case '+':
       
   340 
       
   341 						indicator=ETrue;
       
   342 						break;
       
   343 					case '-':
       
   344 						indicator=EFalse;
       
   345 						break;
       
   346 					case 'S':
       
   347 						pW->ControlScrollBars(indicator);
       
   348 						break;
       
   349 					case 'W':
       
   350 						pW->ControlWrapLock(indicator);
       
   351 						break;
       
   352                     case 'P':
       
   353                         pW->ControlPointerEvents(indicator);
       
   354                         break;
       
   355 					case 'L':
       
   356 						pW->ControlScrollLock(indicator);
       
   357 						break;
       
   358 					case 'V':
       
   359 						pW->ControlVisibility(indicator);
       
   360 						break;
       
   361 					case 'C':
       
   362 						pW->ControlCursorRequired(indicator);
       
   363 						break;
       
   364 					case 'M':
       
   365 						pW->ControlMaximised(indicator);
       
   366 						break;
       
   367 					case 'N':
       
   368 						pW->ControlNewLineMode(indicator);
       
   369 						break;
       
   370                     case 'O':
       
   371 						pW->ControlOnTop(indicator);
       
   372 						break;
       
   373 					case 'I':
       
   374                         pW->ControlInformAllMouse(indicator);
       
   375                         break;
       
   376                     case 'R':
       
   377                         pW->ControlRawEventMode(indicator);
       
   378                         break;
       
   379 					case 'A':
       
   380 						pW->ControlAllowResize(indicator);
       
   381 						}
       
   382 					}
       
   383 				offset+=b.Length();
       
   384 				}
       
   385 			while (b.Length()==b.MaxLength());
       
   386 			r=KErrNone;
       
   387 			}
       
   388 		break;
       
   389 		}
       
   390 	case EConsoleWrite:
       
   391 		{
       
   392 		if (pW)
       
   393 			{
       
   394 			switch(iTestFast)
       
   395 				{
       
   396 			case 0:
       
   397 				{
       
   398 				TInt offset=0;
       
   399 				TBuf<0x100> b;
       
   400 				do
       
   401 					{
       
   402 					iCurMsg.ReadL(0,b,offset);
       
   403 					pW->Write(b);
       
   404 					offset+=b.Length();
       
   405 					}
       
   406 				while (b.Length()==b.MaxLength());
       
   407 				pW->WriteDone();
       
   408 				}
       
   409 				r=KErrNone;
       
   410 				break;
       
   411 
       
   412 			case 1:
       
   413 				{
       
   414 				pW->Write(_L("Output suppressed because TESTFAST mode is set..."));
       
   415 				pW->WriteDone();
       
   416 				++iTestFast;
       
   417 				}
       
   418 				r=KErrNone;
       
   419 				break;
       
   420 
       
   421 			default:
       
   422 				r=KErrNone;
       
   423 				break;
       
   424 				}
       
   425 			}
       
   426 		break;
       
   427 		}
       
   428 	case EConsoleRead:
       
   429 		{
       
   430 		if (pW)
       
   431 			{
       
   432 			if (pW->EnqueReadRequest(aMessage))
       
   433 				{
       
   434 				delayCompletion=ETrue;
       
   435 				r=KErrNone;
       
   436 				}
       
   437 			else
       
   438 				r=EDoubleReadRequest;
       
   439 			}
       
   440 		break;
       
   441 		}
       
   442 	case EConsoleReadCancel:
       
   443 		{
       
   444 		if (pW)
       
   445 			{
       
   446 			pW->DequeReadRequest();
       
   447 			r=KErrNone;
       
   448 			}
       
   449 		break;
       
   450 		}
       
   451 	case EConsoleDestroy:
       
   452 		{
       
   453 		if (pW)
       
   454 			{
       
   455 			delete pW;
       
   456 			iWindow=NULL;
       
   457 			r=KErrNone;
       
   458 			}
       
   459 		break;
       
   460 		}
       
   461 	case EConsoleSetMode:
       
   462 		{
       
   463 		r=CWsWindow::SetMode((TVideoMode)aMessage.Int0());		
       
   464 		break;
       
   465 		}
       
   466 	case EConsoleSetPaletteEntry:
       
   467 		{
       
   468 		CWsWindow::ScreenDriver->SetPaletteEntry((TColorIndex)aMessage.Int0(),(TUint8)aMessage.Int1(),(TUint8)aMessage.Int2(),(TUint8)aMessage.Int3());
       
   469 		pW->Redraw();
       
   470 		r=KErrNone;
       
   471 		break;
       
   472 		}
       
   473 	case EConsoleGetPaletteEntry:
       
   474 		{
       
   475 		TUint8 r,g,b;
       
   476 		TPckgBuf<TUint8> red,green,blue;
       
   477 		CWsWindow::ScreenDriver->GetPaletteEntry((TColorIndex)aMessage.Int0(),r,g,b);
       
   478 		red()=r; green()=g; blue()=b;
       
   479 		aMessage.WriteL(1,red);
       
   480 		aMessage.WriteL(2,green);
       
   481 		aMessage.WriteL(3,blue);
       
   482 		}
       
   483 		r=KErrNone;
       
   484 		break;
       
   485 	case EConsoleSetTextColors:
       
   486 		{
       
   487 		if(pW)
       
   488 			{
       
   489 			pW->iFgColor=(TColorIndex)aMessage.Int0();
       
   490 			pW->iBgColor=(TColorIndex)aMessage.Int1();
       
   491 			}		
       
   492 		r=KErrNone;
       
   493 		break;
       
   494 		}
       
   495 	case EConsoleSetUIColors:
       
   496 		{
       
   497 		CWsWindow::WindowBgColor=(TColorIndex)aMessage.Int0();
       
   498 		CWsWindow::BorderColor=(TColorIndex)aMessage.Int1();
       
   499 		CWsWindow::ScreenColor=(TColorIndex)aMessage.Int2();
       
   500 		CWsWindow::ChangeUIColors();
       
   501 		r=KErrNone;
       
   502 		break;
       
   503 		}
       
   504 	case EConsoleSetTextAttribute:
       
   505 		{
       
   506 		if(pW)
       
   507 			pW->SetTextAttribute((TTextAttribute)aMessage.Int0());		
       
   508 		r=KErrNone;
       
   509 		break;
       
   510 		}
       
   511 	default:
       
   512 		r=KErrNotSupported;
       
   513 		}
       
   514 	if (!delayCompletion)
       
   515 		aMessage.Complete(r);
       
   516 	CWsWindow::SignalService();
       
   517 	}
       
   518 
       
   519 void CWsSession::ServiceError(const RMessage2& aMessage,TInt aError)
       
   520 	{
       
   521 	if (!aMessage.IsNull())
       
   522 		{
       
   523 		if (aError>0)
       
   524 			{
       
   525 			aMessage.Panic(_L("WServ panic"),aError);
       
   526 			}
       
   527 		else
       
   528 			{
       
   529 			aMessage.Complete(aError);
       
   530 			}
       
   531 		}
       
   532 	}
       
   533 
       
   534 CWsServer::~CWsServer()
       
   535 //
       
   536 // Destructor
       
   537 //
       
   538 	{
       
   539 	}
       
   540 
       
   541 //
       
   542 // class CEvent
       
   543 //
       
   544 
       
   545 void CEvent::New()
       
   546 //
       
   547 // Create the CEvent active object.
       
   548 //
       
   549 	{
       
   550 
       
   551 	CEvent *pE=new CEvent(EPriority);
       
   552 	__ASSERT_ALWAYS(pE!=NULL,Fault(ECreateEvent));
       
   553 	pE->CaptureKeys=new CCaptureKeys();
       
   554 	__ASSERT_ALWAYS(pE->CaptureKeys!=NULL,Fault(ECreateEvent));
       
   555 
       
   556 	pE->CaptureKeys->Construct();
       
   557 
       
   558 	CActiveScheduler::Add(pE);
       
   559 	UserSvr::CaptureEventHook();
       
   560 	pE->Request();
       
   561 	}
       
   562 
       
   563 CEvent::~CEvent()
       
   564 //
       
   565 // Destroy the CEvent active object
       
   566 //
       
   567 	{
       
   568 
       
   569 	Cancel();
       
   570 	}
       
   571 
       
   572 #pragma warning( disable : 4705 )	// statement has no effect
       
   573 CEvent::CEvent(TInt aPriority)
       
   574 //
       
   575 // Constructor
       
   576 //
       
   577 	: CActive(aPriority)
       
   578 	{
       
   579 	}
       
   580 #pragma warning( default : 4705 )
       
   581 
       
   582 void CEvent::Request()
       
   583 //
       
   584 // Issue a request for the next event.
       
   585 //
       
   586 	{
       
   587 
       
   588 	UserSvr::RequestEvent(iEvent,iStatus);
       
   589 	SetActive();
       
   590 	}
       
   591 
       
   592 void CEvent::DoCancel()
       
   593 //
       
   594 // Cancel a pending event.
       
   595 //
       
   596 	{
       
   597 
       
   598 	UserSvr::RequestEventCancel();
       
   599 	}
       
   600 
       
   601 void CEvent::RunL()
       
   602 //
       
   603 // Event has completed.
       
   604 //
       
   605 	{
       
   606 
       
   607     if (CWsWindow::RawEventMode())
       
   608         {
       
   609         KeyRepeat->Cancel();
       
   610         CWsWindow::QueueRawEvent(iEvent.Event());
       
   611         Request();
       
   612         return;
       
   613         }
       
   614 	switch(iEvent.Event().Type())
       
   615 		{
       
   616 	case TRawEvent::ERedraw:
       
   617 		CWsWindow::Redraw();
       
   618 		break;
       
   619 	case TRawEvent::EButton1Down:
       
   620         if(!CWsWindow::MouseIsCaptured)
       
   621             {
       
   622       		CWsWindow::MouseMove(iEvent.Event().Pos());
       
   623   	    	CWsWindow::MouseLeftButton();
       
   624             }
       
   625         else
       
   626             CWsWindow::InformTopMouse(iEvent.Event().Pos());
       
   627 		break;
       
   628 	case TRawEvent::EButton1Up:
       
   629 		if(!CWsWindow::MouseIsCaptured)
       
   630 			{
       
   631 			CWsWindow::MouseMove(iEvent.Event().Pos());
       
   632 			CWsWindow::MouseLeftButtonUp();
       
   633 			}
       
   634 		break;
       
   635 	case TRawEvent::EButton2Down:
       
   636 		break;
       
   637 	case TRawEvent::EButton2Up:
       
   638 		break;
       
   639 	case TRawEvent::EButton3Down:
       
   640 		break;
       
   641 	case TRawEvent::EButton3Up:
       
   642 		break;
       
   643 	case TRawEvent::EPointerMove:
       
   644 		CWsWindow::MouseMove(iEvent.Event().Pos());
       
   645 		break;
       
   646 	case TRawEvent::EInactive:
       
   647         KeyRepeat->Cancel();
       
   648         break;
       
   649     case TRawEvent::EActive:
       
   650         break;
       
   651     case TRawEvent::EUpdateModifiers:
       
   652         KeyTranslator->UpdateModifiers(iEvent.Event().Modifiers());
       
   653         break;
       
   654 	case TRawEvent::EKeyDown:
       
   655 		{
       
   656 		TKeyData keyData;
       
   657 		if (KeyTranslator->TranslateKey(iEvent.Event().ScanCode(), EFalse,*CaptureKeys,keyData))
       
   658 			CWsWindow::KeyPress(keyData);
       
   659 		if (keyData.iModifiers&EModifierAutorepeatable)
       
   660 			KeyRepeat->Request(keyData);
       
   661 		break;
       
   662 		}
       
   663 	case TRawEvent::EKeyUp:
       
   664 		{
       
   665 		TKeyData keyData;
       
   666 		KeyRepeat->Cancel();
       
   667 		if (KeyTranslator->TranslateKey(iEvent.Event().ScanCode(), ETrue,*CaptureKeys,keyData))
       
   668 			CWsWindow::KeyPress(keyData);
       
   669 		break;
       
   670 		}
       
   671 	case TRawEvent::ESwitchOn:
       
   672 	case TRawEvent::ECaseOpen:
       
   673 		HAL::Set(HAL::EDisplayState, 1);
       
   674 			{
       
   675 			RDmDomainManager mgr; 
       
   676 			TInt r = mgr.Connect();
       
   677 			if (r != KErrNone)
       
   678 				User::Panic(_L("EWSRV SwitchOn0"), r);
       
   679 			TRequestStatus status;
       
   680 			mgr.RequestDomainTransition(KDmIdUiApps, EPwActive, status);
       
   681 			User::WaitForRequest(status);
       
   682 			if (status.Int() != KErrNone)
       
   683 				User::Panic(_L("EWSRV SwitchOn1"), status.Int());
       
   684 			mgr.Close();
       
   685 			}
       
   686 		break;
       
   687 	case TRawEvent::EPointerSwitchOn:
       
   688 #if defined(_DEBUG)
       
   689     	User::Beep(440,250000);
       
   690 #endif
       
   691 		break;
       
   692 	case TRawEvent::ESwitchOff:
       
   693 			{
       
   694 			RDmDomainManager mgr; 
       
   695 			TInt r = mgr.Connect();
       
   696 			if (r != KErrNone)
       
   697 				User::Panic(_L("EWSRV SwitchOff0"), r);
       
   698 			TRequestStatus status;
       
   699 			mgr.RequestSystemTransition(EPwStandby, status);
       
   700 			User::WaitForRequest(status);
       
   701 			if (status.Int() != KErrNone)
       
   702 				User::Panic(_L("EWSRV SwitchOff1"), status.Int());
       
   703 			mgr.Close();
       
   704 			}
       
   705 		break;
       
   706 	case TRawEvent::ECaseClose:
       
   707 			{
       
   708 			RDmDomainManager mgr; 
       
   709 			TInt r = mgr.Connect();
       
   710 			if (r != KErrNone)
       
   711 				User::Panic(_L("EWSRV CaseClosed"), r);
       
   712 			TRequestStatus status;
       
   713 			mgr.RequestDomainTransition(KDmIdUiApps, EPwStandby, status);
       
   714 			User::WaitForRequest(status);
       
   715 			if (status.Int() != KErrNone)
       
   716 				User::Panic(_L("EWSRV CaseClosed1"), status.Int());
       
   717 			mgr.Close();
       
   718 			}
       
   719 		HAL::Set(HAL::EDisplayState, 0);
       
   720 		break;
       
   721 	case TRawEvent::ENone:
       
   722 		break;
       
   723 	default:
       
   724 		break;
       
   725 		}                                       
       
   726 	Request();
       
   727 	}
       
   728 
       
   729 LOCAL_C void RenderPassword(RConsole *aCon, TInt aPWLeft, const TDesC& aPW)
       
   730 // pre:		aCon points to a console being used to read a password.
       
   731 //			aPWLeft is the column number from which the left brace should be drawn.
       
   732 //			aPasswd is a valid password.
       
   733 // post:	the password is rendered onto the console and followed by a '#' and
       
   734 //			padding spaces.  Everything is enclosed in a pair of square brackets.
       
   735 	{
       
   736 	aCon->SetCursorPosAbs(TPoint(aPWLeft, 3));
       
   737 	aCon->Write(_L("["));
       
   738 	aCon->Write(aPW);
       
   739 	aCon->Write(_L("#"));
       
   740 
       
   741 	TInt i;
       
   742 	for (i = 0; i < KMaxMediaPassword - aPW.Length(); i++)
       
   743 		{
       
   744 		aCon->Write(_L(" "));
       
   745 		}
       
   746 
       
   747 	aCon->Write(_L("]"));
       
   748 	}
       
   749 
       
   750 
       
   751 void CNotifierSession::RunPasswordWindowL(const RMessage2 &aMsg)
       
   752 //
       
   753 // Eight unicode chars are mapped to (up to) sixteen bytes.  Remainder of array is
       
   754 // zeroed.  Message is completed in CNotifierSession::ServiceL().
       
   755 // 
       
   756 	{
       
   757 	// local copies of dialog data, 5 * (8 + 32 * 2) bytes
       
   758 	TBuf<0x20> line1, line2, unlockBtn, storeBtn, cancelBtn;
       
   759 	line1.Copy(_L("Password notifier"));
       
   760 	line2.Copy(_L("Enter password"));
       
   761 	unlockBtn.Copy(_L("Unlock"));
       
   762 	storeBtn.Copy(_L("Store"));
       
   763 	cancelBtn.Copy(_L("Cancel"));
       
   764 
       
   765 	TPckgBuf<TMediaPswdReplyNotifyInfoV1> reply;
       
   766 
       
   767 	// Format the console window.
       
   768 
       
   769 	const TInt KPasswordBarLen(1 + KMaxMediaPassword + 1 + 1);
       
   770 	const TInt KButtonBarLen(
       
   771 				1 + unlockBtn.Length() + 1
       
   772 		+ 1 +	1 + cancelBtn.Length() + 1
       
   773 		+ 1 +	1 + storeBtn.Length() + 1);
       
   774 
       
   775 	// Work out width of window.
       
   776 	// (Buttons are enclosed by angle brackets and separted by a space.)
       
   777 	// (Password is followed by '#' and delimited by square brackets.)
       
   778 	// If KButtonBarLen is at least as long as any other line then it will write
       
   779 	// to the bottom right corner and cause the console to scroll.  To counter
       
   780 	// this, an extra padding character is added if necessary.
       
   781 
       
   782 	TInt width;
       
   783 	width = Max(line1.Length(), line2.Length());
       
   784 	width = Max(width, KPasswordBarLen);
       
   785 	width = KButtonBarLen >= width ? KButtonBarLen + 1: width;
       
   786 
       
   787 	// Create the window and render its contents.
       
   788 
       
   789 	RConsole con;
       
   790 	con.Create();
       
   791 	con.Control(_L("-Visible"));
       
   792 	TInt r = con.Init(_L(""), TSize(width, 2 + 1 + 1 + 1 + 1));
       
   793 	if (KErrNone != r)
       
   794 		{
       
   795 		PanicClient(aMsg, ENotifierPanicPasswordWindow);
       
   796 		User::Leave(KErrGeneral);
       
   797 		}
       
   798 	con.Control(_L("+Max -Cursor -AllowResize +OnTop"));
       
   799 
       
   800 	con.SetCursorPosAbs(TPoint(0, 0));
       
   801 	con.Write(line1);
       
   802 	con.SetCursorPosAbs(TPoint(0, 1));
       
   803 	con.Write(line2);
       
   804 	const TInt KPasswordLeft((width - KPasswordBarLen) / 2);
       
   805 	con.SetCursorPosAbs(TPoint(KPasswordLeft, 3));
       
   806 	con.Write(_L("[#                ]"));
       
   807 	con.SetCursorPosAbs(TPoint((width - KButtonBarLen) / 2, 5));
       
   808 	con.Write(_L("<"));
       
   809 	con.Write(unlockBtn);
       
   810 	con.Write(_L("> <"));
       
   811 	con.Write(storeBtn);
       
   812 	con.Write(_L("> <"));
       
   813 	con.Write(cancelBtn);
       
   814 	con.Write(_L(">"));
       
   815 
       
   816 	// Allow the user to edit the password until they either press enter or escape.
       
   817 
       
   818 	TBool done(EFalse);
       
   819 	TBuf<KMaxMediaPassword> pw;
       
   820 	pw.Zero();
       
   821 	TMediaPswdNotifyExitMode em(EMPEMUnlock);	// avoid VC warning C4701 (used w/o init).
       
   822 
       
   823 	const TInt sendInfoLen = User::LeaveIfError(aMsg.GetDesLength(1));
       
   824 
       
   825 	if (sendInfoLen == sizeof(TMediaPswdSendNotifyInfoV1Debug))
       
   826 		{
       
   827 		// debug mode - wait for specified period and close notifier
       
   828 
       
   829 		TPckgBuf<TMediaPswdSendNotifyInfoV1Debug> sendDbg;
       
   830 		aMsg.ReadL(1, sendDbg);
       
   831 		if (sendDbg().iSleepPeriod >= 0)
       
   832 			User::After(sendDbg().iSleepPeriod);
       
   833 		else
       
   834 			{
       
   835 			TTime now;
       
   836 			now.HomeTime();
       
   837 			TInt64 seed = now.Int64();
       
   838 			User::After(Math::Rand(seed) % -(sendDbg().iSleepPeriod));
       
   839 			}
       
   840 
       
   841 		reply().iEM = sendDbg().iEM;
       
   842 		Mem::Copy(reply().iPW, sendDbg().iPW, KMaxMediaPassword);
       
   843 		}
       
   844 	else
       
   845 		{
       
   846 		RenderPassword(&con, KPasswordLeft, pw);
       
   847 		do
       
   848 			{
       
   849 			TConsoleKey key;
       
   850 
       
   851 			con.Read(key);
       
   852 			TInt keyCode = key.Code();
       
   853 
       
   854 			switch (keyCode)
       
   855 				{
       
   856 				case EKeyEscape:
       
   857 					em = EMPEMCancel;
       
   858 					done = ETrue;
       
   859 					break;
       
   860 
       
   861 				case EKeyEnter:
       
   862 					em = EMPEMUnlock;
       
   863 					done = ETrue;
       
   864 					break;
       
   865 				
       
   866 				case EKeySpace:
       
   867 					em = EMPEMUnlockAndStore;
       
   868 					done = ETrue;
       
   869 					break;
       
   870 				
       
   871 				case EKeyBackspace:
       
   872 					if (pw.Length() > 0)
       
   873 						{
       
   874 						pw.SetLength(pw.Length() - 1);
       
   875 						RenderPassword(&con, KPasswordLeft, pw);
       
   876 						}
       
   877 					break;
       
   878 
       
   879 				default:							// interpret other keys as pw contents
       
   880 					TChar ch(keyCode);
       
   881 					// unicode encoding, so number of password characters is half byte length
       
   882 					if (ch.IsPrint() && pw.Length() < KMaxMediaPassword / 2)
       
   883 						{
       
   884 						pw.Append(ch);
       
   885 						RenderPassword(&con, KPasswordLeft, pw);
       
   886 						}
       
   887 					break;
       
   888 				}
       
   889 			} while (! done);
       
   890 
       
   891 		// Fill the TMediaPswdReplyNotifyInfoV1 structure.
       
   892 
       
   893 		if (em == EMPEMUnlock || em == EMPEMUnlockAndStore)
       
   894 			{
       
   895 			const TInt byteLen = pw.Length() * 2;
       
   896 
       
   897 			// zero entire array; and then copy in valid section of TMediaPassword,
       
   898 			// not converting Unicode to ASCII.
       
   899 			TPtr8 pt8(reply().iPW, KMaxMediaPassword);	// length = 0
       
   900 			pt8.FillZ(KMaxMediaPassword);				// length = KMaxMediaPassword
       
   901 			pt8.Zero();									// length = 0
       
   902 														// length = byteLen
       
   903 			pt8.Copy(reinterpret_cast<const TUint8 *>(pw.Ptr()), byteLen);
       
   904 			}
       
   905 		
       
   906 		// Set exit mode to tell user how dialog handled.
       
   907 
       
   908 		reply().iEM = em;
       
   909 		}	// else (sendInfoLen == sizeof(TMediaPswdSendNotifyInfoV1Debug))
       
   910 	
       
   911 	con.Destroy();
       
   912 
       
   913 	aMsg.WriteL(2, reply);
       
   914 	}
       
   915 
       
   916 //
       
   917 // class MNotifierBase2
       
   918 //
       
   919 
       
   920 void MNotifierBase2::SetManager(MNotifierManager* aManager)
       
   921 	{
       
   922 	iManager=aManager;
       
   923 	}
       
   924 
       
   925 //
       
   926 // class CNotifierServer
       
   927 //
       
   928 
       
   929 _LIT(__NOTIFIER_SERVER,"TextNotifierSrvr");
       
   930 
       
   931 CNotifierServer* CNotifierServer::NewL()
       
   932 	{
       
   933 	CNotifierServer* server=new(ELeave) CNotifierServer(200);
       
   934 	CleanupStack::PushL(server);
       
   935 	server->ConstructL();
       
   936 	server->StartL(__NOTIFIER_NAME);
       
   937 	CleanupStack::Pop(); // server
       
   938 	return server;
       
   939 	}
       
   940 
       
   941 CNotifierServer::~CNotifierServer()
       
   942 	{
       
   943 	SetIsExiting();
       
   944 	delete iManager;
       
   945 	}
       
   946 
       
   947 void CNotifierServer::SetIsExiting()
       
   948 	{
       
   949 	iExiting=ETrue;
       
   950 	}
       
   951 
       
   952 TBool CNotifierServer::IsExiting() const
       
   953 	{
       
   954 	return iExiting;
       
   955 	}
       
   956 
       
   957 CNotifierServer::CNotifierServer(TInt aPriority)
       
   958 	: CServer2(aPriority)
       
   959 	{}
       
   960 
       
   961 void CNotifierServer::ConstructL()
       
   962 	{
       
   963 	iManager=CNotifierManager::NewL();
       
   964 	RFs fs;
       
   965 	User::LeaveIfError(fs.Connect());
       
   966 	CleanupClosePushL(fs);
       
   967 	iManager->RegisterL(fs);
       
   968 	CleanupStack::PopAndDestroy(); // fs.Close()
       
   969 	}
       
   970 
       
   971 CSession2* CNotifierServer::NewSessionL(const TVersion &aVersion,const RMessage2&) const
       
   972 	{
       
   973 	TVersion v(1,0,0); // !! liaise with E32
       
   974 	if (!User::QueryVersionSupported(v,aVersion))
       
   975 		User::Leave(KErrNotSupported);
       
   976 	return new(ELeave) CNotifierSession(*this);
       
   977 	}
       
   978 
       
   979 //
       
   980 // class CNotifierSession
       
   981 //
       
   982 
       
   983 CNotifierSession::CNotifierSession(const CNotifierServer& aServer)
       
   984 	{
       
   985 	iServer=&aServer;
       
   986 	iClientId=(TInt)this;
       
   987 	}
       
   988 
       
   989 CNotifierSession::~CNotifierSession()
       
   990 	{
       
   991 	const CNotifierServer* server=static_cast<const CNotifierServer*>(Server());
       
   992 	if (!server->IsExiting())
       
   993 		{
       
   994 		server->Manager()->HandleClientExit(iClientId);
       
   995 		}
       
   996 	}
       
   997 
       
   998 void CNotifierSession::ServiceL(const RMessage2 &aMessage)
       
   999 	{
       
  1000 	TBool completeMessage=ETrue;
       
  1001 	switch (aMessage.Function())
       
  1002 		{
       
  1003 	case ENotifierNotify:
       
  1004 		DisplayAlertL(aMessage);
       
  1005 		break;
       
  1006 	case ENotifierNotifyCancel:
       
  1007 		// do nothing - this server doesn't support cancelling RNotifier::Notify - the client will just have to wait
       
  1008 		break;
       
  1009 	case ENotifierInfoPrint:
       
  1010 		DisplayInfoMsgL(aMessage);
       
  1011 		break;
       
  1012 	case EStartNotifier:
       
  1013 		DoStartNotifierL(aMessage);
       
  1014 		break;
       
  1015 	case ECancelNotifier:
       
  1016 		iServer->Manager()->NotifierCancel(TUid::Uid(aMessage.Int0()));
       
  1017 		break;
       
  1018 	case EUpdateNotifierAndGetResponse:
       
  1019 	case EUpdateNotifier:
       
  1020 		DoUpdateNotifierL(aMessage);
       
  1021 		break;
       
  1022 	case EStartNotifierAndGetResponse:
       
  1023 		{
       
  1024 		if (aMessage.Int0()==KMediaPasswordNotifyUid)
       
  1025 			{
       
  1026 			RunPasswordWindowL(aMessage);
       
  1027 			}
       
  1028 		else
       
  1029 			{
       
  1030 			TBool cleanupComplete=ETrue;
       
  1031 			StartNotifierAndGetResponseL(aMessage,cleanupComplete);
       
  1032 			 // if the plug-in starts successfully, it has
       
  1033 			 // responsibility for completing the message (either
       
  1034 			 // synchronously or asynchronously)
       
  1035 			completeMessage=EFalse;
       
  1036 			}
       
  1037 		}
       
  1038 		break;
       
  1039 	default:
       
  1040 		aMessage.Complete(KErrNotSupported);
       
  1041 		break;
       
  1042 		}
       
  1043 	if (completeMessage && !aMessage.IsNull())
       
  1044 		{
       
  1045 		aMessage.Complete(KErrNone);
       
  1046 		}
       
  1047 	}
       
  1048 
       
  1049 void CNotifierSession::DisplayAlertL(const RMessage2& aMessage)
       
  1050 	{
       
  1051 	const TInt lengthOfCombinedBuffer=User::LeaveIfError(aMessage.GetDesLength(1));
       
  1052 	const TInt lengthOfLine1=(STATIC_CAST(TUint,aMessage.Int2())>>16);
       
  1053 	const TInt lengthOfLine2=(aMessage.Int2()&KMaxTUint16);
       
  1054 	const TInt lengthOfBut1=(STATIC_CAST(TUint,aMessage.Int3())>>16);
       
  1055 	const TInt lengthOfBut2=(aMessage.Int3()&KMaxTUint16);
       
  1056 	if (lengthOfCombinedBuffer!=lengthOfLine1+lengthOfLine2+lengthOfBut1+lengthOfBut2)
       
  1057 		{
       
  1058 		PanicClient(aMessage,ENotifierPanicInconsistentDescriptorLengths);
       
  1059 		return;
       
  1060 		}
       
  1061 	HBufC* const combinedBuffer=HBufC::NewLC(lengthOfCombinedBuffer);
       
  1062 	{TPtr combinedBuffer_asWritable(combinedBuffer->Des());
       
  1063 	aMessage.ReadL(1,combinedBuffer_asWritable);}
       
  1064 	const TPtrC line1(combinedBuffer->Left(lengthOfLine1));
       
  1065 	const TPtrC line2(combinedBuffer->Mid(lengthOfLine1,lengthOfLine2));
       
  1066 	const TPtrC but1(combinedBuffer->Mid(lengthOfLine1+lengthOfLine2,lengthOfBut1));
       
  1067 	const TPtrC but2(combinedBuffer->Mid(lengthOfLine1+lengthOfLine2+lengthOfBut1,lengthOfBut2));
       
  1068 	TInt buttons, len, offset;
       
  1069 	if (lengthOfBut2==0)
       
  1070 		{
       
  1071 		buttons=1;
       
  1072 		len=lengthOfBut1+2;
       
  1073 		}
       
  1074 	else
       
  1075 		{
       
  1076 		buttons=2;
       
  1077 		len=lengthOfBut1+lengthOfBut2+5;
       
  1078 		}
       
  1079 	if (lengthOfLine1>len)
       
  1080 		len=lengthOfLine1;
       
  1081 	if (lengthOfLine2>len)
       
  1082 		len=lengthOfLine2;
       
  1083 	RConsole con;
       
  1084 	con.Create();
       
  1085 	TSize scsz;
       
  1086 	con.ScreenSize(scsz);
       
  1087 	con.Control(_L("-Visible"));
       
  1088 	TInt ww=Min(len,scsz.iWidth-4);
       
  1089 	TInt wh=3;
       
  1090 	if ((lengthOfBut1+lengthOfBut2+5)>ww)
       
  1091 		wh++;
       
  1092 	if (lengthOfLine1>ww)
       
  1093 		wh++;
       
  1094 	if (lengthOfLine2>ww)
       
  1095 		wh++;
       
  1096 	con.Init(_L(""),TSize(ww,wh));
       
  1097 	con.Control(_L("+Max -Cursor -Allowresize +Ontop +Wrap"));
       
  1098 	con.Write(line1);
       
  1099 	con.SetCursorPosAbs(TPoint(0,1));
       
  1100 	con.Write(line2);
       
  1101 	if (buttons==2)
       
  1102 		offset=(len-lengthOfBut1-lengthOfBut2-5)/2;
       
  1103 	else
       
  1104 		offset=(len-lengthOfBut1-2)/2;
       
  1105 	con.SetCursorPosAbs(TPoint(offset,2));
       
  1106 	con.Write(_L("<"));
       
  1107 	con.Write(but1);
       
  1108 	con.Write(_L(">"));
       
  1109 	if(buttons==2)
       
  1110 		{
       
  1111 		con.Write(_L(" <"));
       
  1112 		con.Write(but2);
       
  1113 		con.Write(_L(">"));
       
  1114 		}
       
  1115 	
       
  1116 	TConsoleKey key;
       
  1117 	TInt keycode;
       
  1118 	do
       
  1119 		{
       
  1120 		con.Read(key);
       
  1121 		keycode=key.Code();
       
  1122 		}
       
  1123 	while((keycode!=EKeyEscape&&keycode!=EKeyEnter&&buttons==2)||(keycode!=EKeyEnter&&buttons==1));
       
  1124 	if(keycode==EKeyEscape)
       
  1125 		keycode=0;
       
  1126 	else
       
  1127 		keycode=1;
       
  1128 	con.Destroy();
       
  1129 	aMessage.WriteL(0,TPckgC<TInt>(keycode));
       
  1130 	CleanupStack::PopAndDestroy(combinedBuffer);
       
  1131 	}
       
  1132 
       
  1133 TInt CNotifierSession::InfoPrintThread(TAny* aMessage)
       
  1134 	{
       
  1135 	TBuf<0x50> des; // 0x50 max size of message
       
  1136 	RConsole con;
       
  1137 	des=*(TBuf<0x50> *)aMessage;
       
  1138 	TInt l=des.Length();
       
  1139 	NotifierSemaphore.Signal();
       
  1140 	con.Create();
       
  1141 	con.Control(_L("-Visible"));
       
  1142 	TSize size;
       
  1143 	con.ScreenSize(size);
       
  1144 	TInt ww=Min(size.iWidth-6,l);
       
  1145 	TInt wh=(l+ww-1)/ww;
       
  1146 	if (wh==0)
       
  1147 		wh=1;
       
  1148 	con.Init(_L(""),TSize(ww,wh));
       
  1149 	con.Control(_L("+Maximise"));
       
  1150 	con.SetWindowPosAbs(TPoint(size.iWidth-ww-4,1));
       
  1151 	con.Control(_L("+Wrap +Ontop"));
       
  1152 	con.Write(des);
       
  1153 
       
  1154 	User::After(1300000);
       
  1155 	con.Destroy();
       
  1156 	return KErrNone;
       
  1157 	}
       
  1158 
       
  1159 void CNotifierSession::DisplayInfoMsgL(const RMessage2& aMessage)
       
  1160 	{
       
  1161 	TInt r;
       
  1162 	TBuf<0x50> des; // 0x50 max size of message lines
       
  1163 	aMessage.ReadL(0,des);
       
  1164 	RThread thread;
       
  1165 	do
       
  1166 		{
       
  1167 		r=thread.Create(_L("Info Window"),InfoPrintThread,KDefaultStackSize,&User::Allocator(),(TAny*)&des);
       
  1168 		if(r==KErrAlreadyExists)
       
  1169 			User::After(200000);
       
  1170 		} while(r==KErrAlreadyExists);
       
  1171 		User::LeaveIfError(r);
       
  1172 	thread.Resume();
       
  1173 	NotifierSemaphore.Wait();
       
  1174 	thread.Close();
       
  1175 	}
       
  1176 
       
  1177 void CNotifierSession::DoStartNotifierL(const RMessage2& aMessage)
       
  1178 	{
       
  1179 	const TUid targetUid={aMessage.Int0()};
       
  1180 	HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1)));
       
  1181 	{TPtr8 input(inputBuffer->Des());
       
  1182 	aMessage.ReadL(1,input);}
       
  1183 	TPtrC8 output(0,0);
       
  1184 	iServer->Manager()->NotifierStartL(targetUid,*inputBuffer,&output,iClientId);
       
  1185 	if(aMessage.Int2())
       
  1186 		aMessage.WriteL(2,output);
       
  1187 	CleanupStack::PopAndDestroy(inputBuffer);
       
  1188 	}
       
  1189 
       
  1190 void CNotifierSession::DoUpdateNotifierL(const RMessage2& aMessage)
       
  1191 	{
       
  1192 	const TUid targetUid={aMessage.Int0()};
       
  1193 	HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1)));
       
  1194 	{TPtr8 input(inputBuffer->Des());
       
  1195 	aMessage.ReadL(1, input);}
       
  1196 	HBufC8* const outputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesMaxLength(2)));
       
  1197 	{TPtr8 output(outputBuffer->Des());
       
  1198 	iServer->Manager()->NotifierUpdateL(targetUid,*inputBuffer,&output,iClientId);}
       
  1199 	aMessage.WriteL(2,*outputBuffer);
       
  1200 	CleanupStack::PopAndDestroy(2,inputBuffer);
       
  1201 	}
       
  1202 
       
  1203 void CNotifierSession::StartNotifierAndGetResponseL(const RMessage2& aMessage,TBool& aCleanupComplete)
       
  1204 	{
       
  1205 	const TUid targetUid={aMessage.Int0()};
       
  1206 	HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1)));
       
  1207 	{TPtr8 input(inputBuffer->Des());
       
  1208 	aMessage.ReadL(1,input);}
       
  1209 	iServer->Manager()->NotifierStartAndGetResponseL(targetUid,*inputBuffer,2,aMessage,iClientId,aCleanupComplete);
       
  1210 	CleanupStack::PopAndDestroy(inputBuffer);
       
  1211 	}
       
  1212 
       
  1213 void CNotifierSession::PanicClient(const RMessage2& aMessage,TNotifierPanic aCode)
       
  1214 	{
       
  1215 	aMessage.Panic(__NOTIFIER_SERVER,aCode);
       
  1216 	}
       
  1217 
       
  1218 //
       
  1219 // class CNotifierManager
       
  1220 //
       
  1221 
       
  1222 const TInt KNullClientId=0;
       
  1223 
       
  1224 CNotifierManager* CNotifierManager::NewL()
       
  1225 	{
       
  1226 	CNotifierManager* self=new(ELeave) CNotifierManager;
       
  1227 	CleanupStack::PushL(self);
       
  1228 	self->ConstructL();
       
  1229 	CleanupStack::Pop(self);
       
  1230 	return self;
       
  1231 	}
       
  1232 
       
  1233 CNotifierManager::~CNotifierManager()
       
  1234 	{
       
  1235 	if (iObservedList)
       
  1236 		{
       
  1237 		const TInt count=iObservedList->Count();
       
  1238 		for (TInt ii=0;ii<count;ii++)
       
  1239 			{
       
  1240 			(*iObservedList)[ii]->Release();
       
  1241 			}
       
  1242 		delete iObservedList;
       
  1243 		}
       
  1244 	if (iLibraries)
       
  1245 		{
       
  1246 		const TInt count=iLibraries->Count();
       
  1247 		for (TInt ii=0;ii<count;ii++)
       
  1248 			{
       
  1249 			(*iLibraries)[ii].Close();
       
  1250 			}
       
  1251 		delete iLibraries;
       
  1252 		}
       
  1253 	delete iChannelMonitor;
       
  1254 	delete iActivityMonitor;
       
  1255 	delete iQueue;
       
  1256 	}
       
  1257 
       
  1258 
       
  1259 void CNotifierManager::RegisterL(RFs& aFs)
       
  1260 	{
       
  1261 #ifdef SUPPORT_OLD_PLUGIN_PATH
       
  1262 	TBool old;
       
  1263 	for(old=0; old<2; old++)
       
  1264 	{
       
  1265 #endif
       
  1266 	TFindFile* findFile=new(ELeave) TFindFile(aFs);
       
  1267 	CleanupStack::PushL(findFile);
       
  1268 	TParse* fileNameParser=new(ELeave) TParse;
       
  1269 	CleanupStack::PushL(fileNameParser);
       
  1270 	CDir* directory=NULL;
       
  1271 	TInt error;
       
  1272 #ifdef SUPPORT_OLD_PLUGIN_PATH
       
  1273 	_LIT(KNotifierPlugInOldSearchPath,"\\system\\tnotifiers\\");
       
  1274 	if(old)
       
  1275 		error=findFile->FindWildByDir(KNotifierPlugInExt, KNotifierPlugInOldSearchPath, directory);
       
  1276 	else
       
  1277 #endif
       
  1278 	error=findFile->FindWildByDir(KNotifierPlugInExt, KNotifierPlugInSearchPath, directory);
       
  1279 	for (; error!=KErrNotFound; error=findFile->FindWild(directory))
       
  1280 		{
       
  1281 		CleanupStack::PushL(directory);
       
  1282 		User::LeaveIfError(error);
       
  1283 		const TInt numberOfEntries=directory->Count();
       
  1284 		for (TInt i=0; i<numberOfEntries; ++i)
       
  1285 			{
       
  1286 			const TEntry& entry=(*directory)[i];
       
  1287 			fileNameParser->SetNoWild(entry.iName, &findFile->File(), NULL); // findFile->File() returns a reference rather than an object, therefore taking the address of it is fine
       
  1288 
       
  1289 			if (entry.iType[0].iUid==0x10000079)
       
  1290 				{
       
  1291 				 // It's a DLL
       
  1292 				if( (entry.iType[1]==KUidTextNotifierPlugInV2))
       
  1293 					{
       
  1294 					// Its a notifier...
       
  1295 					TPtrC path(fileNameParser->DriveAndPath());
       
  1296 					TPtrC name(fileNameParser->NameAndExt());
       
  1297 					DoAddPlugInL(path,name,entry.iType);
       
  1298 					}
       
  1299 				}
       
  1300 			}
       
  1301 		CleanupStack::PopAndDestroy(); // directory
       
  1302 		directory=NULL;
       
  1303 		}
       
  1304 	delete directory;
       
  1305 	CleanupStack::PopAndDestroy(2); // fileNameParser and findFile
       
  1306 #ifdef SUPPORT_OLD_PLUGIN_PATH
       
  1307 	}
       
  1308 #endif
       
  1309 	}
       
  1310 
       
  1311 LOCAL_C void DeleteTemp(TAny* aPtr)
       
  1312 	{
       
  1313 	CArrayPtr<MNotifierBase2>* array=REINTERPRET_CAST(CArrayPtr<MNotifierBase2>*,aPtr);
       
  1314 	const TInt count=array->Count();
       
  1315 	for (TInt ii=0;ii<count;ii++)
       
  1316 		{
       
  1317 		(*array)[ii]->Release();
       
  1318 		}
       
  1319 	delete array;
       
  1320 	}
       
  1321 
       
  1322 
       
  1323 
       
  1324 void CNotifierManager::DoAddPlugInL(const TDesC& aPath,const TDesC& aFileName,const TUidType& aUidType)
       
  1325 	{
       
  1326 	RLibrary lib;
       
  1327 	User::LeaveIfError(lib.Load(aFileName,aPath,aUidType));
       
  1328 	CleanupClosePushL(lib);
       
  1329 	iLibraries->AppendL(lib);
       
  1330 	CleanupStack::Pop(); // lib
       
  1331 	TLibraryFunction libEntry=lib.Lookup(1);
       
  1332 	CArrayPtr<MNotifierBase2>* array=REINTERPRET_CAST(CArrayPtr<MNotifierBase2>*,(libEntry)());
       
  1333 	User::LeaveIfNull(array);
       
  1334 	CleanupStack::PushL(TCleanupItem(DeleteTemp,array));
       
  1335 	while (array->Count()>0)
       
  1336 		{
       
  1337 		MNotifierBase2* notif=(*array)[0];
       
  1338 			{
       
  1339 			iObservedList->AppendL(notif);
       
  1340 			array->Delete(0);
       
  1341 			notif->SetManager(this);
       
  1342 			}
       
  1343 		MNotifierBase2::TNotifierInfo info=notif->RegisterL();
       
  1344 		if (!iChannelMonitor->AlreadyHasChannel(info.iChannel))
       
  1345 			iChannelMonitor->AddNewChannelL(info.iChannel);
       
  1346 		}
       
  1347 	CleanupStack::PopAndDestroy(); // array
       
  1348 	}
       
  1349 
       
  1350 CNotifierManager::CNotifierManager()
       
  1351 	{}
       
  1352 
       
  1353 void CNotifierManager::ConstructL()
       
  1354 	{
       
  1355 	iObservedList=new(ELeave) CArrayPtrSeg<MNotifierBase2>(6);
       
  1356 	iLibraries=new(ELeave) CArrayFixFlat<RLibrary>(2);
       
  1357 	iChannelMonitor=CChannelMonitor::NewL();
       
  1358 	iActivityMonitor=CActivityMonitor::NewL();
       
  1359 	iQueue=CNotifierQueue::NewL();
       
  1360 	}
       
  1361 
       
  1362 struct SActivityCleanup
       
  1363 	{
       
  1364 	CActivityMonitor* iMonitor;
       
  1365 	TUid iNotifier;
       
  1366 	TInt iClientId;
       
  1367 	};
       
  1368 
       
  1369 LOCAL_C void CleanupActivityMonitor(TAny* aPtr)
       
  1370 	{
       
  1371 	SActivityCleanup& cleanup=*REINTERPRET_CAST(SActivityCleanup*,aPtr);
       
  1372 	cleanup.iMonitor->Remove(cleanup.iNotifier,cleanup.iClientId);
       
  1373 	}
       
  1374 
       
  1375 void CNotifierManager::NotifierStartL(TUid aNotifierUid,const TDesC8& aBuffer,TPtrC8* aResponse,TInt aClientId)
       
  1376 	{
       
  1377 	TInt result=KErrNotFound;
       
  1378 	const TInt count=iObservedList->Count();
       
  1379 	for (TInt ii=0;ii<count;ii++)
       
  1380 		{
       
  1381 		MNotifierBase2* notif=(*iObservedList)[ii];
       
  1382 		MNotifierBase2::TNotifierInfo info=notif->Info();
       
  1383 		if (info.iUid==aNotifierUid)
       
  1384 			{
       
  1385 			if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel))
       
  1386 				{
       
  1387 				result=KErrAlreadyExists;
       
  1388 				}
       
  1389 			else if (info.iPriority>iChannelMonitor->ActivityLevel(info.iChannel))
       
  1390 				{
       
  1391 				TUid notifier;
       
  1392 				MNotifierBase2::TNotifierPriority priority;
       
  1393 				const TBool channelWasActive=iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority);
       
  1394 				iActivityMonitor->AddL(info,aClientId);
       
  1395 				SActivityCleanup cleanup;
       
  1396 				cleanup.iMonitor=iActivityMonitor;
       
  1397 				cleanup.iNotifier=aNotifierUid;
       
  1398 				cleanup.iClientId=aClientId;
       
  1399 				CleanupStack::PushL(TCleanupItem(CleanupActivityMonitor,&cleanup));
       
  1400 				TPtrC8 response(notif->StartL(aBuffer));
       
  1401 				if(aResponse)
       
  1402 					aResponse->Set(response);
       
  1403 				CleanupStack::Pop(); // cleanup;
       
  1404 				if (channelWasActive)
       
  1405 					{
       
  1406 					for (TInt jj=0;jj<count;jj++)
       
  1407 						{
       
  1408 						MNotifierBase2* notifForUpdate=(*iObservedList)[ii];
       
  1409 						MNotifierBase2::TNotifierInfo infoForUpdate=notifForUpdate->Info();
       
  1410 						if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel)
       
  1411 							{
       
  1412 							TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused));
       
  1413 							}
       
  1414 						}
       
  1415 					}
       
  1416 				iChannelMonitor->UpdateChannel(info.iChannel,info.iPriority);
       
  1417 				if (result!=ENotExtRequestQueued)
       
  1418 					{
       
  1419 					result=ENotExtRequestCompleted;
       
  1420 					}
       
  1421 				}
       
  1422 			else
       
  1423 				{
       
  1424 				if (iQueue->IsAlreadyQueued(info.iUid,info.iChannel))
       
  1425 					{
       
  1426 					result=KErrAlreadyExists;
       
  1427 					}
       
  1428 				else
       
  1429 					{
       
  1430 					CQueueItem* queueCopy=CQueueItem::NewL(info,aBuffer,aClientId);
       
  1431 					CleanupStack::PushL(queueCopy);
       
  1432 					iQueue->QueueItemL(queueCopy);
       
  1433 					CleanupStack::Pop(); // queueCopy
       
  1434 					result=ENotExtRequestQueued;
       
  1435 					}
       
  1436 				}
       
  1437 			}
       
  1438 		}
       
  1439 	User::LeaveIfError(result);
       
  1440 	}
       
  1441 
       
  1442 TInt CNotifierManager::NotifierUpdateL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8* aResponse,TInt aClientId)
       
  1443 	{
       
  1444 	TInt result=KErrNotFound;
       
  1445 	const TInt count=iObservedList->Count();
       
  1446 	for (TInt ii=0;ii<count;ii++)
       
  1447 		{
       
  1448 		MNotifierBase2* notif=(*iObservedList)[ii];
       
  1449 		MNotifierBase2::TNotifierInfo info=notif->Info();
       
  1450 		if (info.iUid==aNotifierUid)
       
  1451 			{
       
  1452 			if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel))
       
  1453 				{
       
  1454 				if (!iActivityMonitor->IsClientPresent(aNotifierUid,info.iChannel,aClientId))
       
  1455 					{
       
  1456 					iActivityMonitor->AddL(info,aClientId);
       
  1457 					}
       
  1458 				if (aResponse==NULL)
       
  1459 					{
       
  1460 					notif->UpdateL(aBuffer);
       
  1461 					}
       
  1462 				else
       
  1463 					{
       
  1464 					aResponse->Copy(notif->UpdateL(aBuffer));
       
  1465 					}
       
  1466 				}
       
  1467 			else
       
  1468 				{
       
  1469 				; // not all channels have been started yet so update the queue
       
  1470 				}
       
  1471 			result=KErrNone;
       
  1472 			}
       
  1473 		}
       
  1474 	return result;
       
  1475 	}
       
  1476 
       
  1477 void CNotifierManager::NotifierStartAndGetResponseL(TUid aNotifierUid,const TDesC8& aBuffer,TInt aReplySlot,
       
  1478 														  const RMessage2& aMessage,TInt aClientId,TBool& aCleanupComplete)
       
  1479 	{
       
  1480 	NotifierStartAndGetResponseL(aNotifierUid,TUid::Null(),aBuffer,aReplySlot,aMessage,aClientId,aCleanupComplete);
       
  1481 	}
       
  1482 
       
  1483 void CNotifierManager::NotifierStartAndGetResponseL(TUid aNotifierUid,TUid aChannelUid,const TDesC8& aBuffer,TInt aReplySlot,
       
  1484 														  const RMessage2& aMessage,TInt aClientId,TBool& aCleanupComplete)
       
  1485 	{
       
  1486 	TInt result=KErrNotFound;
       
  1487 	const TInt count=iObservedList->Count();
       
  1488 	for (TInt ii=0;ii<count;ii++)
       
  1489 		{
       
  1490 		MNotifierBase2* notif=(*iObservedList)[ii];
       
  1491 		MNotifierBase2::TNotifierInfo info=notif->Info();
       
  1492 		if (info.iUid==aNotifierUid && (aChannelUid==TUid::Null() || info.iChannel==aChannelUid))
       
  1493 			{
       
  1494 			if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel))
       
  1495 				{
       
  1496 				notif->StartL(aBuffer,aReplySlot,aMessage); // asynch notifier can decide whether to support multiple clients
       
  1497 				result=KErrNone;
       
  1498 				}
       
  1499 			else if (info.iPriority>iChannelMonitor->ActivityLevel(info.iChannel))
       
  1500 				{
       
  1501 				TUid notifier;
       
  1502 				MNotifierBase2::TNotifierPriority priority;
       
  1503 				const TBool channelWasActive=iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority);
       
  1504 				iActivityMonitor->AddL(info,aClientId);
       
  1505 				SActivityCleanup activityCleanup;
       
  1506 				activityCleanup.iMonitor=iActivityMonitor;
       
  1507 				activityCleanup.iNotifier=aNotifierUid;
       
  1508 				activityCleanup.iClientId=aClientId;
       
  1509 				CleanupStack::PushL(TCleanupItem(CleanupActivityMonitor,&activityCleanup));
       
  1510 				aCleanupComplete=EFalse;
       
  1511 				// IMPORTANT, aMessage needs to be a full RMessage object until suport for V1 notifiers is removed
       
  1512 				// I.e. until CNotifierBaseAdaptor is removed
       
  1513 				notif->StartL(aBuffer,aReplySlot,aMessage);
       
  1514 				CleanupStack::Pop(&activityCleanup);
       
  1515 				if (channelWasActive)
       
  1516 					{
       
  1517 					for (TInt jj=0;jj<count;jj++)
       
  1518 						{
       
  1519 						MNotifierBase2* notifForUpdate=(*iObservedList)[ii];
       
  1520 						MNotifierBase2::TNotifierInfo infoForUpdate=notifForUpdate->Info();
       
  1521 						if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel)
       
  1522 							{
       
  1523 							TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused));
       
  1524 							}
       
  1525 						}
       
  1526 					}
       
  1527 				iChannelMonitor->UpdateChannel(info.iChannel,info.iPriority);
       
  1528 				result=KErrNone;
       
  1529 				}
       
  1530 			else
       
  1531 				{
       
  1532 				if (iQueue->IsAlreadyQueued(info.iUid,info.iChannel))
       
  1533 					{
       
  1534 					result=KErrAlreadyExists;
       
  1535 					}
       
  1536 				else
       
  1537 					{
       
  1538 					CQueueItem* queueCopy=CQueueItem::NewL(info,aBuffer,aReplySlot,aMessage,aClientId);
       
  1539 					CleanupStack::PushL(queueCopy);
       
  1540 					iQueue->QueueItemL(queueCopy);
       
  1541 					CleanupStack::Pop(queueCopy);
       
  1542 					result=ENotExtRequestQueued;
       
  1543 					}
       
  1544 				}
       
  1545 			}
       
  1546 		}
       
  1547 	User::LeaveIfError(result);
       
  1548 	}
       
  1549 
       
  1550 TInt CNotifierManager::NotifierCancel(TUid aNotifierUid)
       
  1551 	{
       
  1552 	TInt result=KErrNotFound;
       
  1553 	const TInt count=iObservedList->Count();
       
  1554 	for (TInt ii=0;ii<count;ii++)
       
  1555 		{
       
  1556 		MNotifierBase2* notif=(*iObservedList)[ii];
       
  1557 		MNotifierBase2::TNotifierInfo info=notif->Info();
       
  1558 		if (info.iUid==aNotifierUid)
       
  1559 			{
       
  1560 			notif->Cancel();
       
  1561 			iActivityMonitor->RemoveNotifier(aNotifierUid,info.iChannel);
       
  1562 			MNotifierBase2::TNotifierPriority priority=MNotifierBase2::ENotifierPriorityLowest;
       
  1563 			TUid notifier;
       
  1564 			//check channel activity and get highest priority on channnel
       
  1565 			if (iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority))
       
  1566 				{
       
  1567 
       
  1568 				//check if priority of a queued item on the same channel is
       
  1569 				//greater 
       
  1570 				MNotifierBase2::TNotifierPriority queuePriority=
       
  1571 				(MNotifierBase2::TNotifierPriority)iQueue->GetHighestQueuePriority(info.iChannel);
       
  1572 				if (queuePriority>priority)
       
  1573 					{
       
  1574 					iChannelMonitor->UpdateChannel(info.iChannel,MNotifierBase2::ENotifierPriorityLowest);
       
  1575 					CQueueItem* next=iQueue->FetchItem(info.iChannel);
       
  1576 					if (next)
       
  1577 						{
       
  1578 						TUid notif=next->iInfo.iUid;
       
  1579 						TRAPD(err,StartFromQueueL(next));
       
  1580 						if (err!=KErrNone)
       
  1581 							{
       
  1582 							NotifierCancel(notif);
       
  1583 							}
       
  1584 						}
       
  1585 					 }
       
  1586 					else
       
  1587 					{
       
  1588 					for (TInt jj=0;jj<count;jj++)
       
  1589 						{
       
  1590 						MNotifierBase2* notifForUpdate=(*iObservedList)[ii];
       
  1591 						MNotifierBase2::TNotifierInfo infoForUpdate=notifForUpdate->Info();
       
  1592 						if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel)
       
  1593 							{
       
  1594 							TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused));
       
  1595 							}
       
  1596 						}
       
  1597 					iChannelMonitor->UpdateChannel(info.iChannel,priority);
       
  1598 					}
       
  1599 				}
       
  1600 			else
       
  1601 				{
       
  1602 				iChannelMonitor->UpdateChannel(info.iChannel,MNotifierBase2::ENotifierPriorityLowest);
       
  1603 				CQueueItem* next=iQueue->FetchItem(info.iChannel);
       
  1604 				if (next)
       
  1605 					{
       
  1606 					TUid notif=next->iInfo.iUid;
       
  1607 					TRAPD(err,StartFromQueueL(next));
       
  1608 					if (err!=KErrNone)
       
  1609 						{
       
  1610 						NotifierCancel(notif);
       
  1611 						}
       
  1612 					}
       
  1613 				}
       
  1614 			result=KErrNone;
       
  1615 			}
       
  1616 		}
       
  1617 	return result;
       
  1618 	}
       
  1619 
       
  1620 struct SCleanupMessage
       
  1621 	{
       
  1622 	TBool* iDoCleanup;
       
  1623 	RMessage2* iMessage;
       
  1624 	};
       
  1625 
       
  1626 LOCAL_C void CleanupStartAndGetResponse(TAny* aPtr)
       
  1627 	{
       
  1628 	SCleanupMessage& cleanup=*REINTERPRET_CAST(SCleanupMessage*,aPtr);
       
  1629 	if (cleanup.iDoCleanup)
       
  1630 		{
       
  1631 		cleanup.iMessage->Complete(KErrNoMemory);
       
  1632 		}
       
  1633 	}
       
  1634 
       
  1635 void CNotifierManager::StartFromQueueL(CQueueItem* aItem)
       
  1636 	{
       
  1637 	CleanupStack::PushL(aItem);
       
  1638 	TPtr8 buffer=aItem->iBuffer->Des();
       
  1639 	if (aItem->iAsynchronous)
       
  1640 		{
       
  1641 		SCleanupMessage cleanup;
       
  1642 		TBool doCleanup=ETrue;
       
  1643 		cleanup.iDoCleanup=&doCleanup;
       
  1644 		cleanup.iMessage=&aItem->iMessage;
       
  1645 		CleanupStack::PushL(TCleanupItem(CleanupStartAndGetResponse,&cleanup));
       
  1646 		// IMPORTANT, aItem->iMessage needs to be a full RMessage object until suport for V1 notifiers is removed
       
  1647 		// I.e. until CNotifierBaseAdaptor is removed
       
  1648 		NotifierStartAndGetResponseL(aItem->iInfo.iUid,aItem->iInfo.iChannel,buffer,aItem->iReplySlot,aItem->iMessage,aItem->iClientId,doCleanup);
       
  1649 		CleanupStack::Pop(&cleanup);
       
  1650 		}
       
  1651 	else
       
  1652 		{
       
  1653 		NotifierStartL(aItem->iInfo.iUid,buffer,NULL,aItem->iClientId);
       
  1654 		}
       
  1655 	CleanupStack::PopAndDestroy(); // aItem
       
  1656 	CQueueItem* update=iQueue->FetchItem(aItem->iInfo.iChannel);
       
  1657 	while (update)
       
  1658 		{
       
  1659 		CleanupStack::PushL(update);
       
  1660 		NotifierUpdateL(update->iInfo.iUid,*update->iBuffer,NULL,update->iClientId);
       
  1661 		CleanupStack::PopAndDestroy(); // update
       
  1662 		update=iQueue->FetchItem(aItem->iInfo.iChannel);
       
  1663 		}
       
  1664 	}
       
  1665 
       
  1666 void CNotifierManager::HandleClientExit(TInt aClientId)
       
  1667 	{
       
  1668 	TUid notifier=KNullUid;
       
  1669 	while (iActivityMonitor->NotifierForClient(notifier,aClientId))
       
  1670 		{
       
  1671 		const TInt count=iObservedList->Count();
       
  1672 		for (TInt ii=0;ii<count;ii++)
       
  1673 			{
       
  1674 			MNotifierBase2* notif=(*iObservedList)[ii];
       
  1675 			if (notif->Info().iUid==notifier)
       
  1676 				{
       
  1677 				NotifierCancel(notifier);
       
  1678 				}
       
  1679 			}
       
  1680 		iActivityMonitor->Remove(notifier,aClientId);
       
  1681 		}
       
  1682 	iActivityMonitor->RemoveClient(aClientId);
       
  1683 	iQueue->RemoveClient(aClientId);
       
  1684 	}
       
  1685 
       
  1686 void CNotifierManager::StartNotifierL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
       
  1687 	{
       
  1688 	TPtrC8 response(0,0);
       
  1689 	NotifierStartL(aNotifierUid,aBuffer, &response,KNullClientId);
       
  1690 	aResponse.Copy(response);
       
  1691 	}
       
  1692 
       
  1693 void CNotifierManager::CancelNotifier(TUid aNotifierUid)
       
  1694 	{
       
  1695 	NotifierCancel(aNotifierUid);
       
  1696 	}
       
  1697 
       
  1698 void CNotifierManager::UpdateNotifierL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
       
  1699 	{
       
  1700 	NotifierUpdateL(aNotifierUid,aBuffer,&aResponse,KNullClientId);
       
  1701 	}
       
  1702 
       
  1703 //
       
  1704 // class CChannelMonitor
       
  1705 //
       
  1706 
       
  1707 CChannelMonitor* CChannelMonitor::NewL()
       
  1708 	{
       
  1709 	CChannelMonitor* self=new(ELeave) CChannelMonitor;
       
  1710 	return self;
       
  1711 	}
       
  1712 
       
  1713 TBool CChannelMonitor::AlreadyHasChannel(TUid aChannel)const
       
  1714 	{
       
  1715 	const TInt count=iMonitor.Count();
       
  1716 	for (TInt ii=0;ii<count;ii++)
       
  1717 		{
       
  1718 		if (iMonitor[ii].iChannel==aChannel)
       
  1719 			return ETrue;
       
  1720 		}
       
  1721 	return EFalse;
       
  1722 	}
       
  1723 
       
  1724 TInt CChannelMonitor::ActivityLevel(TUid aChannel) const
       
  1725 	{
       
  1726 	const TInt count=iMonitor.Count();
       
  1727 	for (TInt ii=0;ii<count;ii++)
       
  1728 		{
       
  1729 		TChannelActivity activity=iMonitor[ii];
       
  1730 		if (activity.iChannel==aChannel)
       
  1731 			return activity.iHighestPriorityRunning;
       
  1732 		}
       
  1733 	return 0;
       
  1734 	}
       
  1735 
       
  1736 void CChannelMonitor::UpdateChannel(TUid aChannel,TInt aLevel)
       
  1737 	{
       
  1738 	const TInt count=iMonitor.Count();
       
  1739 	for (TInt ii=0;ii<count;ii++)
       
  1740 		{
       
  1741 		TChannelActivity& activity=iMonitor[ii];
       
  1742 		if (activity.iChannel==aChannel)
       
  1743 			{
       
  1744 			activity.iHighestPriorityRunning=aLevel;
       
  1745 			break;
       
  1746 			}
       
  1747 		}
       
  1748 	}
       
  1749 
       
  1750 CChannelMonitor::CChannelMonitor()
       
  1751 	:iMonitor(3)
       
  1752 	{}
       
  1753 
       
  1754 //
       
  1755 // class CNotifierActivity
       
  1756 //
       
  1757 
       
  1758 CNotifierActivity* CNotifierActivity::NewLC(const MNotifierBase2::TNotifierInfo& aInfo,TInt aClientId)
       
  1759 	{ // static
       
  1760 	CNotifierActivity* self=new(ELeave) CNotifierActivity(aInfo);
       
  1761 	CleanupStack::PushL(self);
       
  1762 	self->ConstructL(aClientId);
       
  1763 	return self;
       
  1764 	}
       
  1765 
       
  1766 CNotifierActivity::~CNotifierActivity()
       
  1767 	{
       
  1768 	iClientArray.Reset();
       
  1769 	}
       
  1770 
       
  1771 TInt CNotifierActivity::Find(TInt aClientId) const
       
  1772 	{
       
  1773 	TInt index=KErrNotFound;
       
  1774 	const TInt count=iClientArray.Count();
       
  1775 	for (TInt ii=0;ii<count;ii++)
       
  1776 		{
       
  1777 		TInt clientId=iClientArray[ii];
       
  1778 		if (clientId==aClientId)
       
  1779 			{
       
  1780 			index=ii;
       
  1781 			break;
       
  1782 			}
       
  1783 		}
       
  1784 	return index;
       
  1785 	}
       
  1786 
       
  1787 CNotifierActivity::CNotifierActivity(const MNotifierBase2::TNotifierInfo& aInfo)
       
  1788 	: iInfo(aInfo), iClientArray(1)
       
  1789 	{}
       
  1790 
       
  1791 void CNotifierActivity::ConstructL(TInt aClientId)
       
  1792 	{
       
  1793 	iClientArray.AppendL(aClientId);
       
  1794 	}
       
  1795 
       
  1796 //
       
  1797 // class CActivityMonitor
       
  1798 //
       
  1799 
       
  1800 CActivityMonitor* CActivityMonitor::NewL()
       
  1801 	{ // static
       
  1802 	CActivityMonitor* self=new(ELeave) CActivityMonitor();
       
  1803 	return self;
       
  1804 	}
       
  1805 
       
  1806 CActivityMonitor::~CActivityMonitor()
       
  1807 	{
       
  1808 	iMonitor.ResetAndDestroy();
       
  1809 	}
       
  1810 
       
  1811 void CActivityMonitor::AddL(const MNotifierBase2::TNotifierInfo& aInfo,TInt aClientId)
       
  1812 	{
       
  1813 	const TInt index=Find(aInfo.iUid,aInfo.iChannel);
       
  1814 	if (index==KErrNotFound)
       
  1815 		{
       
  1816 		CNotifierActivity* activity=CNotifierActivity::NewLC(aInfo,aClientId);
       
  1817 		iMonitor.AppendL(activity);
       
  1818 		CleanupStack::Pop(); // activity
       
  1819 		}
       
  1820 	else
       
  1821 		{
       
  1822 		iMonitor[index]->iClientArray.AppendL(aClientId);
       
  1823 		}
       
  1824 	}
       
  1825 
       
  1826 void CActivityMonitor::Remove(TUid aNotifierUid,TInt aClientId)
       
  1827 	{
       
  1828 	const TInt index=Find(aNotifierUid);
       
  1829 	if (index!=KErrNotFound)
       
  1830 		{
       
  1831 		CNotifierActivity* activity=iMonitor[index];
       
  1832 		const TInt clientIndex=activity->Find(aClientId);
       
  1833 		if (clientIndex!=KErrNotFound)
       
  1834 			{
       
  1835 			if (activity->iClientArray.Count()==1)
       
  1836 				{
       
  1837 				delete activity;
       
  1838 				iMonitor.Delete(index);
       
  1839 				}
       
  1840 			else
       
  1841 				{
       
  1842 				activity->iClientArray.Delete(index);
       
  1843 				}
       
  1844 			}
       
  1845 		}
       
  1846 	}
       
  1847 
       
  1848 void CActivityMonitor::RemoveNotifier(TUid aNotifierUid,TUid aChannel)
       
  1849 	{
       
  1850 	const TInt index=Find(aNotifierUid,aChannel);
       
  1851 	if (index!=KErrNotFound)
       
  1852 		{
       
  1853 		delete iMonitor[index];
       
  1854 		iMonitor.Delete(index);
       
  1855 		}
       
  1856 	}
       
  1857 
       
  1858 void CActivityMonitor::RemoveClient(TInt aClientId)
       
  1859 	{
       
  1860 	TInt ii=0;
       
  1861 	while (ii<iMonitor.Count())
       
  1862 		{
       
  1863 		CNotifierActivity* ptr=iMonitor[ii];
       
  1864 		TInt index=ptr->Find(aClientId);
       
  1865 		if (index!=KErrNotFound)
       
  1866 			{
       
  1867 			ptr->iClientArray.Delete(index);
       
  1868 			}
       
  1869 		if (ptr->iClientArray.Count()==0)
       
  1870 			{
       
  1871 			iMonitor.Delete(ii);
       
  1872 			}
       
  1873 		else
       
  1874 			{
       
  1875 			++ii;
       
  1876 			}
       
  1877 		}
       
  1878 	}
       
  1879 
       
  1880 TBool CActivityMonitor::IsNotifierActive(TUid aNotifierUid,TUid aChannel) const
       
  1881 	{
       
  1882 	const TInt index=Find(aNotifierUid,aChannel);
       
  1883 	return (index!=KErrNotFound);
       
  1884 	}
       
  1885 
       
  1886 TBool CActivityMonitor::IsClientPresent(TUid aNotifierUid,TUid aChannel,TInt aClientId) const
       
  1887 	{
       
  1888 	TBool found=EFalse;
       
  1889 	const TInt index=Find(aNotifierUid,aChannel);
       
  1890 	if (index!=KErrNotFound)
       
  1891 		{
       
  1892 		found=(iMonitor[index]->Find(aClientId)!=KErrNotFound);
       
  1893 		}
       
  1894 	return found;
       
  1895 	}
       
  1896 
       
  1897 TBool CActivityMonitor::IsChannelActive(TUid aChannel,TUid& aNotifier,MNotifierBase2::TNotifierPriority& aHighestPriority) const
       
  1898 	{
       
  1899 	TBool ret=EFalse;
       
  1900 	const TInt count=iMonitor.Count();
       
  1901 	for (TInt ii=0;ii<count;ii++)
       
  1902 		{
       
  1903 		MNotifierBase2::TNotifierInfo info=iMonitor[ii]->iInfo;
       
  1904 		if (info.iChannel==aChannel)
       
  1905 			{
       
  1906 			ret=ETrue;
       
  1907 			if ((MNotifierBase2::TNotifierPriority)info.iPriority>aHighestPriority)
       
  1908 				{
       
  1909 				aNotifier=info.iUid;
       
  1910 				aHighestPriority=(MNotifierBase2::TNotifierPriority)info.iPriority;
       
  1911 				}
       
  1912 			}
       
  1913 		}
       
  1914 	return ret;
       
  1915 	}
       
  1916 
       
  1917 TBool CActivityMonitor::NotifierForClient(TUid& aNotifierUid,TInt aClientId) const
       
  1918 	{
       
  1919 	TBool isOnlyClient=EFalse;
       
  1920 	aNotifierUid=KNullUid;
       
  1921 	const TInt count=iMonitor.Count();
       
  1922 	for (TInt ii=0;ii<count;ii++)
       
  1923 		{
       
  1924 		CNotifierActivity* ptr=iMonitor[ii];
       
  1925 		if (ptr->Find(aClientId)!=KErrNotFound)
       
  1926 			{
       
  1927 			aNotifierUid=ptr->iInfo.iUid;
       
  1928 			isOnlyClient=ptr->iClientArray.Count()==1;
       
  1929 			break;
       
  1930 			}
       
  1931 		}
       
  1932 	return isOnlyClient;
       
  1933 	}
       
  1934 
       
  1935 CActivityMonitor::CActivityMonitor()
       
  1936 	: iMonitor(1)
       
  1937 	{}
       
  1938 
       
  1939 TInt CActivityMonitor::Find(TUid aNotifierUid) const
       
  1940 	{
       
  1941 	TInt index=KErrNotFound;
       
  1942 	const TInt count=iMonitor.Count();
       
  1943 	for (TInt ii=0;ii<count;ii++)
       
  1944 		{
       
  1945 		if (iMonitor[ii]->iInfo.iUid==aNotifierUid)
       
  1946 			{
       
  1947 			index=ii;
       
  1948 			break;
       
  1949 			}
       
  1950 		}
       
  1951 	return index;
       
  1952 	}
       
  1953 
       
  1954 TInt CActivityMonitor::Find(TUid aNotifierUid,TUid aChannel) const
       
  1955 	{
       
  1956 	TInt index=KErrNotFound;
       
  1957 	const TInt count=iMonitor.Count();
       
  1958 	for (TInt ii=0;ii<count;ii++)
       
  1959 		{
       
  1960 		CNotifierActivity* ptr=iMonitor[ii];
       
  1961 		if (ptr->iInfo.iUid==aNotifierUid && ptr->iInfo.iChannel==aChannel)
       
  1962 			{
       
  1963 			index=ii;
       
  1964 			break;
       
  1965 			}
       
  1966 		}
       
  1967 	return index;
       
  1968 	}
       
  1969 
       
  1970 //
       
  1971 // class CQueueItem
       
  1972 //
       
  1973 
       
  1974 CQueueItem* CQueueItem::NewL(const MNotifierBase2::TNotifierInfo& aInfo,const TDesC8& aBuffer,
       
  1975 									TInt aReplySlot,const RMessage2& aMessage,TInt aClientId) //Asynchronous
       
  1976 	{
       
  1977 	CQueueItem* self=new(ELeave) CQueueItem(aInfo);
       
  1978 	CleanupStack::PushL(self);
       
  1979 	self->ConstructL(aBuffer,aMessage,aClientId,aReplySlot);
       
  1980 	CleanupStack::Pop(); // self
       
  1981 	return self;
       
  1982 	}
       
  1983 
       
  1984 CQueueItem* CQueueItem::NewL(const MNotifierBase2::TNotifierInfo& aInfo,const TDesC8& aBuffer,TInt aClientId) //synchronous
       
  1985 	{
       
  1986 	CQueueItem* self=new(ELeave) CQueueItem(aInfo);
       
  1987 	CleanupStack::PushL(self);
       
  1988 	self->ConstructL(aBuffer,aClientId);
       
  1989 	CleanupStack::Pop(); // self
       
  1990 	return self;
       
  1991 	}
       
  1992 
       
  1993 CQueueItem::~CQueueItem()
       
  1994 	{
       
  1995 	delete iBuffer;
       
  1996 	}
       
  1997 
       
  1998 CQueueItem::CQueueItem(const MNotifierBase2::TNotifierInfo& aInfo)
       
  1999 	: iInfo(aInfo)
       
  2000 	{}
       
  2001 
       
  2002 void CQueueItem::ConstructL(const TDesC8& aBuffer,TInt aClientId)
       
  2003 	{
       
  2004 	iBuffer=aBuffer.AllocL();
       
  2005 	iClientId=aClientId;
       
  2006 	iAsynchronous=EFalse;
       
  2007 	}
       
  2008 
       
  2009 void CQueueItem::ConstructL(const TDesC8& aBuffer,const RMessage2& aMessage,TInt aClientId,TInt aReplySlot)
       
  2010 	{
       
  2011 	iBuffer=aBuffer.AllocL();
       
  2012 	iAsynchronous=ETrue;
       
  2013 	iMessage=aMessage;
       
  2014 	iClientId=aClientId;
       
  2015 	iReplySlot=aReplySlot;
       
  2016 	}
       
  2017 
       
  2018 //
       
  2019 // class CNotifierQueue
       
  2020 //
       
  2021 
       
  2022 CNotifierQueue* CNotifierQueue::NewL()
       
  2023 	{
       
  2024 	CNotifierQueue* self=new(ELeave) CNotifierQueue;
       
  2025 	return self;
       
  2026 	}
       
  2027 
       
  2028 CQueueItem* CNotifierQueue::FetchItem(TUid aChannel)
       
  2029 	{
       
  2030 	CQueueItem* result=NULL;
       
  2031 	const TInt count=iQueue.Count();
       
  2032 	TInt priority=MNotifierBase2::ENotifierPriorityLowest-1;
       
  2033 	TInt index=KErrNotFound;
       
  2034 	for (TInt ii=0;ii<count;ii++)
       
  2035 		{
       
  2036 		CQueueItem* item=iQueue[ii];
       
  2037 		if (item->iInfo.iChannel==aChannel && item->iInfo.iPriority>priority)
       
  2038 			{
       
  2039 			index=ii;
       
  2040 			priority=item->iInfo.iPriority;
       
  2041 			result=item;
       
  2042 			}
       
  2043 		}
       
  2044 	if (index!=KErrNotFound)
       
  2045 		{
       
  2046 		iQueue.Delete(index);
       
  2047 		}
       
  2048 	return result;
       
  2049 	}
       
  2050 
       
  2051 TBool CNotifierQueue::IsAlreadyQueued(TUid aNotifier,TUid aChannel) const
       
  2052 	{
       
  2053 	TBool ret=EFalse;
       
  2054 	const TInt count=iQueue.Count();
       
  2055 	for (TInt ii=0;ii<count;ii++)
       
  2056 		{
       
  2057 		CQueueItem* item=iQueue[ii];
       
  2058 		if (item->iInfo.iUid==aNotifier && item->iInfo.iChannel==aChannel)
       
  2059 			{
       
  2060 			ret=ETrue;
       
  2061 			break;
       
  2062 			}
       
  2063 		}
       
  2064 	return ret;
       
  2065 	}
       
  2066 
       
  2067 void CNotifierQueue::RemoveClient(TInt aClientId)
       
  2068 	{
       
  2069 	const TInt count=iQueue.Count();
       
  2070 	for (TInt ii=count-1;ii>=0;ii--)
       
  2071 		{
       
  2072 		CQueueItem* item=iQueue[ii];
       
  2073 		TInt clientId=item->iClientId;
       
  2074 		if (clientId==aClientId)
       
  2075 			{
       
  2076 			iQueue.Delete(ii);
       
  2077 			}
       
  2078 		}
       
  2079 	}
       
  2080 
       
  2081 
       
  2082 TInt CNotifierQueue::GetHighestQueuePriority(TUid aChannel)
       
  2083 	{
       
  2084 	const TInt count=iQueue.Count();
       
  2085 	TInt priority=MNotifierBase2::ENotifierPriorityLowest-1;
       
  2086 
       
  2087 	for (TInt ii=0;ii<count;ii++)
       
  2088 		{
       
  2089 		CQueueItem* item=iQueue[ii];
       
  2090 		if (item->iInfo.iChannel==aChannel && item->iInfo.iPriority>priority)
       
  2091 			{
       
  2092 			priority=item->iInfo.iPriority;
       
  2093 			}
       
  2094 		}
       
  2095 
       
  2096 	return priority;
       
  2097 	}
       
  2098 
       
  2099 
       
  2100 void CWsActiveScheduler::New()
       
  2101 //
       
  2102 // Create and install the active scheduler.
       
  2103 //
       
  2104 	{
       
  2105 
       
  2106 	CWsActiveScheduler *pA=new CWsActiveScheduler;
       
  2107 	__ASSERT_ALWAYS(pA!=NULL,Fault(ECreateScheduler));
       
  2108 	CActiveScheduler::Install(pA);
       
  2109 	}
       
  2110 
       
  2111 void CWsActiveScheduler::Error(TInt) const
       
  2112 //
       
  2113 // Called if any Run() method leaves.
       
  2114 //
       
  2115 	{
       
  2116 	}
       
  2117 
       
  2118 
       
  2119 TInt NotifierServerThread(TAny*)
       
  2120 	{
       
  2121 	CTrapCleanup* CleanUpStack=CTrapCleanup::New();
       
  2122 	CWsActiveScheduler::New();
       
  2123 	TRAP_IGNORE(CNotifierServer::NewL());
       
  2124 	CNotifierSession::NotifierSemaphore.Signal();
       
  2125 	CWsActiveScheduler::Start();
       
  2126 	delete CleanUpStack;
       
  2127 	return(0);
       
  2128 	}
       
  2129 
       
  2130 
       
  2131 _LIT(KLitKeyDataDllNameBase, "EKDATA");
       
  2132 _LIT(TwoDigExt,".%02d");
       
  2133 
       
  2134 GLDEF_C TInt E32Main()
       
  2135 	{
       
  2136 	UserSvr::WsRegisterThread();
       
  2137 	UserSvr::WsRegisterSwitchOnScreenHandling(ETrue);
       
  2138 	User::SetProcessCritical(User::ESystemPermanent);
       
  2139 	User::SetCritical(User::ESystemPermanent);
       
  2140 
       
  2141 	CWsActiveScheduler::New();
       
  2142 	CWsServer::New();
       
  2143 	CWsWindow::New();
       
  2144 	CEvent::New();
       
  2145     
       
  2146 	KeyTranslator=CKeyTranslator::New();
       
  2147 	if (!KeyTranslator)
       
  2148 		Fault(ENoKeyboardTranslator);
       
  2149 
       
  2150 //  Change keyboard mapping according to information in the HAL
       
  2151 //	This code is the same as WSERV
       
  2152 	TInt keyboardIndex;
       
  2153 	if (HAL::Get(HALData::EKeyboardIndex,keyboardIndex)==KErrNone)
       
  2154 		{
       
  2155 		TBuf<16> keyDataDllName(KLitKeyDataDllNameBase);
       
  2156 		keyDataDllName.AppendFormat(TwoDigExt, keyboardIndex);
       
  2157 		KeyTranslator->ChangeKeyData(keyDataDllName);
       
  2158 		}
       
  2159 
       
  2160     KeyRepeat=new(ELeave) CKeyRepeat(CKeyRepeat::EKeyRepeatPriority);
       
  2161 	TRAPD(r,KeyRepeat->ConstructL());
       
  2162 	if (r!=KErrNone)
       
  2163 		User::Panic(_L("KEYREPEAT"),r);
       
  2164 
       
  2165 #ifndef __WINS__
       
  2166     if (UserSvr::TestBootSequence())
       
  2167 		{
       
  2168 		RDebug::Print(_L("WS_MAIN: TestBootSequence=TRUE, not loading ESHELL.EXE"));
       
  2169 		}
       
  2170 #else
       
  2171     if (EmulatorAutoRun())
       
  2172     	{	// don't start ESHELL if we used a self-bootstrapping EXE
       
  2173     	}
       
  2174 #endif
       
  2175 	else
       
  2176 		{
       
  2177 		RProcess shell;
       
  2178 		r=shell.Create(KShellProcessName, KShellCommandLine);
       
  2179 		__ASSERT_ALWAYS(r==KErrNone,Fault(ECreateShell));
       
  2180 		shell.Resume();
       
  2181 		shell.Close();
       
  2182 		}
       
  2183 
       
  2184 	RThread t;
       
  2185 	r=CNotifierSession::NotifierSemaphore.CreateLocal(0);
       
  2186 	if (r!=KErrNone)
       
  2187 		Fault(ECreateNotifierSemaphore);
       
  2188 	r=t.Create(_L("NotifierServer"),NotifierServerThread,KDefaultStackSize,0x2000,0x100000,NULL);
       
  2189 	if (r!=KErrNone)
       
  2190 		Fault(ECreateNotifierThread);
       
  2191 	t.Resume();
       
  2192 	CNotifierSession::NotifierSemaphore.Wait();
       
  2193 
       
  2194 	CWsActiveScheduler::Start();
       
  2195 	UserSvr::ReleaseEventHook();
       
  2196 	return(KErrNone);
       
  2197 	}
       
  2198