/*
* Copyright (c) 2002-2006 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: Loader of ASYs
*
*/
// INCLUDE FILES
#include "ASYProxy.h"
#include "ASYProxyAsyHandler.h"
#include "acc_debug.h"
#include <e32svr.h>
// EXTERNAL DATA STRUCTURES
// EXTERNAL FUNCTION PROTOTYPES
// CONSTANTS
// MACROS
// LOCAL CONSTANTS AND MACROS
// MODULE DATA STRUCTURES
// LOCAL FUNCTION PROTOTYPES
// FORWARD DECLARATIONS
// ============================= LOCAL FUNCTIONS ===============================
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CASYProxyAsyLoader::CASYProxyAsyLoader
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CASYProxyAsyLoader::CASYProxyAsyLoader(
CASYProxy* aAsyProxy ) :
CActive( CActive::EPriorityStandard ),
iListRet( EFalse ),
iArrayItemCounter( 0 ),
iStepToDo( EASYLoadingStepListInit ),
iAsyProxy( aAsyProxy )
{
COM_TRACE_1( "[AccFW:AsyProxy] CASYProxyAsyLoader::CASYProxyAsyLoader(0x%x)", &aAsyProxy );
CActiveScheduler::Add( this );
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::CASYProxyAsyLoader" );
}
// -----------------------------------------------------------------------------
// CASYProxyAsyLoader::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CASYProxyAsyLoader::ConstructL()
{
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::ConstructL()" );
iTimer = CASYProxyLoaderTimer::NewL( this );
iTimer->StartTimer();
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::ConstructL - return void" );
}
// -----------------------------------------------------------------------------
// CASYProxyAsyLoader::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CASYProxyAsyLoader* CASYProxyAsyLoader::NewL(
CASYProxy* aAsyProxy )
{
COM_TRACE_1( "[AccFW:AsyProxy] CASYProxyAsyLoader::NewL(0x%x)", aAsyProxy );
CASYProxyAsyLoader* self = new (ELeave) CASYProxyAsyLoader( aAsyProxy );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
COM_TRACE_1( "[AccFW:AsyProxy] CASYProxyAsyLoader::NewL - return 0x%x", self );
return self;
}
// Destructor
CASYProxyAsyLoader::~CASYProxyAsyLoader()
{
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::~CASYProxyAsyLoader()" );
Cancel();
Cleanup();
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::~CASYProxyAsyLoader" );
}
// -----------------------------------------------------------------------------
// CASYProxyAsyLoader::DoCancel
// Cancel of Active object
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CASYProxyAsyLoader::DoCancel()
{
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::DoCancel()" );
// Cancel is called only from destructor
// Cleanup is called from destructor
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::DoCancel - return void" );
}
// -----------------------------------------------------------------------------
// CASYProxyAsyLoader::DoCancel
// Deletes own class members
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CASYProxyAsyLoader::Cleanup()
{
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::Cleanup()" );
delete iTimer;
iTimer = NULL;
iImplUidsHandlerArray.Reset();
iServiceImplInfoArray.ResetAndDestroy();
iHandlerImplInfoArray.ResetAndDestroy();
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::Cleanup - return void" );
}
// -----------------------------------------------------------------------------
// CASYProxyAsyLoader::RunL
// Loading has been splitted to five section
// Each of them are under time out control.
// - case ListImplementations
// - case CheckListValues
// - case OrderImplementations
// - case LoadASY
// - case LoadingOver
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CASYProxyAsyLoader::RunL()
{
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::RunL()" );
User::LeaveIfError( iStatus.Int() );
if ( iTimer && iTimer->IsActive() )
{
NextStep();
switch ( iStepToDo )
{
case EASYLoadingStepListImplementations :
ListImplementationsL();
SetActive();
break;
case EASYLoadingStepOrderImplementations :
ArrangeImplementationsL();
SetActive();
break;
case EASYLoadingStepLoadASY :
DoIssueRequestL();
SetActive();
break;
case EASYLoadingOver :
break;
default :
// Nothing to do. Assert if it comes here.
TRACE_ASSERT_ALWAYS;
break;
}
}
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::RunL - return void" );
}
// -----------------------------------------------------------------------------
// CASYProxyAsyLoader::RunError
// Returns KErrNone
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CASYProxyAsyLoader::RunError( TInt aError )
{
COM_TRACE_1( "[AccFW:AsyProxy] CASYProxyAsyLoader::RunError(%d)", aError );
// Avoid Panic in CActiveScheduler
aError = KErrNone;
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::RunError - return KErrNone" );
return aError;
}
// -----------------------------------------------------------------------------
// CASYProxyAsyLoader::IssueRequest
// Starts the loading process of ASY
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CASYProxyAsyLoader::IssueRequest()
{
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::IssueRequest()" );
SetActive();
TRequestStatus* ptrStat = &iStatus;
*ptrStat = KRequestPending;
User::RequestComplete( ptrStat, KErrNone );
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::IssueRequest - return void" );
}
// -----------------------------------------------------------------------------
// CASYProxyAsyLoader::DoIssueRequestL
// Last step of loading process of ASY
// Creates own CASYProxyASYHandler -object for each ASY to continue it's loading
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CASYProxyAsyLoader::DoIssueRequestL()
{
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::DoIssueRequest()" );
COM_TRACE_1( "[AccFW:AsyProxy] CASYProxyAsyLoader::DoIssueRequestL() - iArrayItemCounter == %d", iArrayItemCounter );
if ( iArrayItemCounter < iServiceImplInfoArray.Count() )
{
TRequestStatus* ptrStat = &iStatus;
*ptrStat = KRequestPending;
CASYProxyASYHandler* createdAccHandler = NULL;
// Starts new ASY creating
TRAPD( err, createdAccHandler = CASYProxyASYHandler::NewL(
iAsyProxy,
iArrayItemCounter,
iImplUidsHandlerArray.operator[]( iArrayItemCounter ),
*iServiceImplInfoArray[ iArrayItemCounter ]
) );
COM_TRACE_1( "[AccFW:AsyProxy] CASYProxyAsyLoader::DoIssueRequest() - err == %d", err );
if ( createdAccHandler )
{
CleanupStack::PushL ( createdAccHandler );
iAsyProxy->iAccHandlerArray.AppendL( createdAccHandler );
iArrayItemCounter++;
CleanupStack::Pop ( createdAccHandler );
}
User::RequestComplete( ptrStat, err );
}
else
{
User::Leave( KErrArgument );
}
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::DoIssueRequest - return void" );
}
// -----------------------------------------------------------------------------
// CASYProxy::ListImplementationsL
// List implementations for ASY by using RECom library
// - List service parts to iServiceImplInfoArray
// - List handler parts to iHandlerImplInfoArray
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CASYProxyAsyLoader::ListImplementationsL()
{
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::ListImplementationsL()" );
TRequestStatus* ptrStat = &iStatus;
*ptrStat = KRequestPending;
TBufC8<KMaxImplementationInfoDataLength>
ASYPluginMainServiceName( ( TText8* ) KACCESSORYPLUGINAPIMAINSERVICE );
TBufC8<KMaxImplementationInfoDataLength>
ASYPluginHandlerName ( ( TText8* ) KACCESSORYPLUGINAPIHANDLER );
// ASY interface_uid
TUid pluginInterfaceUid;
pluginInterfaceUid.iUid = KACCESSORYPLUGINAPIUID;
TEComResolverParams resolverParam;
// MainService
// -----------------------------------------------------
resolverParam.SetDataType( ASYPluginMainServiceName );
REComSession::ListImplementationsL( pluginInterfaceUid,
resolverParam,
iServiceImplInfoArray );
// Handler
// -----------------------------------------------------
resolverParam.SetDataType( ASYPluginHandlerName );
REComSession::ListImplementationsL( pluginInterfaceUid,
resolverParam,
iHandlerImplInfoArray );
iListRet = ( iServiceImplInfoArray.Count() > 0 ) ? ETrue : EFalse;
COM_TRACE_1( "[AccFW:AsyProxy] CASYProxyAsyLoader::ListImplementationsL - count == %d", iServiceImplInfoArray.Count() );
COM_TRACE_1( "[AccFW:AsyProxy] CASYProxyAsyLoader::ListImplementationsL - iListRet == %d", iListRet );
User::RequestComplete( ptrStat, KErrNone );
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::ListImplementationsL - return void");
}
// -----------------------------------------------------------------------------
// CASYProxy::ArrangeImplementationsL
// Arranges the listed implementations
// 1. Find "Idle ASYs" ( i.e. ASY has only service part and not handler part )
// - Service parts are in iServiceImplInfoArray
// - Handler parts are in iHandlerImplInfoArray
// 2. Move idle ASYs to last ones within iServiceImplInfoArray
// 3. Find Service / Handler pairs
// - Service parts are still in iServiceImplInfoArray
// - Handler parts implementation Uids added to iImplUidsHandlerArray
// 4. Add zero values to iImplUidsHandlerArray until it's length is same as
// length of iServiceImplInfoArray
// 5. Create CASYProxyASYHandler -array
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CASYProxyAsyLoader::ArrangeImplementationsL()
{
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::ArrangeImplementationsL()" );
TRequestStatus* ptrStat = &iStatus;
*ptrStat = KRequestPending;
RArray<TInt> onlyServicesIndexArray;
CleanupClosePushL( onlyServicesIndexArray );
TBuf<KMaxImplementationInfoDataLength> bufDisplayNameService;
TBuf<KMaxImplementationInfoDataLength> bufDisplayNameHandler;
// Find implementation indexes of idle ASYs
// ----------------------------------------------------------------
TInt lastServiceIndex = iServiceImplInfoArray.Count() - 1;
TInt lastHandlerIndex = iHandlerImplInfoArray.Count() - 1;
for ( TInt i=0; i<=lastServiceIndex; i++ )
{
TBool found( EFalse );
bufDisplayNameService = iServiceImplInfoArray.operator[]( i )->DisplayName();
for ( TInt j=0; j<=lastHandlerIndex; j++ )
{
bufDisplayNameHandler = iHandlerImplInfoArray.operator[]( j )->DisplayName();
if ( KErrNotFound != bufDisplayNameService.Match( bufDisplayNameHandler ) )
{
found = ETrue;
break; // Break j loop
}
}
if ( found == EFalse )
{
onlyServicesIndexArray.Append( i );
}
}
// ASYProxy must know the "real" ASYs count
iAsyProxy->SetASYsCount( iServiceImplInfoArray.Count() - onlyServicesIndexArray.Count() );
// Move idle ASYs to last ones within iServiceImplInfoArray
// ----------------------------------------------------------------
for ( TInt k = onlyServicesIndexArray.Count() - 1; k>=0; k-- )
{
CImplementationInformation *implementationInformation =
iServiceImplInfoArray.operator[]( onlyServicesIndexArray.operator[]( k ) );
iServiceImplInfoArray.Remove( onlyServicesIndexArray.operator[]( k ) );
iServiceImplInfoArray.Append( implementationInformation );
}
// Find Service / Handler pairs
// ----------------------------------------------------------------
for ( TInt i=0; i<=lastServiceIndex; i++ )
{
bufDisplayNameService = iServiceImplInfoArray.operator[]( i )->DisplayName();
for ( TInt j=0; j<=lastHandlerIndex; j++ )
{
bufDisplayNameHandler = iHandlerImplInfoArray.operator[]( j )->DisplayName();
if ( KErrNotFound != bufDisplayNameService.Match( bufDisplayNameHandler ) )
{
TUid implementUid = iHandlerImplInfoArray.operator[]( j )->ImplementationUid();
User::LeaveIfError( iImplUidsHandlerArray.Append( implementUid ) );
}
}
}
// Add zero -values to iImplUidsHandlerArray for the last idle ASYs
// ----------------------------------------------------------------
TUid zeroUid;
zeroUid.iUid = ZEROHANDLERUID;
while ( iImplUidsHandlerArray.Count() < iServiceImplInfoArray.Count() )
{
iImplUidsHandlerArray.Append( zeroUid );
}
User::RequestComplete( ptrStat, KErrNone );
CleanupStack::PopAndDestroy( &onlyServicesIndexArray );
// only ServicesIndexArray.Close() was called;
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::ArrangeImplementationsL - return void" );
}
// -----------------------------------------------------------------------------
// CASYProxy::NextStep
// Increases the loading process control splitter variable
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CASYProxyAsyLoader::NextStep()
{
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::NextStep()" );
switch ( iStepToDo )
{
case EASYLoadingStepListInit :
iStepToDo = EASYLoadingStepListImplementations;
break;
case EASYLoadingStepListImplementations :
iStepToDo = iListRet ? EASYLoadingStepOrderImplementations : EASYLoadingOver;
break;
case EASYLoadingStepOrderImplementations :
iStepToDo = EASYLoadingStepLoadASY;
break;
case EASYLoadingStepLoadASY :
if ( iArrayItemCounter == iServiceImplInfoArray.Count() )
{
iStepToDo = EASYLoadingOver;
}
break;
default :
iStepToDo = EASYLoadingOver;
break;
}
COM_TRACE_1( "[AccFW:AsyProxy] CASYProxyAsyLoader::NextStep - iStepToDo == %d", iStepToDo );
COM_TRACE_( "[AccFW:AsyProxy] CASYProxyAsyLoader::NextStep - return void" );
}
// ========================== OTHER EXPORTED FUNCTIONS =========================
// End of File