--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingtestenv/imagingtestfw/Source/TestFrameworkServer/TestFrameworkServer.cpp Wed Aug 25 12:29:52 2010 +0300
@@ -0,0 +1,765 @@
+// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <e32svr.h>
+
+#include "TestFrameworkServer.h"
+
+#include "TestFrameworkServer.inl"
+
+#include <testframeworkipc.h>
+
+
+/**
+ *
+ * Initiate server exit when the timer expires
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServerShutdown::RunL()
+ {
+ CActiveScheduler::Stop();
+ }
+
+/**
+ *
+ * Test Framework server static constructor
+ * NOTE : only one instance of the server process should run
+ * during any Test Framework run; all client sessions
+ * will use this one instance.
+ *
+ * @xxxx
+ *
+ */
+CMmfIpcServer* CTestFrameworkServer::NewL()
+ {
+ CTestFrameworkServer* s = new(ELeave) CTestFrameworkServer;
+ CleanupStack::PushL(s);
+ s->ConstructL();
+ CleanupStack::Pop();
+ return s;
+ }
+
+/**
+ *
+ * Test Framework server first-phase constructor
+ *
+ * @xxxx
+ *
+ */
+CTestFrameworkServer::CTestFrameworkServer()
+ :CMmfIpcServer(0, ESharableSessions)
+ {
+ }
+
+// set up so that iConsole is NULL. A call to OpenLogL will initialise the console
+// and file (if any)
+
+/**
+ *
+ * Test Framework server second-phase constructor
+ * Starts the server; does not initialise the log
+ * (this must be done independently with a call to OpenLogL)
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServer::ConstructL()
+ {
+ StartL(KTestFrameworkServerName);
+ //Ensure that the server will exit even if the first client fails to connect
+ iShutdown.ConstructL();
+ iShutdown.Start();
+
+ iLogMode = 0; // initial value : not running any log
+ iConsole = NULL;
+ iFileLogger = NULL;
+ }
+
+/**
+ *
+ * Test Framework server destructor
+ *
+ * @xxxx
+ *
+ */
+CTestFrameworkServer::~CTestFrameworkServer()
+ {
+ CloseLog();
+ }
+
+/**
+ *
+ * Create new server session.
+ *
+ * @param "const TVersion &aVersion"
+ * Server version (required)
+ *
+ * @return "CSharableSession*"
+ * The created server session.
+ *
+ * @xxxx
+ *
+ */
+CMmfIpcSession* CTestFrameworkServer::NewSessionL(const TVersion &aVersion) const
+ {
+ TVersion ver(KTestFrameworkServerMajorVersionNumber,
+ KTestFrameworkServerMinorVersionNumber,
+ KTestFrameworkServerBuildVersionNumber);
+ if (!User::QueryVersionSupported(ver, aVersion))
+ User::Leave(KErrNotSupported);
+ // make new session
+ return new(ELeave) CTestFrameworkServerSession();
+ }
+
+/**
+ *
+ * Add a server session.
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServer::AddSession()
+ {
+ ++iSessionCount;
+ iShutdown.Cancel();
+ }
+
+/**
+ *
+ * Drop a server session.
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServer::DropSession()
+ {
+ if (--iSessionCount <= 0)
+ iShutdown.Start();
+ }
+
+/**
+ *
+ * Add an input window (at request from client).
+ *
+ * @param "CTestFrameworkServerSession* aOwner"
+ * Window owning server session
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServer::AddInputWindowL(CTestFrameworkServerSession* aOwner)
+ {
+ if (iInputWindow.HasOwner())
+ User::Leave(KErrAlreadyExists);
+ // else
+ iInputWindow.SetOwner(aOwner);
+ TRect rect;
+ rect.iTl = TPoint(0,0);
+ rect.iBr = TPoint(KConsFullScreen, KConsFullScreen);
+ iInputWindow.SetWinRectAndNotifyOwner(rect);
+ }
+
+/**
+ *
+ * Remove an input window (at request from client).
+ *
+ * @param "CTestFrameworkServerSession* aOwner"
+ * Window owning server session
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServer::RemoveWindow(CTestFrameworkServerSession* aOwner)
+ {
+ if (aOwner == iInputWindow.Owner())
+ {
+ iInputWindow.SetOwner(NULL);
+ }
+ }
+
+/**
+ *
+ * Open a log.
+ *
+ * @param "const TDesC& aLogName"
+ * The log name
+ *
+ * @param "TInt aLogMode"
+ * The log mode (as bitmask of TTestFrameworkLogMode)
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServer::OpenLogL(const TDesC& aLogName, TInt aLogMode)
+ {
+ // NB we need to check if a console is already open - if so, we do NOT
+ // create another one. Ditto with file / port.
+
+ if(aLogMode & ELogToConsole)
+ {
+ if(!iConsole)
+ {
+ iConsole = CServerConsole::NewL(aLogName);
+
+ CConsoleBase* theConsole = iConsole->Console();
+ theConsole->Printf(_L("%S : Server log starting\n"), &aLogName);
+
+ iLogMode |= ELogToConsole;
+
+ if (aLogMode & ELogConsoleFull)
+ iLogMode |= ELogConsoleFull;
+
+ iConsole->Read(*this);
+
+ }
+ }
+
+ // NB relative paths will not work with TParse (there is no file server open).
+ // Exception is a bare filename (with no path) : this will be found in root of C:
+
+ // NOTE! We have no mechanism to notify this error. The console will display
+ // and then exit. The log file cannot be opened.
+
+ // TO BE ENHANCED - if console is made active, then we can pause
+
+ if(aLogMode & ELogToFile)
+ {
+ if(!iFileLogger)
+ {
+ TRAPD(err, iFileLogger = CFileLogger::NewL());
+ if(err != KErrNone)
+ {
+ // if we can't create a logger, we panic
+ User::Panic(_L("TestFrameworkServer"), 1);
+ }
+
+ _LIT(KLogPath, "C:\\Logs\\TestResults");
+ _LIT(KDefault, "C:\\.htm");
+
+ TParse parseLogName;
+ parseLogName.Set(aLogName, NULL, NULL);
+
+ TFileName logFilePath;
+ logFilePath = KLogPath;
+
+ if(parseLogName.PathPresent())
+ logFilePath.Append(parseLogName.Path());
+ else
+ logFilePath.Append(_L("\\"));
+
+
+ // overwrite extension if supplied with .htm
+ TParse logFileFullName;
+ TInt returnCode = logFileFullName.Set(KDefault, &logFilePath, &aLogName);
+ if (returnCode == KErrNone)
+ {
+ TInt ret = iFileLogger->Connect();
+ if (ret == KErrNone)
+ {
+ iFileLogger->CreateLog(logFilePath, logFileFullName.NameAndExt());
+ iLogMode |= ELogToFile;
+ }
+ }
+ }
+ }
+
+ if(aLogMode & ELogToPort)
+ {
+ // RDebug::Print will deal with the serial port, we don't do anything special here
+ iLogMode |= ELogToPort;
+ }
+ }
+
+/**
+ *
+ * Write to the log.
+ *
+ * @param "const TDesC& aMsg"
+ * The message string to write
+ *
+ * @param "TInt aLogMode"
+ * The log mode (as bitmask of TTestFrameworkLogMode)
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServer::WriteLog(const TDesC& aMsg, TInt aLogMode)
+ {
+ if(aLogMode & ELogToConsole)
+ {
+ if(iConsole)
+ {
+ CConsoleBase* theConsole = iConsole->Console();
+ theConsole->Printf(aMsg);
+ theConsole->Printf(_L("\n")); // add newline
+ }
+ }
+
+ if(aLogMode & ELogToFile)
+ {
+ if(iFileLogger)
+ {
+ iFileLogger->WriteLog(aMsg);
+ }
+ }
+
+ if(aLogMode & ELogToPort)
+ {
+ RDebug::Print(aMsg);
+ }
+ }
+
+/**
+ *
+ * Close the log.
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServer::CloseLog()
+ {
+ if (iFileLogger != NULL)
+ iFileLogger->CloseLog();
+ delete(iFileLogger);
+ iFileLogger = NULL;
+ delete(iConsole);
+ iConsole = NULL;
+ iLogMode = 0;
+ }
+
+/**
+ *
+ * Get the log status.
+ *
+ * @return "TInt"
+ * The log status (as bitmask of TTestFrameworkLogMode)
+ *
+ * @xxxx
+ *
+ */
+TInt CTestFrameworkServer::LogStatus() const
+ {
+ return iLogMode;
+ }
+
+
+/**
+ *
+ * process key input from console.
+ *
+ * @param "TKeyCode aKeystroke"
+ * The keystroke
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServer::InputReceived(TKeyCode aKeystroke)
+ {
+ // store it
+ iInputKey = STATIC_CAST(TInt, aKeystroke);
+
+ // key not processed as yet - pending implementation of async request from client
+
+ //read from console again
+ iConsole->Read(*this);
+ }
+
+/**
+ *
+ * Display general error.
+ *
+ * @param "TInt aError"
+ * The error code
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServer::Error(TInt)
+ {
+ // stubbed; undefined input keys can be safely discarded
+ }
+
+/**
+ *
+ * Default window constructor (no owner)
+ *
+ * @xxxx
+ *
+ */
+TWindow::TWindow()
+ {
+ iOwner = NULL;
+ }
+
+/**
+ *
+ * Default window constructor
+ *
+ * @param "CTestFrameworkServerSession* aOwner"
+ * The window owner
+ * @xxxx
+ *
+ */
+TWindow::TWindow(CTestFrameworkServerSession* aOwner)
+ {
+ iOwner = aOwner;
+ }
+
+/**
+ *
+ * Set the window owner
+ *
+ * @param "CTestFrameworkServerSession* aOwner"
+ * The window owner
+ * @xxxx
+ *
+ */
+void TWindow::SetOwner(CTestFrameworkServerSession* aOwner)
+ {
+ iOwner = aOwner;
+ }
+
+/**
+ *
+ * Set the window rectangle, and notify owner
+ *
+ * @param "const TRect& aWinRect"
+ * The window rectangle
+ * @xxxx
+ *
+ */
+void TWindow::SetWinRectAndNotifyOwner(const TRect& aWinRect)
+ {
+ if (HasOwner())
+ iOwner->NotifyWindowChanged(aWinRect);
+ }
+
+/**
+ *
+ * Does this window have an owner?
+ *
+ * @return "TBool"
+ * ETrue if window has an owner
+ * @xxxx
+ *
+ */
+TBool TWindow::HasOwner()
+ {
+ if (iOwner)
+ return ETrue;
+ return EFalse;
+ }
+
+/**
+ *
+ * Server session first-phase constructor
+ *
+ * @xxxx
+ *
+ */
+CTestFrameworkServerSession::CTestFrameworkServerSession()
+ {
+ }
+
+/**
+ *
+ * Create a server session.
+ *
+ * @param "aServer"
+ * The server to add this session to
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServerSession::CreateL(const CMmfIpcServer& aServer)
+ {
+ CMmfIpcSession::CreateL(aServer); // does not leave
+ //Add session to server first. If anything leaves, it will be removed by the destructor
+ iServer = STATIC_CAST(CTestFrameworkServer*, (CONST_CAST(CMmfIpcServer*, &aServer)));
+ iServer->AddSession();
+ ConstructL();
+ }
+
+/**
+ *
+ * Server session second-phase constructor
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServerSession::ConstructL()
+ {
+ }
+
+/**
+ *
+ * Server session destructor
+ *
+ * @xxxx
+ *
+ */
+CTestFrameworkServerSession::~CTestFrameworkServerSession()
+ {
+ iServer->RemoveWindow(this);
+ iServer->DropSession();
+ }
+
+/**
+ *
+ * Server session service function
+ *
+ * @param "aMessage"
+ * The message to be serviced.
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServerSession::ServiceL(const RMmfIpcMessage& aMessage)
+ {
+ switch (aMessage.Function())
+ {
+ case ECreateInputWindow:
+ SetOwnCopyOfWindowMessageL(aMessage);
+ iServer->AddInputWindowL(this);
+ break;
+ case ENotifyIfWindowChange:
+ SetOwnCopyOfWindowMessageL(aMessage);
+ break;
+ case ECancelNotifyIfWindowChange:
+ CompleteOwnCopyOfWindowMessage(KErrCancel);
+ aMessage.Complete(KErrNone);
+ break;
+
+ // logging messages
+
+ case EOpenLog:
+ {
+ TBuf<KMaxLogFilenameLength> msgBuf;
+
+ TInt r = MmfMessageUtilX::Read(aMessage, 0, msgBuf);
+ if (r != KErrNone)
+ RunError(aMessage, r);
+ else
+ {
+ iServer->OpenLogL(msgBuf, aMessage.Int1());
+ aMessage.Complete(KErrNone);
+ }
+ }
+ break;
+
+ case EWriteLog:
+ {
+ TBuf<KMaxLogLineLength> msgBuf;
+
+ TInt r = MmfMessageUtilX::Read(aMessage, 0, msgBuf);
+
+ if (r != KErrNone)
+ RunError(aMessage, r);
+ else
+ {
+ iServer->WriteLog(msgBuf, aMessage.Int1());
+ aMessage.Complete(KErrNone);
+ }
+ }
+ break;
+
+ case ECloseLog:
+ iServer->CloseLog();
+ aMessage.Complete(KErrNone);
+ break;
+
+ case ELogStatus:
+ {
+ TPckgBuf<TInt> countPckg(iServer->LogStatus());
+ TInt r = MmfMessageUtilX::Write(aMessage, 0, countPckg);
+ if (r != KErrNone)
+ RunError(aMessage, r);
+ else
+ aMessage.Complete(KErrNone);
+ }
+ break;
+
+ default:
+ // ? should panic here
+ break;
+ }
+ }
+
+/**
+ *
+ * Error handler for server session.
+ * Completes the pending message using the error code
+ *
+ * @param "TInt aError"
+ * The error code
+ *
+ * @return "TInt"
+ * The error code (always KErrNone)
+ *
+ * @xxxx
+ *
+ */
+ TInt CTestFrameworkServerSession::RunError(const RMmfIpcMessage& aMessage, TInt aError)
+ {
+ aMessage.Complete(aError);
+ return KErrNone;
+ }
+
+/**
+ *
+ * Set own copy of message.
+ * Helper function to enable window change notification.
+ *
+ * @param "aMessage"
+ * The message to be serviced.
+ *
+ * @xxxx
+ *
+ */
+ void CTestFrameworkServerSession::SetOwnCopyOfWindowMessageL(const RMmfIpcMessage& aMessage)
+ {
+ if (iCanCompleteWindowMessage)
+ User::Leave(KErrAlreadyExists);
+ //else
+ iWindowMessage = aMessage;
+ iCanCompleteWindowMessage = ETrue;
+
+ if (iNeedToNotifyClientOfWindowSizeChange)
+ {
+ TInt err = MmfMessageUtil::Write(iWindowMessage, 0, iWinRectBuf);
+ CompleteOwnCopyOfWindowMessage(err);
+ iNeedToNotifyClientOfWindowSizeChange = EFalse;
+ }
+ }
+
+/**
+ *
+ * Complete own copy of message.
+ * Helper function to enable window change notification.
+ *
+ * @param "TInt aReason"
+ * The message return code.
+ *
+ * @xxxx
+ *
+ */
+ void CTestFrameworkServerSession::CompleteOwnCopyOfWindowMessage(TInt aReason)
+ {
+ if (iCanCompleteWindowMessage)
+ iWindowMessage.Complete(aReason);
+ iCanCompleteWindowMessage = EFalse;
+ }
+
+/**
+ *
+ * Window change notification.
+ *
+ * @param "const TRect& aWinRect"
+ * The window rectangle.
+ *
+ * @xxxx
+ *
+ */
+void CTestFrameworkServerSession::NotifyWindowChanged(const TRect& aWinRect)
+ {
+ iWinRectBuf() = aWinRect;
+
+ if (iCanCompleteWindowMessage)
+ {
+ TInt err = MmfMessageUtilX::Write(iWindowMessage, 0, iWinRectBuf);
+ CompleteOwnCopyOfWindowMessage(err);
+ }
+ else
+ {
+ iNeedToNotifyClientOfWindowSizeChange = ETrue;
+ }
+ }
+
+// EXE/DLL initialisation
+
+// NOTE! None of this should be built when compiling for Unit Testing
+#if !defined (__TSU_TESTFRAMEWORK__)
+
+
+/**
+ *
+ * Perform all server initialisation, in particular creation of the
+ * scheduler and server; then run the scheduler
+ *
+ *
+ * @xxxx
+ *
+ */
+static void RunServerL()
+ {
+ // create and install the active scheduler we need
+ CActiveScheduler* s = new(ELeave) CActiveScheduler;
+ CleanupStack::PushL(s);
+ CActiveScheduler::Install(s);
+ //
+ // create the server (leave it on the cleanup stack)
+ CleanupStack::PushL(CTestFrameworkServer::NewL());
+ //
+ // Initialisation complete, now signal the client
+ RProcess::Rendezvous(KErrNone);
+
+ //
+ // Ready to run
+ CActiveScheduler::Start();
+ //
+ // Cleanup the server and scheduler
+ CleanupStack::PopAndDestroy(2);
+ }
+
+/**
+ *
+ * Main entry point for the server thread
+ *
+ * @param "TTestFrameworkServerStart& aStart"
+ * The server starter.
+ *
+ * @xxxx
+ *
+ */
+static TInt RunServer()
+ {
+ __UHEAP_MARK;
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ TInt r = KErrNoMemory;
+ if (cleanup)
+ {
+ TRAP(r, RunServerL());
+ delete cleanup;
+ }
+ //
+ __UHEAP_MARKEND;
+ return r;
+ }
+
+
+GLDEF_C TInt E32Main()
+
+// Server process entry-point
+// Recover the startup parameters and run the server
+
+ {
+ TInt r = RunServer();
+ return r;
+ }
+
+
+#endif // __TSU_TESTFRAMEWORK__