diff -r 000000000000 -r c9bc50fca66e usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/eventqueue.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/eventqueue.cpp Tue Feb 02 02:02:59 2010 +0200 @@ -0,0 +1,240 @@ +/* +* Copyright (c) 2008-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: +* +*/ + +/** + @file + @internalComponent +*/ + +#include "eventqueue.h" +#include "eventhandler.h" +#include "msmmserver.h" +#include "msmmnodebase.h" +#include "msmmengine.h" +#include +#include + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, "UsbHostMsmmServer"); +#endif + +// Public member functions +CDeviceEventQueue::~CDeviceEventQueue( ) + { + LOG_FUNC + Cancel(); + delete iHandler; + iEventArray.Close(); + } + +CDeviceEventQueue* CDeviceEventQueue::NewL(MMsmmSrvProxy& aServer) + { + LOG_STATIC_FUNC_ENTRY + CDeviceEventQueue* self = CDeviceEventQueue::NewLC(aServer); + CleanupStack::Pop(self); + + return self; + } +CDeviceEventQueue* CDeviceEventQueue::NewLC(MMsmmSrvProxy& aServer) + { + LOG_STATIC_FUNC_ENTRY + CDeviceEventQueue* self = new (ELeave) CDeviceEventQueue(aServer); + CleanupStack::PushL(self); + self->ConstructL(); + + return self; + } + +void CDeviceEventQueue::PushL(const TDeviceEvent& aEvent) + { + LOG_FUNC + + // Perform optimization for remove device event + AppendAndOptimizeL(aEvent); + + // Start handling first event in queue + StartL(); + } + +void CDeviceEventQueue::Finalize() + { + TInt index(0); + while(index < iEventArray.Count()) + { + if (EDeviceEventAddFunction == iEventArray[index].iEvent) + { + iEventArray.Remove(index); + } + else + { + index ++; + } + }; + + if (EDeviceEventAddFunction == iHandler->Event().iEvent) + { + iHandler->Cancel(); + } + } + + +// Protected member functions +void CDeviceEventQueue::DoCancel() + { + LOG_FUNC + iEventArray.Reset(); + iHandler->Cancel(); + } + +void CDeviceEventQueue::RunL() + { + LOG_FUNC + // Check the completion code from CDeviceEventHandler. If there + // is some error occured. We need issue error notification here. + TInt err = iStatus.Int(); + if ((KErrNone != err) && (KErrCancel != err)) + { + iServer.PolicyPlugin()-> + SendErrorNotificationL(iHandler->ErrNotiData()); + } + iHandler->ResetHandler(); + if (IsEventAvailable()) + { + SendEventL(); + } + } + +TInt CDeviceEventQueue::RunError(TInt aError) + { + LOG_FUNC + THostMsErrData errData; + switch (aError) + { + case KErrNoMemory: + errData.iError = EHostMsErrOutOfMemory; + break; + case KErrArgument: + errData.iError = EHostMsErrInvalidParameter; + break; + default: + errData.iError = EHostMsErrGeneral; + } + errData.iE32Error = aError; + TUsbMsDevice* deviceNode = + iServer.Engine().SearchDevice(iHandler->Event().iDeviceId); + if (deviceNode) + { + errData.iManufacturerString.Copy(deviceNode->iDevice.iManufacturerString); + errData.iProductString.Copy(deviceNode->iDevice.iProductString); + } + errData.iDriveName = 0x0; + TInt err(KErrNone); + TRAP(err, iServer.PolicyPlugin()->SendErrorNotificationL(errData)); + return KErrNone; + } + +// Private member functions +CDeviceEventQueue::CDeviceEventQueue(MMsmmSrvProxy& aServer): +CActive(EPriorityStandard), +iServer(aServer) + { + LOG_FUNC + CActiveScheduler::Add(this); + } + +void CDeviceEventQueue::ConstructL() + { + LOG_FUNC + iHandler = CDeviceEventHandler::NewL(iServer); + } + +void CDeviceEventQueue::AppendAndOptimizeL(const TDeviceEvent& aEvent) + { + LOG_FUNC + if (EDeviceEventRemoveDevice == aEvent.iEvent) + { + // Scan the event queue to discard all pending related adding + // function events. + TInt index(0); + while(index < iEventArray.Count()) + { + if (aEvent.iDeviceId == iEventArray[index].iDeviceId) + { + iEventArray.Remove(index); + } + else + { + index ++; + } + }; + + switch (iHandler->Event().iEvent) + { + case EDeviceEventAddFunction: + // If a related adding interface event is being handled currently, + // CDeviceEventQueue shall cancel it first. + if (aEvent.iDeviceId == iHandler->Event().iDeviceId) + { + iHandler->Cancel(); + } + break; + case EDeviceEventRemoveDevice: + if (aEvent.iDeviceId == iHandler->Event().iDeviceId && IsActive()) + { + // Discard duplicated removing event. + return; + } + break; + } + } + iEventArray.AppendL(aEvent); + } + +void CDeviceEventQueue::StartL() + { + LOG_FUNC + if (IsActive()) + { + return; + } + + if (IsEventAvailable()) + { + SendEventL(); + } + } + +void CDeviceEventQueue::SendEventL() + { + LOG_FUNC + // If the handler is available, sending oldest event to it + iHandler->HandleEventL(iStatus, Pop()); + + // Activiate the manager again to wait for the handler + // finish current event + SetActive(); + } + +TDeviceEvent CDeviceEventQueue::Pop() + { + LOG_FUNC + TDeviceEvent event = iEventArray[0]; + iEventArray.Remove(0); + return event; + } + +// End of file