1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/ewsrv/ws_main.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,2198 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\ewsrv\ws_main.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "ws_std.h"
1.22 +#include <e32hal.h>
1.23 +#include <hal.h>
1.24 +#include <e32math.h>
1.25 +#include <domainmanager.h>
1.26 +#ifdef __WINS__
1.27 +#include <e32wins.h>
1.28 +#endif
1.29 +
1.30 +GLREF_D CKeyTranslator *KeyTranslator;
1.31 +GLREF_D CKeyRepeat* KeyRepeat;
1.32 +
1.33 +// password notifier support functions
1.34 +LOCAL_C void RenderPassword(RConsole *aCon, TInt aPWLeft, const TDesC& aPW);
1.35 +
1.36 +_LIT(KShellProcessName, "ESHELL");
1.37 +_LIT(KShellCommandLine, "/p");
1.38 +
1.39 +//
1.40 +// class CKeyRepeat
1.41 +//
1.42 +
1.43 +CKeyRepeat::CKeyRepeat(TInt aPriority) : CTimer(aPriority)
1.44 +//
1.45 +// Constructor. Set default repeat delay and rate
1.46 +//
1.47 + {
1.48 + iDelay=EDefaultKeyRepeatDelay;
1.49 + iRate=EDefaultKeyRepeatRate;
1.50 + }
1.51 +
1.52 +void CKeyRepeat::ConstructL()
1.53 + {
1.54 +
1.55 + CTimer::ConstructL();
1.56 + CActiveScheduler::Add(this);
1.57 + }
1.58 +
1.59 +void CKeyRepeat::RunL()
1.60 +//
1.61 +// Send a repeat keypress to the window
1.62 +//
1.63 + {
1.64 +
1.65 + After(iRate);
1.66 + CWsWindow::KeyPress(iKeyData);
1.67 + }
1.68 +
1.69 +void CKeyRepeat::Request(TKeyData& aKeyData)
1.70 +//
1.71 +// Request a repeat event
1.72 +//
1.73 + {
1.74 +
1.75 + iKeyData=aKeyData;
1.76 + Cancel();
1.77 + After(iDelay);
1.78 + }
1.79 +
1.80 +void CKeyRepeat::SetRepeatTime(TInt aDelay,TInt aRate)
1.81 + {
1.82 +
1.83 + iDelay=aDelay;
1.84 + iRate=aRate;
1.85 + }
1.86 +
1.87 +void CKeyRepeat::RepeatTime(TInt& aDelay,TInt& aRate)
1.88 + {
1.89 +
1.90 + aDelay=iDelay;
1.91 + aRate=iRate;
1.92 + }
1.93 +
1.94 +//
1.95 +// class CWsSession
1.96 +//
1.97 +
1.98 +CWsSession::CWsSession()
1.99 + {
1.100 + iTestFast = (UserSvr::DebugMask(2)&0x00000002) ? 1 : 0;
1.101 + }
1.102 +
1.103 +CWsSession::~CWsSession()
1.104 +//
1.105 +// Destructor
1.106 +//
1.107 + {
1.108 +
1.109 + delete iWindow;
1.110 + }
1.111 +
1.112 +//
1.113 +// class CWsServer
1.114 +//
1.115 +
1.116 +void CWsServer::New()
1.117 +//
1.118 +// Create a new CWsServer.
1.119 +//
1.120 + {
1.121 +
1.122 + CWsServer *pS=new CWsServer(EPriority);
1.123 + __ASSERT_ALWAYS(pS!=NULL,Fault(ECreateServer));
1.124 + pS->SetPinClientDescriptors(EFalse); // don't pin because client interface can't cope with errors if pin fails under real or simulated OOM
1.125 + TInt r=pS->Start(KE32WindowServer);
1.126 + __ASSERT_ALWAYS(r==KErrNone,Fault(EStartServer));
1.127 + RProcess::Rendezvous(KErrNone);
1.128 +
1.129 + }
1.130 +
1.131 +CWsServer::CWsServer(TInt aPriority)
1.132 +//
1.133 +// Constructor.
1.134 +//
1.135 + : CServer2(aPriority)
1.136 + {
1.137 + }
1.138 +
1.139 +CSession2* CWsServer::NewSessionL(const TVersion& aVersion,const RMessage2&) const
1.140 +//
1.141 +// Create a new client for this server.
1.142 +//
1.143 + {
1.144 +
1.145 + TVersion v(KW32MajorVersionNumber,KW32MinorVersionNumber,KE32BuildVersionNumber);
1.146 + TBool r=User::QueryVersionSupported(v,aVersion);
1.147 + if (!r)
1.148 + User::Leave(KErrNotSupported);
1.149 + return new(ELeave) CWsSession;
1.150 + }
1.151 +
1.152 +void CWsSession::ServiceL(const RMessage2& aMessage)
1.153 +//
1.154 +// Handle messages for this session.
1.155 +//
1.156 + {
1.157 +
1.158 + iCurMsg = aMessage;
1.159 + CWsWindow::WaitOnService();
1.160 + CWsWindow* pW=iWindow;
1.161 + TInt r=EPrematureOperation;
1.162 + TBool delayCompletion=EFalse;
1.163 + switch (aMessage.Function())
1.164 + {
1.165 + case EConsoleCreate:
1.166 + {
1.167 + if (pW)
1.168 + {
1.169 + delete pW;
1.170 + iWindow=NULL;
1.171 + }
1.172 + pW=new CWsWindow;
1.173 + if (!pW)
1.174 + {
1.175 + r=EWindowOutOfMemory;
1.176 + break;
1.177 + }
1.178 + iWindow=pW;
1.179 + pW->iAllowResize=ETrue;
1.180 + pW->iIsVisible=ETrue;
1.181 + pW->iOnTop=EFalse;
1.182 + pW->SetCursorHeight(50);
1.183 + pW->iKQueue.SetOffset(_FOFF(SWsKey,iLink));
1.184 + break;
1.185 + }
1.186 + case EConsoleSet:
1.187 + {
1.188 + if (!pW)
1.189 + {
1.190 + pW=new(ELeave) CWsWindow;
1.191 + iWindow=pW;
1.192 + pW->iAllowResize=ETrue;
1.193 + pW->iIsVisible=ETrue;
1.194 + pW->iOnTop=EFalse;
1.195 + pW->SetCursorHeight(50);
1.196 + pW->iKQueue.SetOffset(_FOFF(SWsKey,iLink));
1.197 + }
1.198 + pW->iAllowSlide=ETrue;
1.199 + TFileName name;
1.200 + iCurMsg.ReadL(0, name);
1.201 + pW->iTitle=name;
1.202 + TPckgBuf<TSize> size;
1.203 + iCurMsg.ReadL(1, size);
1.204 + TRAP(r,pW->CreateL(size()));
1.205 + if (r != KErrNone)
1.206 + {
1.207 + delete pW;
1.208 + iWindow=NULL;
1.209 + }
1.210 + break;
1.211 + }
1.212 + case EConsoleClearScreen:
1.213 + {
1.214 + if (pW)
1.215 + {
1.216 + pW->Clear();
1.217 + r=KErrNone;
1.218 + }
1.219 + break;
1.220 + }
1.221 + case EConsoleClearToEndOfLine:
1.222 + {
1.223 + if (pW)
1.224 + {
1.225 + pW->ClearToEndOfLine();
1.226 + r=KErrNone;
1.227 + }
1.228 + break;
1.229 + }
1.230 + case EConsoleSetTitle:
1.231 + {
1.232 + if (pW)
1.233 + {
1.234 + TFileName name;
1.235 + iCurMsg.ReadL(0, name);
1.236 + pW->SetTitle(name);
1.237 + r=KErrNone;
1.238 + }
1.239 + break;
1.240 + }
1.241 + case EConsoleSetSize:
1.242 + {
1.243 + if (pW)
1.244 + {
1.245 + TPckgBuf<TSize> size;
1.246 + iCurMsg.ReadL(0, size);
1.247 +// pW->SetSize(size());
1.248 +// r=KErrNone;
1.249 + r=KErrNotSupported;
1.250 + }
1.251 + break;
1.252 + }
1.253 + case EConsoleSetWindowPosAbs:
1.254 + {
1.255 + if (pW)
1.256 + {
1.257 + TPckgBuf<TPoint> point;
1.258 + iCurMsg.ReadL(0, point);
1.259 + pW->SetWindowPosAbs(point());
1.260 + r=KErrNone;
1.261 + }
1.262 + break;
1.263 + }
1.264 + case EConsoleSetCursorHeight:
1.265 + {
1.266 + if (pW)
1.267 + {
1.268 + pW->SetCursorHeight(aMessage.Int0());
1.269 + r=KErrNone;
1.270 + }
1.271 + break;
1.272 + }
1.273 + case EConsoleSetCursorPosAbs:
1.274 + {
1.275 + if (pW)
1.276 + {
1.277 + TPckgBuf<TPoint> point;
1.278 + iCurMsg.ReadL(0, point);
1.279 + pW->SetCursorPosAbs(point());
1.280 + r=KErrNone;
1.281 + }
1.282 + break;
1.283 + }
1.284 + case EConsoleSetCursorPosRel:
1.285 + {
1.286 + if (pW)
1.287 + {
1.288 + TPckgBuf<TPoint> point;
1.289 + iCurMsg.ReadL(0, point);
1.290 + pW->SetCursorPosRel(point());
1.291 + r=KErrNone;
1.292 + }
1.293 + break;
1.294 + }
1.295 + case EConsoleCursorPos:
1.296 + {
1.297 + if (pW)
1.298 + {
1.299 + TPckgBuf<TPoint> point;
1.300 + point()=pW->CursorPosition();
1.301 + aMessage.WriteL(0,point);
1.302 + r=KErrNone;
1.303 + }
1.304 + break;
1.305 + }
1.306 + case EConsoleSize:
1.307 + {
1.308 + if (pW)
1.309 + {
1.310 + TPckgBuf<TSize> size;
1.311 + size()=pW->Size();
1.312 + aMessage.WriteL(0,size);
1.313 + r=KErrNone;
1.314 + }
1.315 + break;
1.316 + }
1.317 + case EConsoleScreenSize:
1.318 + {
1.319 + if (pW)
1.320 + {
1.321 + TPckgBuf<TSize> size;
1.322 + size()=CWsWindow::ScreenSize;
1.323 + aMessage.WriteL(0,size);
1.324 + r=KErrNone;
1.325 + }
1.326 + break;
1.327 + }
1.328 + case EConsoleControl:
1.329 + {
1.330 + if (pW)
1.331 + {
1.332 + TBool indicator=ETrue;
1.333 + TInt offset=0;
1.334 + TBuf<0x100> b;
1.335 + do
1.336 + {
1.337 + iCurMsg.ReadL(0,b,offset);
1.338 + for (const TText* pB=b.Ptr();pB<b.Ptr()+b.Length();pB++)
1.339 + {
1.340 + switch(*pB)
1.341 + {
1.342 + case '+':
1.343 +
1.344 + indicator=ETrue;
1.345 + break;
1.346 + case '-':
1.347 + indicator=EFalse;
1.348 + break;
1.349 + case 'S':
1.350 + pW->ControlScrollBars(indicator);
1.351 + break;
1.352 + case 'W':
1.353 + pW->ControlWrapLock(indicator);
1.354 + break;
1.355 + case 'P':
1.356 + pW->ControlPointerEvents(indicator);
1.357 + break;
1.358 + case 'L':
1.359 + pW->ControlScrollLock(indicator);
1.360 + break;
1.361 + case 'V':
1.362 + pW->ControlVisibility(indicator);
1.363 + break;
1.364 + case 'C':
1.365 + pW->ControlCursorRequired(indicator);
1.366 + break;
1.367 + case 'M':
1.368 + pW->ControlMaximised(indicator);
1.369 + break;
1.370 + case 'N':
1.371 + pW->ControlNewLineMode(indicator);
1.372 + break;
1.373 + case 'O':
1.374 + pW->ControlOnTop(indicator);
1.375 + break;
1.376 + case 'I':
1.377 + pW->ControlInformAllMouse(indicator);
1.378 + break;
1.379 + case 'R':
1.380 + pW->ControlRawEventMode(indicator);
1.381 + break;
1.382 + case 'A':
1.383 + pW->ControlAllowResize(indicator);
1.384 + }
1.385 + }
1.386 + offset+=b.Length();
1.387 + }
1.388 + while (b.Length()==b.MaxLength());
1.389 + r=KErrNone;
1.390 + }
1.391 + break;
1.392 + }
1.393 + case EConsoleWrite:
1.394 + {
1.395 + if (pW)
1.396 + {
1.397 + switch(iTestFast)
1.398 + {
1.399 + case 0:
1.400 + {
1.401 + TInt offset=0;
1.402 + TBuf<0x100> b;
1.403 + do
1.404 + {
1.405 + iCurMsg.ReadL(0,b,offset);
1.406 + pW->Write(b);
1.407 + offset+=b.Length();
1.408 + }
1.409 + while (b.Length()==b.MaxLength());
1.410 + pW->WriteDone();
1.411 + }
1.412 + r=KErrNone;
1.413 + break;
1.414 +
1.415 + case 1:
1.416 + {
1.417 + pW->Write(_L("Output suppressed because TESTFAST mode is set..."));
1.418 + pW->WriteDone();
1.419 + ++iTestFast;
1.420 + }
1.421 + r=KErrNone;
1.422 + break;
1.423 +
1.424 + default:
1.425 + r=KErrNone;
1.426 + break;
1.427 + }
1.428 + }
1.429 + break;
1.430 + }
1.431 + case EConsoleRead:
1.432 + {
1.433 + if (pW)
1.434 + {
1.435 + if (pW->EnqueReadRequest(aMessage))
1.436 + {
1.437 + delayCompletion=ETrue;
1.438 + r=KErrNone;
1.439 + }
1.440 + else
1.441 + r=EDoubleReadRequest;
1.442 + }
1.443 + break;
1.444 + }
1.445 + case EConsoleReadCancel:
1.446 + {
1.447 + if (pW)
1.448 + {
1.449 + pW->DequeReadRequest();
1.450 + r=KErrNone;
1.451 + }
1.452 + break;
1.453 + }
1.454 + case EConsoleDestroy:
1.455 + {
1.456 + if (pW)
1.457 + {
1.458 + delete pW;
1.459 + iWindow=NULL;
1.460 + r=KErrNone;
1.461 + }
1.462 + break;
1.463 + }
1.464 + case EConsoleSetMode:
1.465 + {
1.466 + r=CWsWindow::SetMode((TVideoMode)aMessage.Int0());
1.467 + break;
1.468 + }
1.469 + case EConsoleSetPaletteEntry:
1.470 + {
1.471 + CWsWindow::ScreenDriver->SetPaletteEntry((TColorIndex)aMessage.Int0(),(TUint8)aMessage.Int1(),(TUint8)aMessage.Int2(),(TUint8)aMessage.Int3());
1.472 + pW->Redraw();
1.473 + r=KErrNone;
1.474 + break;
1.475 + }
1.476 + case EConsoleGetPaletteEntry:
1.477 + {
1.478 + TUint8 r,g,b;
1.479 + TPckgBuf<TUint8> red,green,blue;
1.480 + CWsWindow::ScreenDriver->GetPaletteEntry((TColorIndex)aMessage.Int0(),r,g,b);
1.481 + red()=r; green()=g; blue()=b;
1.482 + aMessage.WriteL(1,red);
1.483 + aMessage.WriteL(2,green);
1.484 + aMessage.WriteL(3,blue);
1.485 + }
1.486 + r=KErrNone;
1.487 + break;
1.488 + case EConsoleSetTextColors:
1.489 + {
1.490 + if(pW)
1.491 + {
1.492 + pW->iFgColor=(TColorIndex)aMessage.Int0();
1.493 + pW->iBgColor=(TColorIndex)aMessage.Int1();
1.494 + }
1.495 + r=KErrNone;
1.496 + break;
1.497 + }
1.498 + case EConsoleSetUIColors:
1.499 + {
1.500 + CWsWindow::WindowBgColor=(TColorIndex)aMessage.Int0();
1.501 + CWsWindow::BorderColor=(TColorIndex)aMessage.Int1();
1.502 + CWsWindow::ScreenColor=(TColorIndex)aMessage.Int2();
1.503 + CWsWindow::ChangeUIColors();
1.504 + r=KErrNone;
1.505 + break;
1.506 + }
1.507 + case EConsoleSetTextAttribute:
1.508 + {
1.509 + if(pW)
1.510 + pW->SetTextAttribute((TTextAttribute)aMessage.Int0());
1.511 + r=KErrNone;
1.512 + break;
1.513 + }
1.514 + default:
1.515 + r=KErrNotSupported;
1.516 + }
1.517 + if (!delayCompletion)
1.518 + aMessage.Complete(r);
1.519 + CWsWindow::SignalService();
1.520 + }
1.521 +
1.522 +void CWsSession::ServiceError(const RMessage2& aMessage,TInt aError)
1.523 + {
1.524 + if (!aMessage.IsNull())
1.525 + {
1.526 + if (aError>0)
1.527 + {
1.528 + aMessage.Panic(_L("WServ panic"),aError);
1.529 + }
1.530 + else
1.531 + {
1.532 + aMessage.Complete(aError);
1.533 + }
1.534 + }
1.535 + }
1.536 +
1.537 +CWsServer::~CWsServer()
1.538 +//
1.539 +// Destructor
1.540 +//
1.541 + {
1.542 + }
1.543 +
1.544 +//
1.545 +// class CEvent
1.546 +//
1.547 +
1.548 +void CEvent::New()
1.549 +//
1.550 +// Create the CEvent active object.
1.551 +//
1.552 + {
1.553 +
1.554 + CEvent *pE=new CEvent(EPriority);
1.555 + __ASSERT_ALWAYS(pE!=NULL,Fault(ECreateEvent));
1.556 + pE->CaptureKeys=new CCaptureKeys();
1.557 + __ASSERT_ALWAYS(pE->CaptureKeys!=NULL,Fault(ECreateEvent));
1.558 +
1.559 + pE->CaptureKeys->Construct();
1.560 +
1.561 + CActiveScheduler::Add(pE);
1.562 + UserSvr::CaptureEventHook();
1.563 + pE->Request();
1.564 + }
1.565 +
1.566 +CEvent::~CEvent()
1.567 +//
1.568 +// Destroy the CEvent active object
1.569 +//
1.570 + {
1.571 +
1.572 + Cancel();
1.573 + }
1.574 +
1.575 +#pragma warning( disable : 4705 ) // statement has no effect
1.576 +CEvent::CEvent(TInt aPriority)
1.577 +//
1.578 +// Constructor
1.579 +//
1.580 + : CActive(aPriority)
1.581 + {
1.582 + }
1.583 +#pragma warning( default : 4705 )
1.584 +
1.585 +void CEvent::Request()
1.586 +//
1.587 +// Issue a request for the next event.
1.588 +//
1.589 + {
1.590 +
1.591 + UserSvr::RequestEvent(iEvent,iStatus);
1.592 + SetActive();
1.593 + }
1.594 +
1.595 +void CEvent::DoCancel()
1.596 +//
1.597 +// Cancel a pending event.
1.598 +//
1.599 + {
1.600 +
1.601 + UserSvr::RequestEventCancel();
1.602 + }
1.603 +
1.604 +void CEvent::RunL()
1.605 +//
1.606 +// Event has completed.
1.607 +//
1.608 + {
1.609 +
1.610 + if (CWsWindow::RawEventMode())
1.611 + {
1.612 + KeyRepeat->Cancel();
1.613 + CWsWindow::QueueRawEvent(iEvent.Event());
1.614 + Request();
1.615 + return;
1.616 + }
1.617 + switch(iEvent.Event().Type())
1.618 + {
1.619 + case TRawEvent::ERedraw:
1.620 + CWsWindow::Redraw();
1.621 + break;
1.622 + case TRawEvent::EButton1Down:
1.623 + if(!CWsWindow::MouseIsCaptured)
1.624 + {
1.625 + CWsWindow::MouseMove(iEvent.Event().Pos());
1.626 + CWsWindow::MouseLeftButton();
1.627 + }
1.628 + else
1.629 + CWsWindow::InformTopMouse(iEvent.Event().Pos());
1.630 + break;
1.631 + case TRawEvent::EButton1Up:
1.632 + if(!CWsWindow::MouseIsCaptured)
1.633 + {
1.634 + CWsWindow::MouseMove(iEvent.Event().Pos());
1.635 + CWsWindow::MouseLeftButtonUp();
1.636 + }
1.637 + break;
1.638 + case TRawEvent::EButton2Down:
1.639 + break;
1.640 + case TRawEvent::EButton2Up:
1.641 + break;
1.642 + case TRawEvent::EButton3Down:
1.643 + break;
1.644 + case TRawEvent::EButton3Up:
1.645 + break;
1.646 + case TRawEvent::EPointerMove:
1.647 + CWsWindow::MouseMove(iEvent.Event().Pos());
1.648 + break;
1.649 + case TRawEvent::EInactive:
1.650 + KeyRepeat->Cancel();
1.651 + break;
1.652 + case TRawEvent::EActive:
1.653 + break;
1.654 + case TRawEvent::EUpdateModifiers:
1.655 + KeyTranslator->UpdateModifiers(iEvent.Event().Modifiers());
1.656 + break;
1.657 + case TRawEvent::EKeyDown:
1.658 + {
1.659 + TKeyData keyData;
1.660 + if (KeyTranslator->TranslateKey(iEvent.Event().ScanCode(), EFalse,*CaptureKeys,keyData))
1.661 + CWsWindow::KeyPress(keyData);
1.662 + if (keyData.iModifiers&EModifierAutorepeatable)
1.663 + KeyRepeat->Request(keyData);
1.664 + break;
1.665 + }
1.666 + case TRawEvent::EKeyUp:
1.667 + {
1.668 + TKeyData keyData;
1.669 + KeyRepeat->Cancel();
1.670 + if (KeyTranslator->TranslateKey(iEvent.Event().ScanCode(), ETrue,*CaptureKeys,keyData))
1.671 + CWsWindow::KeyPress(keyData);
1.672 + break;
1.673 + }
1.674 + case TRawEvent::ESwitchOn:
1.675 + case TRawEvent::ECaseOpen:
1.676 + HAL::Set(HAL::EDisplayState, 1);
1.677 + {
1.678 + RDmDomainManager mgr;
1.679 + TInt r = mgr.Connect();
1.680 + if (r != KErrNone)
1.681 + User::Panic(_L("EWSRV SwitchOn0"), r);
1.682 + TRequestStatus status;
1.683 + mgr.RequestDomainTransition(KDmIdUiApps, EPwActive, status);
1.684 + User::WaitForRequest(status);
1.685 + if (status.Int() != KErrNone)
1.686 + User::Panic(_L("EWSRV SwitchOn1"), status.Int());
1.687 + mgr.Close();
1.688 + }
1.689 + break;
1.690 + case TRawEvent::EPointerSwitchOn:
1.691 +#if defined(_DEBUG)
1.692 + User::Beep(440,250000);
1.693 +#endif
1.694 + break;
1.695 + case TRawEvent::ESwitchOff:
1.696 + {
1.697 + RDmDomainManager mgr;
1.698 + TInt r = mgr.Connect();
1.699 + if (r != KErrNone)
1.700 + User::Panic(_L("EWSRV SwitchOff0"), r);
1.701 + TRequestStatus status;
1.702 + mgr.RequestSystemTransition(EPwStandby, status);
1.703 + User::WaitForRequest(status);
1.704 + if (status.Int() != KErrNone)
1.705 + User::Panic(_L("EWSRV SwitchOff1"), status.Int());
1.706 + mgr.Close();
1.707 + }
1.708 + break;
1.709 + case TRawEvent::ECaseClose:
1.710 + {
1.711 + RDmDomainManager mgr;
1.712 + TInt r = mgr.Connect();
1.713 + if (r != KErrNone)
1.714 + User::Panic(_L("EWSRV CaseClosed"), r);
1.715 + TRequestStatus status;
1.716 + mgr.RequestDomainTransition(KDmIdUiApps, EPwStandby, status);
1.717 + User::WaitForRequest(status);
1.718 + if (status.Int() != KErrNone)
1.719 + User::Panic(_L("EWSRV CaseClosed1"), status.Int());
1.720 + mgr.Close();
1.721 + }
1.722 + HAL::Set(HAL::EDisplayState, 0);
1.723 + break;
1.724 + case TRawEvent::ENone:
1.725 + break;
1.726 + default:
1.727 + break;
1.728 + }
1.729 + Request();
1.730 + }
1.731 +
1.732 +LOCAL_C void RenderPassword(RConsole *aCon, TInt aPWLeft, const TDesC& aPW)
1.733 +// pre: aCon points to a console being used to read a password.
1.734 +// aPWLeft is the column number from which the left brace should be drawn.
1.735 +// aPasswd is a valid password.
1.736 +// post: the password is rendered onto the console and followed by a '#' and
1.737 +// padding spaces. Everything is enclosed in a pair of square brackets.
1.738 + {
1.739 + aCon->SetCursorPosAbs(TPoint(aPWLeft, 3));
1.740 + aCon->Write(_L("["));
1.741 + aCon->Write(aPW);
1.742 + aCon->Write(_L("#"));
1.743 +
1.744 + TInt i;
1.745 + for (i = 0; i < KMaxMediaPassword - aPW.Length(); i++)
1.746 + {
1.747 + aCon->Write(_L(" "));
1.748 + }
1.749 +
1.750 + aCon->Write(_L("]"));
1.751 + }
1.752 +
1.753 +
1.754 +void CNotifierSession::RunPasswordWindowL(const RMessage2 &aMsg)
1.755 +//
1.756 +// Eight unicode chars are mapped to (up to) sixteen bytes. Remainder of array is
1.757 +// zeroed. Message is completed in CNotifierSession::ServiceL().
1.758 +//
1.759 + {
1.760 + // local copies of dialog data, 5 * (8 + 32 * 2) bytes
1.761 + TBuf<0x20> line1, line2, unlockBtn, storeBtn, cancelBtn;
1.762 + line1.Copy(_L("Password notifier"));
1.763 + line2.Copy(_L("Enter password"));
1.764 + unlockBtn.Copy(_L("Unlock"));
1.765 + storeBtn.Copy(_L("Store"));
1.766 + cancelBtn.Copy(_L("Cancel"));
1.767 +
1.768 + TPckgBuf<TMediaPswdReplyNotifyInfoV1> reply;
1.769 +
1.770 + // Format the console window.
1.771 +
1.772 + const TInt KPasswordBarLen(1 + KMaxMediaPassword + 1 + 1);
1.773 + const TInt KButtonBarLen(
1.774 + 1 + unlockBtn.Length() + 1
1.775 + + 1 + 1 + cancelBtn.Length() + 1
1.776 + + 1 + 1 + storeBtn.Length() + 1);
1.777 +
1.778 + // Work out width of window.
1.779 + // (Buttons are enclosed by angle brackets and separted by a space.)
1.780 + // (Password is followed by '#' and delimited by square brackets.)
1.781 + // If KButtonBarLen is at least as long as any other line then it will write
1.782 + // to the bottom right corner and cause the console to scroll. To counter
1.783 + // this, an extra padding character is added if necessary.
1.784 +
1.785 + TInt width;
1.786 + width = Max(line1.Length(), line2.Length());
1.787 + width = Max(width, KPasswordBarLen);
1.788 + width = KButtonBarLen >= width ? KButtonBarLen + 1: width;
1.789 +
1.790 + // Create the window and render its contents.
1.791 +
1.792 + RConsole con;
1.793 + con.Create();
1.794 + con.Control(_L("-Visible"));
1.795 + TInt r = con.Init(_L(""), TSize(width, 2 + 1 + 1 + 1 + 1));
1.796 + if (KErrNone != r)
1.797 + {
1.798 + PanicClient(aMsg, ENotifierPanicPasswordWindow);
1.799 + User::Leave(KErrGeneral);
1.800 + }
1.801 + con.Control(_L("+Max -Cursor -AllowResize +OnTop"));
1.802 +
1.803 + con.SetCursorPosAbs(TPoint(0, 0));
1.804 + con.Write(line1);
1.805 + con.SetCursorPosAbs(TPoint(0, 1));
1.806 + con.Write(line2);
1.807 + const TInt KPasswordLeft((width - KPasswordBarLen) / 2);
1.808 + con.SetCursorPosAbs(TPoint(KPasswordLeft, 3));
1.809 + con.Write(_L("[# ]"));
1.810 + con.SetCursorPosAbs(TPoint((width - KButtonBarLen) / 2, 5));
1.811 + con.Write(_L("<"));
1.812 + con.Write(unlockBtn);
1.813 + con.Write(_L("> <"));
1.814 + con.Write(storeBtn);
1.815 + con.Write(_L("> <"));
1.816 + con.Write(cancelBtn);
1.817 + con.Write(_L(">"));
1.818 +
1.819 + // Allow the user to edit the password until they either press enter or escape.
1.820 +
1.821 + TBool done(EFalse);
1.822 + TBuf<KMaxMediaPassword> pw;
1.823 + pw.Zero();
1.824 + TMediaPswdNotifyExitMode em(EMPEMUnlock); // avoid VC warning C4701 (used w/o init).
1.825 +
1.826 + const TInt sendInfoLen = User::LeaveIfError(aMsg.GetDesLength(1));
1.827 +
1.828 + if (sendInfoLen == sizeof(TMediaPswdSendNotifyInfoV1Debug))
1.829 + {
1.830 + // debug mode - wait for specified period and close notifier
1.831 +
1.832 + TPckgBuf<TMediaPswdSendNotifyInfoV1Debug> sendDbg;
1.833 + aMsg.ReadL(1, sendDbg);
1.834 + if (sendDbg().iSleepPeriod >= 0)
1.835 + User::After(sendDbg().iSleepPeriod);
1.836 + else
1.837 + {
1.838 + TTime now;
1.839 + now.HomeTime();
1.840 + TInt64 seed = now.Int64();
1.841 + User::After(Math::Rand(seed) % -(sendDbg().iSleepPeriod));
1.842 + }
1.843 +
1.844 + reply().iEM = sendDbg().iEM;
1.845 + Mem::Copy(reply().iPW, sendDbg().iPW, KMaxMediaPassword);
1.846 + }
1.847 + else
1.848 + {
1.849 + RenderPassword(&con, KPasswordLeft, pw);
1.850 + do
1.851 + {
1.852 + TConsoleKey key;
1.853 +
1.854 + con.Read(key);
1.855 + TInt keyCode = key.Code();
1.856 +
1.857 + switch (keyCode)
1.858 + {
1.859 + case EKeyEscape:
1.860 + em = EMPEMCancel;
1.861 + done = ETrue;
1.862 + break;
1.863 +
1.864 + case EKeyEnter:
1.865 + em = EMPEMUnlock;
1.866 + done = ETrue;
1.867 + break;
1.868 +
1.869 + case EKeySpace:
1.870 + em = EMPEMUnlockAndStore;
1.871 + done = ETrue;
1.872 + break;
1.873 +
1.874 + case EKeyBackspace:
1.875 + if (pw.Length() > 0)
1.876 + {
1.877 + pw.SetLength(pw.Length() - 1);
1.878 + RenderPassword(&con, KPasswordLeft, pw);
1.879 + }
1.880 + break;
1.881 +
1.882 + default: // interpret other keys as pw contents
1.883 + TChar ch(keyCode);
1.884 + // unicode encoding, so number of password characters is half byte length
1.885 + if (ch.IsPrint() && pw.Length() < KMaxMediaPassword / 2)
1.886 + {
1.887 + pw.Append(ch);
1.888 + RenderPassword(&con, KPasswordLeft, pw);
1.889 + }
1.890 + break;
1.891 + }
1.892 + } while (! done);
1.893 +
1.894 + // Fill the TMediaPswdReplyNotifyInfoV1 structure.
1.895 +
1.896 + if (em == EMPEMUnlock || em == EMPEMUnlockAndStore)
1.897 + {
1.898 + const TInt byteLen = pw.Length() * 2;
1.899 +
1.900 + // zero entire array; and then copy in valid section of TMediaPassword,
1.901 + // not converting Unicode to ASCII.
1.902 + TPtr8 pt8(reply().iPW, KMaxMediaPassword); // length = 0
1.903 + pt8.FillZ(KMaxMediaPassword); // length = KMaxMediaPassword
1.904 + pt8.Zero(); // length = 0
1.905 + // length = byteLen
1.906 + pt8.Copy(reinterpret_cast<const TUint8 *>(pw.Ptr()), byteLen);
1.907 + }
1.908 +
1.909 + // Set exit mode to tell user how dialog handled.
1.910 +
1.911 + reply().iEM = em;
1.912 + } // else (sendInfoLen == sizeof(TMediaPswdSendNotifyInfoV1Debug))
1.913 +
1.914 + con.Destroy();
1.915 +
1.916 + aMsg.WriteL(2, reply);
1.917 + }
1.918 +
1.919 +//
1.920 +// class MNotifierBase2
1.921 +//
1.922 +
1.923 +void MNotifierBase2::SetManager(MNotifierManager* aManager)
1.924 + {
1.925 + iManager=aManager;
1.926 + }
1.927 +
1.928 +//
1.929 +// class CNotifierServer
1.930 +//
1.931 +
1.932 +_LIT(__NOTIFIER_SERVER,"TextNotifierSrvr");
1.933 +
1.934 +CNotifierServer* CNotifierServer::NewL()
1.935 + {
1.936 + CNotifierServer* server=new(ELeave) CNotifierServer(200);
1.937 + CleanupStack::PushL(server);
1.938 + server->ConstructL();
1.939 + server->StartL(__NOTIFIER_NAME);
1.940 + CleanupStack::Pop(); // server
1.941 + return server;
1.942 + }
1.943 +
1.944 +CNotifierServer::~CNotifierServer()
1.945 + {
1.946 + SetIsExiting();
1.947 + delete iManager;
1.948 + }
1.949 +
1.950 +void CNotifierServer::SetIsExiting()
1.951 + {
1.952 + iExiting=ETrue;
1.953 + }
1.954 +
1.955 +TBool CNotifierServer::IsExiting() const
1.956 + {
1.957 + return iExiting;
1.958 + }
1.959 +
1.960 +CNotifierServer::CNotifierServer(TInt aPriority)
1.961 + : CServer2(aPriority)
1.962 + {}
1.963 +
1.964 +void CNotifierServer::ConstructL()
1.965 + {
1.966 + iManager=CNotifierManager::NewL();
1.967 + RFs fs;
1.968 + User::LeaveIfError(fs.Connect());
1.969 + CleanupClosePushL(fs);
1.970 + iManager->RegisterL(fs);
1.971 + CleanupStack::PopAndDestroy(); // fs.Close()
1.972 + }
1.973 +
1.974 +CSession2* CNotifierServer::NewSessionL(const TVersion &aVersion,const RMessage2&) const
1.975 + {
1.976 + TVersion v(1,0,0); // !! liaise with E32
1.977 + if (!User::QueryVersionSupported(v,aVersion))
1.978 + User::Leave(KErrNotSupported);
1.979 + return new(ELeave) CNotifierSession(*this);
1.980 + }
1.981 +
1.982 +//
1.983 +// class CNotifierSession
1.984 +//
1.985 +
1.986 +CNotifierSession::CNotifierSession(const CNotifierServer& aServer)
1.987 + {
1.988 + iServer=&aServer;
1.989 + iClientId=(TInt)this;
1.990 + }
1.991 +
1.992 +CNotifierSession::~CNotifierSession()
1.993 + {
1.994 + const CNotifierServer* server=static_cast<const CNotifierServer*>(Server());
1.995 + if (!server->IsExiting())
1.996 + {
1.997 + server->Manager()->HandleClientExit(iClientId);
1.998 + }
1.999 + }
1.1000 +
1.1001 +void CNotifierSession::ServiceL(const RMessage2 &aMessage)
1.1002 + {
1.1003 + TBool completeMessage=ETrue;
1.1004 + switch (aMessage.Function())
1.1005 + {
1.1006 + case ENotifierNotify:
1.1007 + DisplayAlertL(aMessage);
1.1008 + break;
1.1009 + case ENotifierNotifyCancel:
1.1010 + // do nothing - this server doesn't support cancelling RNotifier::Notify - the client will just have to wait
1.1011 + break;
1.1012 + case ENotifierInfoPrint:
1.1013 + DisplayInfoMsgL(aMessage);
1.1014 + break;
1.1015 + case EStartNotifier:
1.1016 + DoStartNotifierL(aMessage);
1.1017 + break;
1.1018 + case ECancelNotifier:
1.1019 + iServer->Manager()->NotifierCancel(TUid::Uid(aMessage.Int0()));
1.1020 + break;
1.1021 + case EUpdateNotifierAndGetResponse:
1.1022 + case EUpdateNotifier:
1.1023 + DoUpdateNotifierL(aMessage);
1.1024 + break;
1.1025 + case EStartNotifierAndGetResponse:
1.1026 + {
1.1027 + if (aMessage.Int0()==KMediaPasswordNotifyUid)
1.1028 + {
1.1029 + RunPasswordWindowL(aMessage);
1.1030 + }
1.1031 + else
1.1032 + {
1.1033 + TBool cleanupComplete=ETrue;
1.1034 + StartNotifierAndGetResponseL(aMessage,cleanupComplete);
1.1035 + // if the plug-in starts successfully, it has
1.1036 + // responsibility for completing the message (either
1.1037 + // synchronously or asynchronously)
1.1038 + completeMessage=EFalse;
1.1039 + }
1.1040 + }
1.1041 + break;
1.1042 + default:
1.1043 + aMessage.Complete(KErrNotSupported);
1.1044 + break;
1.1045 + }
1.1046 + if (completeMessage && !aMessage.IsNull())
1.1047 + {
1.1048 + aMessage.Complete(KErrNone);
1.1049 + }
1.1050 + }
1.1051 +
1.1052 +void CNotifierSession::DisplayAlertL(const RMessage2& aMessage)
1.1053 + {
1.1054 + const TInt lengthOfCombinedBuffer=User::LeaveIfError(aMessage.GetDesLength(1));
1.1055 + const TInt lengthOfLine1=(STATIC_CAST(TUint,aMessage.Int2())>>16);
1.1056 + const TInt lengthOfLine2=(aMessage.Int2()&KMaxTUint16);
1.1057 + const TInt lengthOfBut1=(STATIC_CAST(TUint,aMessage.Int3())>>16);
1.1058 + const TInt lengthOfBut2=(aMessage.Int3()&KMaxTUint16);
1.1059 + if (lengthOfCombinedBuffer!=lengthOfLine1+lengthOfLine2+lengthOfBut1+lengthOfBut2)
1.1060 + {
1.1061 + PanicClient(aMessage,ENotifierPanicInconsistentDescriptorLengths);
1.1062 + return;
1.1063 + }
1.1064 + HBufC* const combinedBuffer=HBufC::NewLC(lengthOfCombinedBuffer);
1.1065 + {TPtr combinedBuffer_asWritable(combinedBuffer->Des());
1.1066 + aMessage.ReadL(1,combinedBuffer_asWritable);}
1.1067 + const TPtrC line1(combinedBuffer->Left(lengthOfLine1));
1.1068 + const TPtrC line2(combinedBuffer->Mid(lengthOfLine1,lengthOfLine2));
1.1069 + const TPtrC but1(combinedBuffer->Mid(lengthOfLine1+lengthOfLine2,lengthOfBut1));
1.1070 + const TPtrC but2(combinedBuffer->Mid(lengthOfLine1+lengthOfLine2+lengthOfBut1,lengthOfBut2));
1.1071 + TInt buttons, len, offset;
1.1072 + if (lengthOfBut2==0)
1.1073 + {
1.1074 + buttons=1;
1.1075 + len=lengthOfBut1+2;
1.1076 + }
1.1077 + else
1.1078 + {
1.1079 + buttons=2;
1.1080 + len=lengthOfBut1+lengthOfBut2+5;
1.1081 + }
1.1082 + if (lengthOfLine1>len)
1.1083 + len=lengthOfLine1;
1.1084 + if (lengthOfLine2>len)
1.1085 + len=lengthOfLine2;
1.1086 + RConsole con;
1.1087 + con.Create();
1.1088 + TSize scsz;
1.1089 + con.ScreenSize(scsz);
1.1090 + con.Control(_L("-Visible"));
1.1091 + TInt ww=Min(len,scsz.iWidth-4);
1.1092 + TInt wh=3;
1.1093 + if ((lengthOfBut1+lengthOfBut2+5)>ww)
1.1094 + wh++;
1.1095 + if (lengthOfLine1>ww)
1.1096 + wh++;
1.1097 + if (lengthOfLine2>ww)
1.1098 + wh++;
1.1099 + con.Init(_L(""),TSize(ww,wh));
1.1100 + con.Control(_L("+Max -Cursor -Allowresize +Ontop +Wrap"));
1.1101 + con.Write(line1);
1.1102 + con.SetCursorPosAbs(TPoint(0,1));
1.1103 + con.Write(line2);
1.1104 + if (buttons==2)
1.1105 + offset=(len-lengthOfBut1-lengthOfBut2-5)/2;
1.1106 + else
1.1107 + offset=(len-lengthOfBut1-2)/2;
1.1108 + con.SetCursorPosAbs(TPoint(offset,2));
1.1109 + con.Write(_L("<"));
1.1110 + con.Write(but1);
1.1111 + con.Write(_L(">"));
1.1112 + if(buttons==2)
1.1113 + {
1.1114 + con.Write(_L(" <"));
1.1115 + con.Write(but2);
1.1116 + con.Write(_L(">"));
1.1117 + }
1.1118 +
1.1119 + TConsoleKey key;
1.1120 + TInt keycode;
1.1121 + do
1.1122 + {
1.1123 + con.Read(key);
1.1124 + keycode=key.Code();
1.1125 + }
1.1126 + while((keycode!=EKeyEscape&&keycode!=EKeyEnter&&buttons==2)||(keycode!=EKeyEnter&&buttons==1));
1.1127 + if(keycode==EKeyEscape)
1.1128 + keycode=0;
1.1129 + else
1.1130 + keycode=1;
1.1131 + con.Destroy();
1.1132 + aMessage.WriteL(0,TPckgC<TInt>(keycode));
1.1133 + CleanupStack::PopAndDestroy(combinedBuffer);
1.1134 + }
1.1135 +
1.1136 +TInt CNotifierSession::InfoPrintThread(TAny* aMessage)
1.1137 + {
1.1138 + TBuf<0x50> des; // 0x50 max size of message
1.1139 + RConsole con;
1.1140 + des=*(TBuf<0x50> *)aMessage;
1.1141 + TInt l=des.Length();
1.1142 + NotifierSemaphore.Signal();
1.1143 + con.Create();
1.1144 + con.Control(_L("-Visible"));
1.1145 + TSize size;
1.1146 + con.ScreenSize(size);
1.1147 + TInt ww=Min(size.iWidth-6,l);
1.1148 + TInt wh=(l+ww-1)/ww;
1.1149 + if (wh==0)
1.1150 + wh=1;
1.1151 + con.Init(_L(""),TSize(ww,wh));
1.1152 + con.Control(_L("+Maximise"));
1.1153 + con.SetWindowPosAbs(TPoint(size.iWidth-ww-4,1));
1.1154 + con.Control(_L("+Wrap +Ontop"));
1.1155 + con.Write(des);
1.1156 +
1.1157 + User::After(1300000);
1.1158 + con.Destroy();
1.1159 + return KErrNone;
1.1160 + }
1.1161 +
1.1162 +void CNotifierSession::DisplayInfoMsgL(const RMessage2& aMessage)
1.1163 + {
1.1164 + TInt r;
1.1165 + TBuf<0x50> des; // 0x50 max size of message lines
1.1166 + aMessage.ReadL(0,des);
1.1167 + RThread thread;
1.1168 + do
1.1169 + {
1.1170 + r=thread.Create(_L("Info Window"),InfoPrintThread,KDefaultStackSize,&User::Allocator(),(TAny*)&des);
1.1171 + if(r==KErrAlreadyExists)
1.1172 + User::After(200000);
1.1173 + } while(r==KErrAlreadyExists);
1.1174 + User::LeaveIfError(r);
1.1175 + thread.Resume();
1.1176 + NotifierSemaphore.Wait();
1.1177 + thread.Close();
1.1178 + }
1.1179 +
1.1180 +void CNotifierSession::DoStartNotifierL(const RMessage2& aMessage)
1.1181 + {
1.1182 + const TUid targetUid={aMessage.Int0()};
1.1183 + HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1)));
1.1184 + {TPtr8 input(inputBuffer->Des());
1.1185 + aMessage.ReadL(1,input);}
1.1186 + TPtrC8 output(0,0);
1.1187 + iServer->Manager()->NotifierStartL(targetUid,*inputBuffer,&output,iClientId);
1.1188 + if(aMessage.Int2())
1.1189 + aMessage.WriteL(2,output);
1.1190 + CleanupStack::PopAndDestroy(inputBuffer);
1.1191 + }
1.1192 +
1.1193 +void CNotifierSession::DoUpdateNotifierL(const RMessage2& aMessage)
1.1194 + {
1.1195 + const TUid targetUid={aMessage.Int0()};
1.1196 + HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1)));
1.1197 + {TPtr8 input(inputBuffer->Des());
1.1198 + aMessage.ReadL(1, input);}
1.1199 + HBufC8* const outputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesMaxLength(2)));
1.1200 + {TPtr8 output(outputBuffer->Des());
1.1201 + iServer->Manager()->NotifierUpdateL(targetUid,*inputBuffer,&output,iClientId);}
1.1202 + aMessage.WriteL(2,*outputBuffer);
1.1203 + CleanupStack::PopAndDestroy(2,inputBuffer);
1.1204 + }
1.1205 +
1.1206 +void CNotifierSession::StartNotifierAndGetResponseL(const RMessage2& aMessage,TBool& aCleanupComplete)
1.1207 + {
1.1208 + const TUid targetUid={aMessage.Int0()};
1.1209 + HBufC8* const inputBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(1)));
1.1210 + {TPtr8 input(inputBuffer->Des());
1.1211 + aMessage.ReadL(1,input);}
1.1212 + iServer->Manager()->NotifierStartAndGetResponseL(targetUid,*inputBuffer,2,aMessage,iClientId,aCleanupComplete);
1.1213 + CleanupStack::PopAndDestroy(inputBuffer);
1.1214 + }
1.1215 +
1.1216 +void CNotifierSession::PanicClient(const RMessage2& aMessage,TNotifierPanic aCode)
1.1217 + {
1.1218 + aMessage.Panic(__NOTIFIER_SERVER,aCode);
1.1219 + }
1.1220 +
1.1221 +//
1.1222 +// class CNotifierManager
1.1223 +//
1.1224 +
1.1225 +const TInt KNullClientId=0;
1.1226 +
1.1227 +CNotifierManager* CNotifierManager::NewL()
1.1228 + {
1.1229 + CNotifierManager* self=new(ELeave) CNotifierManager;
1.1230 + CleanupStack::PushL(self);
1.1231 + self->ConstructL();
1.1232 + CleanupStack::Pop(self);
1.1233 + return self;
1.1234 + }
1.1235 +
1.1236 +CNotifierManager::~CNotifierManager()
1.1237 + {
1.1238 + if (iObservedList)
1.1239 + {
1.1240 + const TInt count=iObservedList->Count();
1.1241 + for (TInt ii=0;ii<count;ii++)
1.1242 + {
1.1243 + (*iObservedList)[ii]->Release();
1.1244 + }
1.1245 + delete iObservedList;
1.1246 + }
1.1247 + if (iLibraries)
1.1248 + {
1.1249 + const TInt count=iLibraries->Count();
1.1250 + for (TInt ii=0;ii<count;ii++)
1.1251 + {
1.1252 + (*iLibraries)[ii].Close();
1.1253 + }
1.1254 + delete iLibraries;
1.1255 + }
1.1256 + delete iChannelMonitor;
1.1257 + delete iActivityMonitor;
1.1258 + delete iQueue;
1.1259 + }
1.1260 +
1.1261 +
1.1262 +void CNotifierManager::RegisterL(RFs& aFs)
1.1263 + {
1.1264 +#ifdef SUPPORT_OLD_PLUGIN_PATH
1.1265 + TBool old;
1.1266 + for(old=0; old<2; old++)
1.1267 + {
1.1268 +#endif
1.1269 + TFindFile* findFile=new(ELeave) TFindFile(aFs);
1.1270 + CleanupStack::PushL(findFile);
1.1271 + TParse* fileNameParser=new(ELeave) TParse;
1.1272 + CleanupStack::PushL(fileNameParser);
1.1273 + CDir* directory=NULL;
1.1274 + TInt error;
1.1275 +#ifdef SUPPORT_OLD_PLUGIN_PATH
1.1276 + _LIT(KNotifierPlugInOldSearchPath,"\\system\\tnotifiers\\");
1.1277 + if(old)
1.1278 + error=findFile->FindWildByDir(KNotifierPlugInExt, KNotifierPlugInOldSearchPath, directory);
1.1279 + else
1.1280 +#endif
1.1281 + error=findFile->FindWildByDir(KNotifierPlugInExt, KNotifierPlugInSearchPath, directory);
1.1282 + for (; error!=KErrNotFound; error=findFile->FindWild(directory))
1.1283 + {
1.1284 + CleanupStack::PushL(directory);
1.1285 + User::LeaveIfError(error);
1.1286 + const TInt numberOfEntries=directory->Count();
1.1287 + for (TInt i=0; i<numberOfEntries; ++i)
1.1288 + {
1.1289 + const TEntry& entry=(*directory)[i];
1.1290 + fileNameParser->SetNoWild(entry.iName, &findFile->File(), NULL); // findFile->File() returns a reference rather than an object, therefore taking the address of it is fine
1.1291 +
1.1292 + if (entry.iType[0].iUid==0x10000079)
1.1293 + {
1.1294 + // It's a DLL
1.1295 + if( (entry.iType[1]==KUidTextNotifierPlugInV2))
1.1296 + {
1.1297 + // Its a notifier...
1.1298 + TPtrC path(fileNameParser->DriveAndPath());
1.1299 + TPtrC name(fileNameParser->NameAndExt());
1.1300 + DoAddPlugInL(path,name,entry.iType);
1.1301 + }
1.1302 + }
1.1303 + }
1.1304 + CleanupStack::PopAndDestroy(); // directory
1.1305 + directory=NULL;
1.1306 + }
1.1307 + delete directory;
1.1308 + CleanupStack::PopAndDestroy(2); // fileNameParser and findFile
1.1309 +#ifdef SUPPORT_OLD_PLUGIN_PATH
1.1310 + }
1.1311 +#endif
1.1312 + }
1.1313 +
1.1314 +LOCAL_C void DeleteTemp(TAny* aPtr)
1.1315 + {
1.1316 + CArrayPtr<MNotifierBase2>* array=REINTERPRET_CAST(CArrayPtr<MNotifierBase2>*,aPtr);
1.1317 + const TInt count=array->Count();
1.1318 + for (TInt ii=0;ii<count;ii++)
1.1319 + {
1.1320 + (*array)[ii]->Release();
1.1321 + }
1.1322 + delete array;
1.1323 + }
1.1324 +
1.1325 +
1.1326 +
1.1327 +void CNotifierManager::DoAddPlugInL(const TDesC& aPath,const TDesC& aFileName,const TUidType& aUidType)
1.1328 + {
1.1329 + RLibrary lib;
1.1330 + User::LeaveIfError(lib.Load(aFileName,aPath,aUidType));
1.1331 + CleanupClosePushL(lib);
1.1332 + iLibraries->AppendL(lib);
1.1333 + CleanupStack::Pop(); // lib
1.1334 + TLibraryFunction libEntry=lib.Lookup(1);
1.1335 + CArrayPtr<MNotifierBase2>* array=REINTERPRET_CAST(CArrayPtr<MNotifierBase2>*,(libEntry)());
1.1336 + User::LeaveIfNull(array);
1.1337 + CleanupStack::PushL(TCleanupItem(DeleteTemp,array));
1.1338 + while (array->Count()>0)
1.1339 + {
1.1340 + MNotifierBase2* notif=(*array)[0];
1.1341 + {
1.1342 + iObservedList->AppendL(notif);
1.1343 + array->Delete(0);
1.1344 + notif->SetManager(this);
1.1345 + }
1.1346 + MNotifierBase2::TNotifierInfo info=notif->RegisterL();
1.1347 + if (!iChannelMonitor->AlreadyHasChannel(info.iChannel))
1.1348 + iChannelMonitor->AddNewChannelL(info.iChannel);
1.1349 + }
1.1350 + CleanupStack::PopAndDestroy(); // array
1.1351 + }
1.1352 +
1.1353 +CNotifierManager::CNotifierManager()
1.1354 + {}
1.1355 +
1.1356 +void CNotifierManager::ConstructL()
1.1357 + {
1.1358 + iObservedList=new(ELeave) CArrayPtrSeg<MNotifierBase2>(6);
1.1359 + iLibraries=new(ELeave) CArrayFixFlat<RLibrary>(2);
1.1360 + iChannelMonitor=CChannelMonitor::NewL();
1.1361 + iActivityMonitor=CActivityMonitor::NewL();
1.1362 + iQueue=CNotifierQueue::NewL();
1.1363 + }
1.1364 +
1.1365 +struct SActivityCleanup
1.1366 + {
1.1367 + CActivityMonitor* iMonitor;
1.1368 + TUid iNotifier;
1.1369 + TInt iClientId;
1.1370 + };
1.1371 +
1.1372 +LOCAL_C void CleanupActivityMonitor(TAny* aPtr)
1.1373 + {
1.1374 + SActivityCleanup& cleanup=*REINTERPRET_CAST(SActivityCleanup*,aPtr);
1.1375 + cleanup.iMonitor->Remove(cleanup.iNotifier,cleanup.iClientId);
1.1376 + }
1.1377 +
1.1378 +void CNotifierManager::NotifierStartL(TUid aNotifierUid,const TDesC8& aBuffer,TPtrC8* aResponse,TInt aClientId)
1.1379 + {
1.1380 + TInt result=KErrNotFound;
1.1381 + const TInt count=iObservedList->Count();
1.1382 + for (TInt ii=0;ii<count;ii++)
1.1383 + {
1.1384 + MNotifierBase2* notif=(*iObservedList)[ii];
1.1385 + MNotifierBase2::TNotifierInfo info=notif->Info();
1.1386 + if (info.iUid==aNotifierUid)
1.1387 + {
1.1388 + if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel))
1.1389 + {
1.1390 + result=KErrAlreadyExists;
1.1391 + }
1.1392 + else if (info.iPriority>iChannelMonitor->ActivityLevel(info.iChannel))
1.1393 + {
1.1394 + TUid notifier;
1.1395 + MNotifierBase2::TNotifierPriority priority;
1.1396 + const TBool channelWasActive=iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority);
1.1397 + iActivityMonitor->AddL(info,aClientId);
1.1398 + SActivityCleanup cleanup;
1.1399 + cleanup.iMonitor=iActivityMonitor;
1.1400 + cleanup.iNotifier=aNotifierUid;
1.1401 + cleanup.iClientId=aClientId;
1.1402 + CleanupStack::PushL(TCleanupItem(CleanupActivityMonitor,&cleanup));
1.1403 + TPtrC8 response(notif->StartL(aBuffer));
1.1404 + if(aResponse)
1.1405 + aResponse->Set(response);
1.1406 + CleanupStack::Pop(); // cleanup;
1.1407 + if (channelWasActive)
1.1408 + {
1.1409 + for (TInt jj=0;jj<count;jj++)
1.1410 + {
1.1411 + MNotifierBase2* notifForUpdate=(*iObservedList)[ii];
1.1412 + MNotifierBase2::TNotifierInfo infoForUpdate=notifForUpdate->Info();
1.1413 + if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel)
1.1414 + {
1.1415 + TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused));
1.1416 + }
1.1417 + }
1.1418 + }
1.1419 + iChannelMonitor->UpdateChannel(info.iChannel,info.iPriority);
1.1420 + if (result!=ENotExtRequestQueued)
1.1421 + {
1.1422 + result=ENotExtRequestCompleted;
1.1423 + }
1.1424 + }
1.1425 + else
1.1426 + {
1.1427 + if (iQueue->IsAlreadyQueued(info.iUid,info.iChannel))
1.1428 + {
1.1429 + result=KErrAlreadyExists;
1.1430 + }
1.1431 + else
1.1432 + {
1.1433 + CQueueItem* queueCopy=CQueueItem::NewL(info,aBuffer,aClientId);
1.1434 + CleanupStack::PushL(queueCopy);
1.1435 + iQueue->QueueItemL(queueCopy);
1.1436 + CleanupStack::Pop(); // queueCopy
1.1437 + result=ENotExtRequestQueued;
1.1438 + }
1.1439 + }
1.1440 + }
1.1441 + }
1.1442 + User::LeaveIfError(result);
1.1443 + }
1.1444 +
1.1445 +TInt CNotifierManager::NotifierUpdateL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8* aResponse,TInt aClientId)
1.1446 + {
1.1447 + TInt result=KErrNotFound;
1.1448 + const TInt count=iObservedList->Count();
1.1449 + for (TInt ii=0;ii<count;ii++)
1.1450 + {
1.1451 + MNotifierBase2* notif=(*iObservedList)[ii];
1.1452 + MNotifierBase2::TNotifierInfo info=notif->Info();
1.1453 + if (info.iUid==aNotifierUid)
1.1454 + {
1.1455 + if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel))
1.1456 + {
1.1457 + if (!iActivityMonitor->IsClientPresent(aNotifierUid,info.iChannel,aClientId))
1.1458 + {
1.1459 + iActivityMonitor->AddL(info,aClientId);
1.1460 + }
1.1461 + if (aResponse==NULL)
1.1462 + {
1.1463 + notif->UpdateL(aBuffer);
1.1464 + }
1.1465 + else
1.1466 + {
1.1467 + aResponse->Copy(notif->UpdateL(aBuffer));
1.1468 + }
1.1469 + }
1.1470 + else
1.1471 + {
1.1472 + ; // not all channels have been started yet so update the queue
1.1473 + }
1.1474 + result=KErrNone;
1.1475 + }
1.1476 + }
1.1477 + return result;
1.1478 + }
1.1479 +
1.1480 +void CNotifierManager::NotifierStartAndGetResponseL(TUid aNotifierUid,const TDesC8& aBuffer,TInt aReplySlot,
1.1481 + const RMessage2& aMessage,TInt aClientId,TBool& aCleanupComplete)
1.1482 + {
1.1483 + NotifierStartAndGetResponseL(aNotifierUid,TUid::Null(),aBuffer,aReplySlot,aMessage,aClientId,aCleanupComplete);
1.1484 + }
1.1485 +
1.1486 +void CNotifierManager::NotifierStartAndGetResponseL(TUid aNotifierUid,TUid aChannelUid,const TDesC8& aBuffer,TInt aReplySlot,
1.1487 + const RMessage2& aMessage,TInt aClientId,TBool& aCleanupComplete)
1.1488 + {
1.1489 + TInt result=KErrNotFound;
1.1490 + const TInt count=iObservedList->Count();
1.1491 + for (TInt ii=0;ii<count;ii++)
1.1492 + {
1.1493 + MNotifierBase2* notif=(*iObservedList)[ii];
1.1494 + MNotifierBase2::TNotifierInfo info=notif->Info();
1.1495 + if (info.iUid==aNotifierUid && (aChannelUid==TUid::Null() || info.iChannel==aChannelUid))
1.1496 + {
1.1497 + if (iActivityMonitor->IsNotifierActive(aNotifierUid,info.iChannel))
1.1498 + {
1.1499 + notif->StartL(aBuffer,aReplySlot,aMessage); // asynch notifier can decide whether to support multiple clients
1.1500 + result=KErrNone;
1.1501 + }
1.1502 + else if (info.iPriority>iChannelMonitor->ActivityLevel(info.iChannel))
1.1503 + {
1.1504 + TUid notifier;
1.1505 + MNotifierBase2::TNotifierPriority priority;
1.1506 + const TBool channelWasActive=iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority);
1.1507 + iActivityMonitor->AddL(info,aClientId);
1.1508 + SActivityCleanup activityCleanup;
1.1509 + activityCleanup.iMonitor=iActivityMonitor;
1.1510 + activityCleanup.iNotifier=aNotifierUid;
1.1511 + activityCleanup.iClientId=aClientId;
1.1512 + CleanupStack::PushL(TCleanupItem(CleanupActivityMonitor,&activityCleanup));
1.1513 + aCleanupComplete=EFalse;
1.1514 + // IMPORTANT, aMessage needs to be a full RMessage object until suport for V1 notifiers is removed
1.1515 + // I.e. until CNotifierBaseAdaptor is removed
1.1516 + notif->StartL(aBuffer,aReplySlot,aMessage);
1.1517 + CleanupStack::Pop(&activityCleanup);
1.1518 + if (channelWasActive)
1.1519 + {
1.1520 + for (TInt jj=0;jj<count;jj++)
1.1521 + {
1.1522 + MNotifierBase2* notifForUpdate=(*iObservedList)[ii];
1.1523 + MNotifierBase2::TNotifierInfo infoForUpdate=notifForUpdate->Info();
1.1524 + if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel)
1.1525 + {
1.1526 + TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused));
1.1527 + }
1.1528 + }
1.1529 + }
1.1530 + iChannelMonitor->UpdateChannel(info.iChannel,info.iPriority);
1.1531 + result=KErrNone;
1.1532 + }
1.1533 + else
1.1534 + {
1.1535 + if (iQueue->IsAlreadyQueued(info.iUid,info.iChannel))
1.1536 + {
1.1537 + result=KErrAlreadyExists;
1.1538 + }
1.1539 + else
1.1540 + {
1.1541 + CQueueItem* queueCopy=CQueueItem::NewL(info,aBuffer,aReplySlot,aMessage,aClientId);
1.1542 + CleanupStack::PushL(queueCopy);
1.1543 + iQueue->QueueItemL(queueCopy);
1.1544 + CleanupStack::Pop(queueCopy);
1.1545 + result=ENotExtRequestQueued;
1.1546 + }
1.1547 + }
1.1548 + }
1.1549 + }
1.1550 + User::LeaveIfError(result);
1.1551 + }
1.1552 +
1.1553 +TInt CNotifierManager::NotifierCancel(TUid aNotifierUid)
1.1554 + {
1.1555 + TInt result=KErrNotFound;
1.1556 + const TInt count=iObservedList->Count();
1.1557 + for (TInt ii=0;ii<count;ii++)
1.1558 + {
1.1559 + MNotifierBase2* notif=(*iObservedList)[ii];
1.1560 + MNotifierBase2::TNotifierInfo info=notif->Info();
1.1561 + if (info.iUid==aNotifierUid)
1.1562 + {
1.1563 + notif->Cancel();
1.1564 + iActivityMonitor->RemoveNotifier(aNotifierUid,info.iChannel);
1.1565 + MNotifierBase2::TNotifierPriority priority=MNotifierBase2::ENotifierPriorityLowest;
1.1566 + TUid notifier;
1.1567 + //check channel activity and get highest priority on channnel
1.1568 + if (iActivityMonitor->IsChannelActive(info.iChannel,notifier,priority))
1.1569 + {
1.1570 +
1.1571 + //check if priority of a queued item on the same channel is
1.1572 + //greater
1.1573 + MNotifierBase2::TNotifierPriority queuePriority=
1.1574 + (MNotifierBase2::TNotifierPriority)iQueue->GetHighestQueuePriority(info.iChannel);
1.1575 + if (queuePriority>priority)
1.1576 + {
1.1577 + iChannelMonitor->UpdateChannel(info.iChannel,MNotifierBase2::ENotifierPriorityLowest);
1.1578 + CQueueItem* next=iQueue->FetchItem(info.iChannel);
1.1579 + if (next)
1.1580 + {
1.1581 + TUid notif=next->iInfo.iUid;
1.1582 + TRAPD(err,StartFromQueueL(next));
1.1583 + if (err!=KErrNone)
1.1584 + {
1.1585 + NotifierCancel(notif);
1.1586 + }
1.1587 + }
1.1588 + }
1.1589 + else
1.1590 + {
1.1591 + for (TInt jj=0;jj<count;jj++)
1.1592 + {
1.1593 + MNotifierBase2* notifForUpdate=(*iObservedList)[ii];
1.1594 + MNotifierBase2::TNotifierInfo infoForUpdate=notifForUpdate->Info();
1.1595 + if (infoForUpdate.iUid==notifier && infoForUpdate.iChannel==info.iChannel)
1.1596 + {
1.1597 + TRAP_IGNORE(notifForUpdate->UpdateL(KNotifierPaused));
1.1598 + }
1.1599 + }
1.1600 + iChannelMonitor->UpdateChannel(info.iChannel,priority);
1.1601 + }
1.1602 + }
1.1603 + else
1.1604 + {
1.1605 + iChannelMonitor->UpdateChannel(info.iChannel,MNotifierBase2::ENotifierPriorityLowest);
1.1606 + CQueueItem* next=iQueue->FetchItem(info.iChannel);
1.1607 + if (next)
1.1608 + {
1.1609 + TUid notif=next->iInfo.iUid;
1.1610 + TRAPD(err,StartFromQueueL(next));
1.1611 + if (err!=KErrNone)
1.1612 + {
1.1613 + NotifierCancel(notif);
1.1614 + }
1.1615 + }
1.1616 + }
1.1617 + result=KErrNone;
1.1618 + }
1.1619 + }
1.1620 + return result;
1.1621 + }
1.1622 +
1.1623 +struct SCleanupMessage
1.1624 + {
1.1625 + TBool* iDoCleanup;
1.1626 + RMessage2* iMessage;
1.1627 + };
1.1628 +
1.1629 +LOCAL_C void CleanupStartAndGetResponse(TAny* aPtr)
1.1630 + {
1.1631 + SCleanupMessage& cleanup=*REINTERPRET_CAST(SCleanupMessage*,aPtr);
1.1632 + if (cleanup.iDoCleanup)
1.1633 + {
1.1634 + cleanup.iMessage->Complete(KErrNoMemory);
1.1635 + }
1.1636 + }
1.1637 +
1.1638 +void CNotifierManager::StartFromQueueL(CQueueItem* aItem)
1.1639 + {
1.1640 + CleanupStack::PushL(aItem);
1.1641 + TPtr8 buffer=aItem->iBuffer->Des();
1.1642 + if (aItem->iAsynchronous)
1.1643 + {
1.1644 + SCleanupMessage cleanup;
1.1645 + TBool doCleanup=ETrue;
1.1646 + cleanup.iDoCleanup=&doCleanup;
1.1647 + cleanup.iMessage=&aItem->iMessage;
1.1648 + CleanupStack::PushL(TCleanupItem(CleanupStartAndGetResponse,&cleanup));
1.1649 + // IMPORTANT, aItem->iMessage needs to be a full RMessage object until suport for V1 notifiers is removed
1.1650 + // I.e. until CNotifierBaseAdaptor is removed
1.1651 + NotifierStartAndGetResponseL(aItem->iInfo.iUid,aItem->iInfo.iChannel,buffer,aItem->iReplySlot,aItem->iMessage,aItem->iClientId,doCleanup);
1.1652 + CleanupStack::Pop(&cleanup);
1.1653 + }
1.1654 + else
1.1655 + {
1.1656 + NotifierStartL(aItem->iInfo.iUid,buffer,NULL,aItem->iClientId);
1.1657 + }
1.1658 + CleanupStack::PopAndDestroy(); // aItem
1.1659 + CQueueItem* update=iQueue->FetchItem(aItem->iInfo.iChannel);
1.1660 + while (update)
1.1661 + {
1.1662 + CleanupStack::PushL(update);
1.1663 + NotifierUpdateL(update->iInfo.iUid,*update->iBuffer,NULL,update->iClientId);
1.1664 + CleanupStack::PopAndDestroy(); // update
1.1665 + update=iQueue->FetchItem(aItem->iInfo.iChannel);
1.1666 + }
1.1667 + }
1.1668 +
1.1669 +void CNotifierManager::HandleClientExit(TInt aClientId)
1.1670 + {
1.1671 + TUid notifier=KNullUid;
1.1672 + while (iActivityMonitor->NotifierForClient(notifier,aClientId))
1.1673 + {
1.1674 + const TInt count=iObservedList->Count();
1.1675 + for (TInt ii=0;ii<count;ii++)
1.1676 + {
1.1677 + MNotifierBase2* notif=(*iObservedList)[ii];
1.1678 + if (notif->Info().iUid==notifier)
1.1679 + {
1.1680 + NotifierCancel(notifier);
1.1681 + }
1.1682 + }
1.1683 + iActivityMonitor->Remove(notifier,aClientId);
1.1684 + }
1.1685 + iActivityMonitor->RemoveClient(aClientId);
1.1686 + iQueue->RemoveClient(aClientId);
1.1687 + }
1.1688 +
1.1689 +void CNotifierManager::StartNotifierL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
1.1690 + {
1.1691 + TPtrC8 response(0,0);
1.1692 + NotifierStartL(aNotifierUid,aBuffer, &response,KNullClientId);
1.1693 + aResponse.Copy(response);
1.1694 + }
1.1695 +
1.1696 +void CNotifierManager::CancelNotifier(TUid aNotifierUid)
1.1697 + {
1.1698 + NotifierCancel(aNotifierUid);
1.1699 + }
1.1700 +
1.1701 +void CNotifierManager::UpdateNotifierL(TUid aNotifierUid,const TDesC8& aBuffer,TDes8& aResponse)
1.1702 + {
1.1703 + NotifierUpdateL(aNotifierUid,aBuffer,&aResponse,KNullClientId);
1.1704 + }
1.1705 +
1.1706 +//
1.1707 +// class CChannelMonitor
1.1708 +//
1.1709 +
1.1710 +CChannelMonitor* CChannelMonitor::NewL()
1.1711 + {
1.1712 + CChannelMonitor* self=new(ELeave) CChannelMonitor;
1.1713 + return self;
1.1714 + }
1.1715 +
1.1716 +TBool CChannelMonitor::AlreadyHasChannel(TUid aChannel)const
1.1717 + {
1.1718 + const TInt count=iMonitor.Count();
1.1719 + for (TInt ii=0;ii<count;ii++)
1.1720 + {
1.1721 + if (iMonitor[ii].iChannel==aChannel)
1.1722 + return ETrue;
1.1723 + }
1.1724 + return EFalse;
1.1725 + }
1.1726 +
1.1727 +TInt CChannelMonitor::ActivityLevel(TUid aChannel) const
1.1728 + {
1.1729 + const TInt count=iMonitor.Count();
1.1730 + for (TInt ii=0;ii<count;ii++)
1.1731 + {
1.1732 + TChannelActivity activity=iMonitor[ii];
1.1733 + if (activity.iChannel==aChannel)
1.1734 + return activity.iHighestPriorityRunning;
1.1735 + }
1.1736 + return 0;
1.1737 + }
1.1738 +
1.1739 +void CChannelMonitor::UpdateChannel(TUid aChannel,TInt aLevel)
1.1740 + {
1.1741 + const TInt count=iMonitor.Count();
1.1742 + for (TInt ii=0;ii<count;ii++)
1.1743 + {
1.1744 + TChannelActivity& activity=iMonitor[ii];
1.1745 + if (activity.iChannel==aChannel)
1.1746 + {
1.1747 + activity.iHighestPriorityRunning=aLevel;
1.1748 + break;
1.1749 + }
1.1750 + }
1.1751 + }
1.1752 +
1.1753 +CChannelMonitor::CChannelMonitor()
1.1754 + :iMonitor(3)
1.1755 + {}
1.1756 +
1.1757 +//
1.1758 +// class CNotifierActivity
1.1759 +//
1.1760 +
1.1761 +CNotifierActivity* CNotifierActivity::NewLC(const MNotifierBase2::TNotifierInfo& aInfo,TInt aClientId)
1.1762 + { // static
1.1763 + CNotifierActivity* self=new(ELeave) CNotifierActivity(aInfo);
1.1764 + CleanupStack::PushL(self);
1.1765 + self->ConstructL(aClientId);
1.1766 + return self;
1.1767 + }
1.1768 +
1.1769 +CNotifierActivity::~CNotifierActivity()
1.1770 + {
1.1771 + iClientArray.Reset();
1.1772 + }
1.1773 +
1.1774 +TInt CNotifierActivity::Find(TInt aClientId) const
1.1775 + {
1.1776 + TInt index=KErrNotFound;
1.1777 + const TInt count=iClientArray.Count();
1.1778 + for (TInt ii=0;ii<count;ii++)
1.1779 + {
1.1780 + TInt clientId=iClientArray[ii];
1.1781 + if (clientId==aClientId)
1.1782 + {
1.1783 + index=ii;
1.1784 + break;
1.1785 + }
1.1786 + }
1.1787 + return index;
1.1788 + }
1.1789 +
1.1790 +CNotifierActivity::CNotifierActivity(const MNotifierBase2::TNotifierInfo& aInfo)
1.1791 + : iInfo(aInfo), iClientArray(1)
1.1792 + {}
1.1793 +
1.1794 +void CNotifierActivity::ConstructL(TInt aClientId)
1.1795 + {
1.1796 + iClientArray.AppendL(aClientId);
1.1797 + }
1.1798 +
1.1799 +//
1.1800 +// class CActivityMonitor
1.1801 +//
1.1802 +
1.1803 +CActivityMonitor* CActivityMonitor::NewL()
1.1804 + { // static
1.1805 + CActivityMonitor* self=new(ELeave) CActivityMonitor();
1.1806 + return self;
1.1807 + }
1.1808 +
1.1809 +CActivityMonitor::~CActivityMonitor()
1.1810 + {
1.1811 + iMonitor.ResetAndDestroy();
1.1812 + }
1.1813 +
1.1814 +void CActivityMonitor::AddL(const MNotifierBase2::TNotifierInfo& aInfo,TInt aClientId)
1.1815 + {
1.1816 + const TInt index=Find(aInfo.iUid,aInfo.iChannel);
1.1817 + if (index==KErrNotFound)
1.1818 + {
1.1819 + CNotifierActivity* activity=CNotifierActivity::NewLC(aInfo,aClientId);
1.1820 + iMonitor.AppendL(activity);
1.1821 + CleanupStack::Pop(); // activity
1.1822 + }
1.1823 + else
1.1824 + {
1.1825 + iMonitor[index]->iClientArray.AppendL(aClientId);
1.1826 + }
1.1827 + }
1.1828 +
1.1829 +void CActivityMonitor::Remove(TUid aNotifierUid,TInt aClientId)
1.1830 + {
1.1831 + const TInt index=Find(aNotifierUid);
1.1832 + if (index!=KErrNotFound)
1.1833 + {
1.1834 + CNotifierActivity* activity=iMonitor[index];
1.1835 + const TInt clientIndex=activity->Find(aClientId);
1.1836 + if (clientIndex!=KErrNotFound)
1.1837 + {
1.1838 + if (activity->iClientArray.Count()==1)
1.1839 + {
1.1840 + delete activity;
1.1841 + iMonitor.Delete(index);
1.1842 + }
1.1843 + else
1.1844 + {
1.1845 + activity->iClientArray.Delete(index);
1.1846 + }
1.1847 + }
1.1848 + }
1.1849 + }
1.1850 +
1.1851 +void CActivityMonitor::RemoveNotifier(TUid aNotifierUid,TUid aChannel)
1.1852 + {
1.1853 + const TInt index=Find(aNotifierUid,aChannel);
1.1854 + if (index!=KErrNotFound)
1.1855 + {
1.1856 + delete iMonitor[index];
1.1857 + iMonitor.Delete(index);
1.1858 + }
1.1859 + }
1.1860 +
1.1861 +void CActivityMonitor::RemoveClient(TInt aClientId)
1.1862 + {
1.1863 + TInt ii=0;
1.1864 + while (ii<iMonitor.Count())
1.1865 + {
1.1866 + CNotifierActivity* ptr=iMonitor[ii];
1.1867 + TInt index=ptr->Find(aClientId);
1.1868 + if (index!=KErrNotFound)
1.1869 + {
1.1870 + ptr->iClientArray.Delete(index);
1.1871 + }
1.1872 + if (ptr->iClientArray.Count()==0)
1.1873 + {
1.1874 + iMonitor.Delete(ii);
1.1875 + }
1.1876 + else
1.1877 + {
1.1878 + ++ii;
1.1879 + }
1.1880 + }
1.1881 + }
1.1882 +
1.1883 +TBool CActivityMonitor::IsNotifierActive(TUid aNotifierUid,TUid aChannel) const
1.1884 + {
1.1885 + const TInt index=Find(aNotifierUid,aChannel);
1.1886 + return (index!=KErrNotFound);
1.1887 + }
1.1888 +
1.1889 +TBool CActivityMonitor::IsClientPresent(TUid aNotifierUid,TUid aChannel,TInt aClientId) const
1.1890 + {
1.1891 + TBool found=EFalse;
1.1892 + const TInt index=Find(aNotifierUid,aChannel);
1.1893 + if (index!=KErrNotFound)
1.1894 + {
1.1895 + found=(iMonitor[index]->Find(aClientId)!=KErrNotFound);
1.1896 + }
1.1897 + return found;
1.1898 + }
1.1899 +
1.1900 +TBool CActivityMonitor::IsChannelActive(TUid aChannel,TUid& aNotifier,MNotifierBase2::TNotifierPriority& aHighestPriority) const
1.1901 + {
1.1902 + TBool ret=EFalse;
1.1903 + const TInt count=iMonitor.Count();
1.1904 + for (TInt ii=0;ii<count;ii++)
1.1905 + {
1.1906 + MNotifierBase2::TNotifierInfo info=iMonitor[ii]->iInfo;
1.1907 + if (info.iChannel==aChannel)
1.1908 + {
1.1909 + ret=ETrue;
1.1910 + if ((MNotifierBase2::TNotifierPriority)info.iPriority>aHighestPriority)
1.1911 + {
1.1912 + aNotifier=info.iUid;
1.1913 + aHighestPriority=(MNotifierBase2::TNotifierPriority)info.iPriority;
1.1914 + }
1.1915 + }
1.1916 + }
1.1917 + return ret;
1.1918 + }
1.1919 +
1.1920 +TBool CActivityMonitor::NotifierForClient(TUid& aNotifierUid,TInt aClientId) const
1.1921 + {
1.1922 + TBool isOnlyClient=EFalse;
1.1923 + aNotifierUid=KNullUid;
1.1924 + const TInt count=iMonitor.Count();
1.1925 + for (TInt ii=0;ii<count;ii++)
1.1926 + {
1.1927 + CNotifierActivity* ptr=iMonitor[ii];
1.1928 + if (ptr->Find(aClientId)!=KErrNotFound)
1.1929 + {
1.1930 + aNotifierUid=ptr->iInfo.iUid;
1.1931 + isOnlyClient=ptr->iClientArray.Count()==1;
1.1932 + break;
1.1933 + }
1.1934 + }
1.1935 + return isOnlyClient;
1.1936 + }
1.1937 +
1.1938 +CActivityMonitor::CActivityMonitor()
1.1939 + : iMonitor(1)
1.1940 + {}
1.1941 +
1.1942 +TInt CActivityMonitor::Find(TUid aNotifierUid) const
1.1943 + {
1.1944 + TInt index=KErrNotFound;
1.1945 + const TInt count=iMonitor.Count();
1.1946 + for (TInt ii=0;ii<count;ii++)
1.1947 + {
1.1948 + if (iMonitor[ii]->iInfo.iUid==aNotifierUid)
1.1949 + {
1.1950 + index=ii;
1.1951 + break;
1.1952 + }
1.1953 + }
1.1954 + return index;
1.1955 + }
1.1956 +
1.1957 +TInt CActivityMonitor::Find(TUid aNotifierUid,TUid aChannel) const
1.1958 + {
1.1959 + TInt index=KErrNotFound;
1.1960 + const TInt count=iMonitor.Count();
1.1961 + for (TInt ii=0;ii<count;ii++)
1.1962 + {
1.1963 + CNotifierActivity* ptr=iMonitor[ii];
1.1964 + if (ptr->iInfo.iUid==aNotifierUid && ptr->iInfo.iChannel==aChannel)
1.1965 + {
1.1966 + index=ii;
1.1967 + break;
1.1968 + }
1.1969 + }
1.1970 + return index;
1.1971 + }
1.1972 +
1.1973 +//
1.1974 +// class CQueueItem
1.1975 +//
1.1976 +
1.1977 +CQueueItem* CQueueItem::NewL(const MNotifierBase2::TNotifierInfo& aInfo,const TDesC8& aBuffer,
1.1978 + TInt aReplySlot,const RMessage2& aMessage,TInt aClientId) //Asynchronous
1.1979 + {
1.1980 + CQueueItem* self=new(ELeave) CQueueItem(aInfo);
1.1981 + CleanupStack::PushL(self);
1.1982 + self->ConstructL(aBuffer,aMessage,aClientId,aReplySlot);
1.1983 + CleanupStack::Pop(); // self
1.1984 + return self;
1.1985 + }
1.1986 +
1.1987 +CQueueItem* CQueueItem::NewL(const MNotifierBase2::TNotifierInfo& aInfo,const TDesC8& aBuffer,TInt aClientId) //synchronous
1.1988 + {
1.1989 + CQueueItem* self=new(ELeave) CQueueItem(aInfo);
1.1990 + CleanupStack::PushL(self);
1.1991 + self->ConstructL(aBuffer,aClientId);
1.1992 + CleanupStack::Pop(); // self
1.1993 + return self;
1.1994 + }
1.1995 +
1.1996 +CQueueItem::~CQueueItem()
1.1997 + {
1.1998 + delete iBuffer;
1.1999 + }
1.2000 +
1.2001 +CQueueItem::CQueueItem(const MNotifierBase2::TNotifierInfo& aInfo)
1.2002 + : iInfo(aInfo)
1.2003 + {}
1.2004 +
1.2005 +void CQueueItem::ConstructL(const TDesC8& aBuffer,TInt aClientId)
1.2006 + {
1.2007 + iBuffer=aBuffer.AllocL();
1.2008 + iClientId=aClientId;
1.2009 + iAsynchronous=EFalse;
1.2010 + }
1.2011 +
1.2012 +void CQueueItem::ConstructL(const TDesC8& aBuffer,const RMessage2& aMessage,TInt aClientId,TInt aReplySlot)
1.2013 + {
1.2014 + iBuffer=aBuffer.AllocL();
1.2015 + iAsynchronous=ETrue;
1.2016 + iMessage=aMessage;
1.2017 + iClientId=aClientId;
1.2018 + iReplySlot=aReplySlot;
1.2019 + }
1.2020 +
1.2021 +//
1.2022 +// class CNotifierQueue
1.2023 +//
1.2024 +
1.2025 +CNotifierQueue* CNotifierQueue::NewL()
1.2026 + {
1.2027 + CNotifierQueue* self=new(ELeave) CNotifierQueue;
1.2028 + return self;
1.2029 + }
1.2030 +
1.2031 +CQueueItem* CNotifierQueue::FetchItem(TUid aChannel)
1.2032 + {
1.2033 + CQueueItem* result=NULL;
1.2034 + const TInt count=iQueue.Count();
1.2035 + TInt priority=MNotifierBase2::ENotifierPriorityLowest-1;
1.2036 + TInt index=KErrNotFound;
1.2037 + for (TInt ii=0;ii<count;ii++)
1.2038 + {
1.2039 + CQueueItem* item=iQueue[ii];
1.2040 + if (item->iInfo.iChannel==aChannel && item->iInfo.iPriority>priority)
1.2041 + {
1.2042 + index=ii;
1.2043 + priority=item->iInfo.iPriority;
1.2044 + result=item;
1.2045 + }
1.2046 + }
1.2047 + if (index!=KErrNotFound)
1.2048 + {
1.2049 + iQueue.Delete(index);
1.2050 + }
1.2051 + return result;
1.2052 + }
1.2053 +
1.2054 +TBool CNotifierQueue::IsAlreadyQueued(TUid aNotifier,TUid aChannel) const
1.2055 + {
1.2056 + TBool ret=EFalse;
1.2057 + const TInt count=iQueue.Count();
1.2058 + for (TInt ii=0;ii<count;ii++)
1.2059 + {
1.2060 + CQueueItem* item=iQueue[ii];
1.2061 + if (item->iInfo.iUid==aNotifier && item->iInfo.iChannel==aChannel)
1.2062 + {
1.2063 + ret=ETrue;
1.2064 + break;
1.2065 + }
1.2066 + }
1.2067 + return ret;
1.2068 + }
1.2069 +
1.2070 +void CNotifierQueue::RemoveClient(TInt aClientId)
1.2071 + {
1.2072 + const TInt count=iQueue.Count();
1.2073 + for (TInt ii=count-1;ii>=0;ii--)
1.2074 + {
1.2075 + CQueueItem* item=iQueue[ii];
1.2076 + TInt clientId=item->iClientId;
1.2077 + if (clientId==aClientId)
1.2078 + {
1.2079 + iQueue.Delete(ii);
1.2080 + }
1.2081 + }
1.2082 + }
1.2083 +
1.2084 +
1.2085 +TInt CNotifierQueue::GetHighestQueuePriority(TUid aChannel)
1.2086 + {
1.2087 + const TInt count=iQueue.Count();
1.2088 + TInt priority=MNotifierBase2::ENotifierPriorityLowest-1;
1.2089 +
1.2090 + for (TInt ii=0;ii<count;ii++)
1.2091 + {
1.2092 + CQueueItem* item=iQueue[ii];
1.2093 + if (item->iInfo.iChannel==aChannel && item->iInfo.iPriority>priority)
1.2094 + {
1.2095 + priority=item->iInfo.iPriority;
1.2096 + }
1.2097 + }
1.2098 +
1.2099 + return priority;
1.2100 + }
1.2101 +
1.2102 +
1.2103 +void CWsActiveScheduler::New()
1.2104 +//
1.2105 +// Create and install the active scheduler.
1.2106 +//
1.2107 + {
1.2108 +
1.2109 + CWsActiveScheduler *pA=new CWsActiveScheduler;
1.2110 + __ASSERT_ALWAYS(pA!=NULL,Fault(ECreateScheduler));
1.2111 + CActiveScheduler::Install(pA);
1.2112 + }
1.2113 +
1.2114 +void CWsActiveScheduler::Error(TInt) const
1.2115 +//
1.2116 +// Called if any Run() method leaves.
1.2117 +//
1.2118 + {
1.2119 + }
1.2120 +
1.2121 +
1.2122 +TInt NotifierServerThread(TAny*)
1.2123 + {
1.2124 + CTrapCleanup* CleanUpStack=CTrapCleanup::New();
1.2125 + CWsActiveScheduler::New();
1.2126 + TRAP_IGNORE(CNotifierServer::NewL());
1.2127 + CNotifierSession::NotifierSemaphore.Signal();
1.2128 + CWsActiveScheduler::Start();
1.2129 + delete CleanUpStack;
1.2130 + return(0);
1.2131 + }
1.2132 +
1.2133 +
1.2134 +_LIT(KLitKeyDataDllNameBase, "EKDATA");
1.2135 +_LIT(TwoDigExt,".%02d");
1.2136 +
1.2137 +GLDEF_C TInt E32Main()
1.2138 + {
1.2139 + UserSvr::WsRegisterThread();
1.2140 + UserSvr::WsRegisterSwitchOnScreenHandling(ETrue);
1.2141 + User::SetProcessCritical(User::ESystemPermanent);
1.2142 + User::SetCritical(User::ESystemPermanent);
1.2143 +
1.2144 + CWsActiveScheduler::New();
1.2145 + CWsServer::New();
1.2146 + CWsWindow::New();
1.2147 + CEvent::New();
1.2148 +
1.2149 + KeyTranslator=CKeyTranslator::New();
1.2150 + if (!KeyTranslator)
1.2151 + Fault(ENoKeyboardTranslator);
1.2152 +
1.2153 +// Change keyboard mapping according to information in the HAL
1.2154 +// This code is the same as WSERV
1.2155 + TInt keyboardIndex;
1.2156 + if (HAL::Get(HALData::EKeyboardIndex,keyboardIndex)==KErrNone)
1.2157 + {
1.2158 + TBuf<16> keyDataDllName(KLitKeyDataDllNameBase);
1.2159 + keyDataDllName.AppendFormat(TwoDigExt, keyboardIndex);
1.2160 + KeyTranslator->ChangeKeyData(keyDataDllName);
1.2161 + }
1.2162 +
1.2163 + KeyRepeat=new(ELeave) CKeyRepeat(CKeyRepeat::EKeyRepeatPriority);
1.2164 + TRAPD(r,KeyRepeat->ConstructL());
1.2165 + if (r!=KErrNone)
1.2166 + User::Panic(_L("KEYREPEAT"),r);
1.2167 +
1.2168 +#ifndef __WINS__
1.2169 + if (UserSvr::TestBootSequence())
1.2170 + {
1.2171 + RDebug::Print(_L("WS_MAIN: TestBootSequence=TRUE, not loading ESHELL.EXE"));
1.2172 + }
1.2173 +#else
1.2174 + if (EmulatorAutoRun())
1.2175 + { // don't start ESHELL if we used a self-bootstrapping EXE
1.2176 + }
1.2177 +#endif
1.2178 + else
1.2179 + {
1.2180 + RProcess shell;
1.2181 + r=shell.Create(KShellProcessName, KShellCommandLine);
1.2182 + __ASSERT_ALWAYS(r==KErrNone,Fault(ECreateShell));
1.2183 + shell.Resume();
1.2184 + shell.Close();
1.2185 + }
1.2186 +
1.2187 + RThread t;
1.2188 + r=CNotifierSession::NotifierSemaphore.CreateLocal(0);
1.2189 + if (r!=KErrNone)
1.2190 + Fault(ECreateNotifierSemaphore);
1.2191 + r=t.Create(_L("NotifierServer"),NotifierServerThread,KDefaultStackSize,0x2000,0x100000,NULL);
1.2192 + if (r!=KErrNone)
1.2193 + Fault(ECreateNotifierThread);
1.2194 + t.Resume();
1.2195 + CNotifierSession::NotifierSemaphore.Wait();
1.2196 +
1.2197 + CWsActiveScheduler::Start();
1.2198 + UserSvr::ReleaseEventHook();
1.2199 + return(KErrNone);
1.2200 + }
1.2201 +