diff -r 095bea5f582e -r 0ac9a5310753 mmserv/sts/stsproxy/src/rstssession.cpp --- a/mmserv/sts/stsproxy/src/rstssession.cpp Tue Aug 31 15:43:02 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,359 +0,0 @@ -/* - * Copyright (c) 2010 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: - * The file provides the implementation of the client side session - * to the STS Server. - */ - -// Include Files -#include "rstssession.h" -#include "stsclientservercommon.h" - -const TUint KNumSlots = 30; - -/*static*/TInt RStsSession::CallBackThreadMain(TAny* aSession) - { - TInt err = KErrNoMemory; - - RThread myThread; - myThread.SetPriority(EPriorityAbsoluteHigh); - myThread.Close(); - - CTrapCleanup* cleanup = CTrapCleanup::New(); - - if (cleanup) - { - // Run the server and request a thread rendezvous. - TRAP( err, ((RStsSession*)aSession)->RunThreadL() ); - delete cleanup; - } - - return err; - } - -void RStsSession::RunThreadL() - { - iState = ERunning; - // Initialisation complete, now signal the client, if requested. - RThread::Rendezvous(KErrNone); - TRequestStatus queueStatus = KRequestPending; - iMsgQueue.NotifyDataAvailable(queueStatus); - - RThread server; - TInt err = server.Open(iServerThreadId); - TRequestStatus serverStatus = KRequestPending; - server.Logon(serverStatus); - - while (iState == ERunning) - { - TStsCallBack message; - // Using ReceiveBlocking here would block forever if the executive thread - // dies, so instead wait for either a data available notification or a - // notification that the executive thread has died. - User::WaitForRequest(queueStatus, serverStatus); - - if (queueStatus != KRequestPending) - { - TInt err = iMsgQueue.Receive(message); - if (err == KErrNone) - { - HandleMessage(message); - } - else - { - //TODO:Log a message - } - queueStatus = KRequestPending; - iMsgQueue.NotifyDataAvailable(queueStatus); - } - if (serverStatus != KRequestPending && iState == ERunning) - { - //TODO: Log a message - //Restart the server - SignalObservers(); - server.Close(); - CreateServerSession(); - TInt err = server.Open(iServerThreadId); - TRequestStatus serverStatus = KRequestPending; - server.Logon(serverStatus); - } - } - - iMsgQueue.CancelDataAvailable(); - server.LogonCancel(serverStatus); - server.Close(); - } - -void RStsSession::HandleMessage(TStsCallBack& aMessage) - { - bool signalObserver = false; - TStsCallBackType type = aMessage.callBackType; - if (type == EStsPlayAlarmComplete) - { - MStsPlayAlarmObserver* observer = aMessage.observer; - unsigned int context = aMessage.alarmContext; - iObserverMutex.Wait(); - if (observer == iObserverMap[context]) - { - signalObserver = true; - } - else - { - //TODO: Log a message - } - iObserverMap.erase(context); - iObserverMutex.Signal(); - if (signalObserver) - { - observer->PlayAlarmComplete(aMessage.alarmContext); - } - } - else if (type == EStsShutdown) - { - iState = EStopping; - } - else - { - //TODO: Log error message - } - } - -TInt RStsSession::StartServer() - { - TInt err = KErrNone; - - // Launch the server executable (i.e. in it its own process). - - // Create a new server process. Simultaneous launching of two such processes - // should be detected when the second one attempts to create the server - // object, failing with KErrAlreadyExists. - RProcess server; - err = server.Create(KStsServerFile, KNullDesC); - - if (err == KErrNone) - { - TRequestStatus rendezvousStatus; - server.Rendezvous(rendezvousStatus); - server.Resume(); - - // wait for start or death - User::WaitForRequest(rendezvousStatus); - - // we can't use the 'exit reason' if the server panicked as this - // is the panic 'reason' and may be '0' which cannot be distinguished - // from KErrNone - if (server.ExitType() == EExitPanic) - { - err = KErrGeneral; - } - else - { - err = rendezvousStatus.Int(); - } - } - server.Close(); - - return err; - } - -TInt RStsSession::StartThread() - { - TInt result = iThread.Create(KNullDesC, RStsSession::CallBackThreadMain, - KDefaultStackSize, &User::Heap(), (TAny*) this); - if (result == KErrNone) - { - TRequestStatus rendezvousStatus = KRequestPending; - - // Register for rendezvous notification when thread is started. - iThread.Rendezvous(rendezvousStatus); - - // Start the thread execution - iThread.Resume(); - - // Wait for thread to start. - User::WaitForRequest(rendezvousStatus); - - result = rendezvousStatus.Int(); - - if (result != KErrNone) - { - iThread.Kill(result); - } - } - return result; - } - -TInt RStsSession::CreateServerSession() - { - // Try to create a session with the server - TInt result = CreateSession(KStsServerName, TVersion( - KStsServerMajorVersion, KStsServerMinorVersion, KStsServerBuild), - KNumSlots, EIpcSession_Sharable); - - // If the server wasn't found, start the server and try creating a session again - if (result == KErrNotFound || result == KErrServerTerminated) - { - result = StartServer(); - if (result == KErrNone || result == KErrAlreadyExists) - { - result = CreateSession(KStsServerName, TVersion( - KStsServerMajorVersion, KStsServerMinorVersion, - KStsServerBuild), KNumSlots, EIpcSession_Sharable); - } - } - if (result == KErrNone) - { - TPckg idPckg(iServerThreadId); - result = SendReceive(StsMsg_RegisterMsgQueue, TIpcArgs(iMsgQueue, - &idPckg)); - } - return result; - } - -TInt RStsSession::Connect() - { - iState = EInitializing; - - // Create a nameless global message queue, then pass the handle to the queue to the server. - TInt result = iMsgQueue.CreateGlobal(KNullDesC, 30); - - // Create thread for receiving asynch callbacks from the server - if (result == KErrNone) - { - result = CreateServerSession(); - if (result == KErrNone) - { - result = StartThread(); - if (result == KErrNone) - { - result = iObserverMutex.CreateLocal(); - } - } - } - return result; - } - -void RStsSession::Close() - { - TRequestStatus logonStatus = KRequestPending; - iThread.Logon(logonStatus); - RSessionBase::Close(); - User::WaitForRequest(logonStatus); - iThread.Close(); - iMsgQueue.Close(); - CleanUpObservers(); - iObserverMutex.Close(); - } - -void RStsSession::SendPlayTone(CSystemToneService::TToneType aTone) - { - TInt err = SendReceive(StsMsg_PlayTone, TIpcArgs(aTone)); - if (err != KErrNone) - { - //TODO: Log a message - } - } - -void RStsSession::SendPlayAlarm(CSystemToneService::TAlarmType aAlarm, - unsigned int& aAlarmContext, MStsPlayAlarmObserver& aObserver) - { - bool signalObserver = false; - TPckg alarmContextPckg(aAlarmContext); - // Need to do the SendReceive and adding the observer to the - // observer map in a critical section in case the playback - // completes before this method has a chance to update the - // observer list. - iObserverMutex.Wait(); - TInt err = SendReceive(StsMsg_PlayAlarm, TIpcArgs(aAlarm, - &alarmContextPckg, &aObserver)); - if (err != KErrNone) - { - //TODO: Log a message - signalObserver = true; - } - else - { - iObserverMap[aAlarmContext] = &aObserver; - } - iObserverMutex.Signal(); - if (signalObserver) - { - aObserver.PlayAlarmComplete(aAlarmContext); - } - } - -void RStsSession::SendPlayToneAlarm(CSystemToneService::TToneType aTone, - unsigned int& aAlarmContext, MStsPlayAlarmObserver& aObserver) - { - bool signalObserver = false; - TPckg alarmContextPckg(aAlarmContext); - // Need to do the SendReceive and adding the observer to the - // observer map in a critical section in case the playback - // completes before this method has a chance to update the - // observer list. - iObserverMutex.Wait(); - TInt err = SendReceive(StsMsg_PlayToneAlarm, TIpcArgs(aTone, - &alarmContextPckg, &aObserver)); - if (err != KErrNone) - { - //TODO: Log a message - signalObserver = true; - } - else - { - iObserverMap[aAlarmContext] = &aObserver; - } - iObserverMutex.Signal(); - if (signalObserver) - { - aObserver.PlayAlarmComplete(aAlarmContext); - } - } - -void RStsSession::SendStopAlarm(unsigned int aAlarmContext) - { - iObserverMutex.Wait(); - iObserverMap.erase(aAlarmContext); - iObserverMutex.Signal(); - TInt err = SendReceive(StsMsg_StopAlarm, TIpcArgs(aAlarmContext)); - if (err != KErrNone) - { - //TODO: Log a message - } - } - -void RStsSession::CleanUpObservers() - { - iObserverMutex.Wait(); - while (!iObserverMap.empty()) - { - //TODO: Add trace here - unsigned int context = iObserverMap.begin()->first; - iObserverMap.erase(context); - } - iObserverMutex.Signal(); - } - -void RStsSession::SignalObservers() - { - iObserverMutex.Wait(); - while (!iObserverMap.empty()) - { - //TODO: Add trace here - unsigned int context = iObserverMap.begin()->first; - iObserverMap[context]->PlayAlarmComplete(context); - iObserverMap.erase(context); - } - iObserverMutex.Signal(); - }