diff -r 000000000000 -r 29b1cd4cb562 atext/server/src/atextlisten.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/atext/server/src/atextlisten.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,530 @@ +/* +* Copyright (c) 2008 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: ECOM listener for ATEXT +* +*/ + + +#include +#include "atextlisten.h" +#include "utils.h" +#include "debug.h" + +const TInt KGranularity = 4; + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CATExtListen* CATExtListen::NewL( REComSession& aSession, + MATExtListen* aCallback ) + { + CATExtListen* self = NewLC( aSession, aCallback ); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CATExtListen* CATExtListen::NewLC( REComSession& aSession, + MATExtListen* aCallback ) + { + CATExtListen* self = new (ELeave) CATExtListen( aSession, + aCallback ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CATExtListen::~CATExtListen() + { + ResetData(); + } + +// --------------------------------------------------------------------------- +// Resets data to initial values +// --------------------------------------------------------------------------- +// +void CATExtListen::ResetData() + { + // APIs affecting this: + // IssueRequest() + Stop(); + // NewL(), AddPluginUid() + if ( iPluginUids ) + { + iPluginUids->Reset(); + delete iPluginUids; + iPluginUids = NULL; + } + // NewL(), AddInterfaceUid() + DeleteLists( iCurrentLists ); + } + +// --------------------------------------------------------------------------- +// Adds a new interface UID to the array of supported interfaces. +// Uses DoAddInterfaceUidL() to add the interface UID. +// --------------------------------------------------------------------------- +// +TInt CATExtListen::AddInterfaceUid( TUid& aIfUid ) + { + TRACE_FUNC_ENTRY + TRAPD( retTrap, DoAddInterfaceUidL(aIfUid) ); + TRACE_FUNC_EXIT + return retTrap; + } + +// --------------------------------------------------------------------------- +// Adds a new plugin UID to the array of supported plugin UIDs. +// --------------------------------------------------------------------------- +// +TInt CATExtListen::AddPluginUid( TUid& aPluginUid ) + { + TRACE_FUNC_ENTRY + TRAPD( retTrap, iPluginUids->AppendL(aPluginUid) ); + TRACE_FUNC_EXIT + return retTrap; + } + +// --------------------------------------------------------------------------- +// Starts waiting for changes in ECOM plugin registration data +// --------------------------------------------------------------------------- +// +TInt CATExtListen::IssueRequest() + { + TRACE_FUNC_ENTRY + if ( IsActive() ) + { + TRACE_FUNC_EXIT + return KErrNotReady; + } + iStatus = KRequestPending; + iSession.NotifyOnChange( iStatus ); + SetActive(); + TRACE_FUNC_EXIT + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Stops waiting for changes in ECOM plugin registration data +// --------------------------------------------------------------------------- +// +TInt CATExtListen::Stop() + { + TRACE_FUNC_ENTRY + if ( !IsActive() ) + { + TRACE_FUNC_EXIT + return KErrNotReady; + } + Cancel(); + TRACE_FUNC_EXIT + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CATExtListen::CATExtListen +// --------------------------------------------------------------------------- +// +CATExtListen::CATExtListen( REComSession& aSession, + MATExtListen* aCallback ) : + CActive( EPriorityNormal ), + iSession( aSession ), + iCallback( aCallback ) + { + Initialize(); + } + +// --------------------------------------------------------------------------- +// CATExtListen::ConstructL +// --------------------------------------------------------------------------- +// +void CATExtListen::ConstructL() + { + TRACE_FUNC_ENTRY + if ( !iCallback ) + { + TRACE_FUNC_EXIT + User::Leave( KErrGeneral ); + } + CArrayFixFlat* pluginUids = + new (ELeave) CArrayFixFlat( KGranularity ); + CleanupStack::PushL( pluginUids ); + iCurrentLists = new (ELeave) CArrayFixFlat( KGranularity ); + CleanupStack::Pop( pluginUids ); + iPluginUids = pluginUids; + CActiveScheduler::Add( this ); + TRACE_FUNC_EXIT + } + +// --------------------------------------------------------------------------- +// Initializes this class +// --------------------------------------------------------------------------- +// +void CATExtListen::Initialize() + { + // Don't initialize iSession here (it is set through NewL) + // Don't initialize iCallback here (it is set through NewL) + iPluginUids = NULL; + iCurrentLists = NULL; + } + +// --------------------------------------------------------------------------- +// Deletes instances of lists associated with ECOM plugin registration data. +// Used to update iCurrentLists on ECOM changes and to delete in destructor. +// --------------------------------------------------------------------------- +// +TInt CATExtListen::DeleteLists( CArrayFixFlat*& aLists ) + { + TRACE_FUNC_ENTRY + if ( !aLists ) + { + TRACE_FUNC_EXIT + return KErrGeneral; + } + TInt i; + TInt count = aLists->Count(); + for ( i=0; iReset(); + delete aLists; + aLists = NULL; + TRACE_FUNC_EXIT + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Adds new interface UID and its implementation UIDs to iCurrentLists list of +// ECOM plugin registration data. +// --------------------------------------------------------------------------- +// +TInt CATExtListen::DoAddInterfaceUidL( TUid& aIfUid ) + { + TRACE_FUNC_ENTRY + // First get the implementations for this aIfUid + TATExtIfData ifData; + ifData.iIfUid = aIfUid; + iSession.ListImplementationsL( aIfUid, ifData.iUidList ); + CleanupResetDestroyClosePushL( ifData.iUidList ); + // Add the implementations to iCurrentLists + iCurrentLists->AppendL( ifData ); + CleanupStack::Pop( &ifData.iUidList ); + TRACE_FUNC_EXIT + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Sorts one array of ECOM plugin registration data. Used to sort both the new +// and the old (iCurrentLists) array of plugin registration data when a change +// is detected by NotifyOnChange(). +// --------------------------------------------------------------------------- +// +TInt CATExtListen::SortArrays( CArrayFixFlat* aLists ) + { + TRACE_FUNC_ENTRY + if ( !aLists ) + { + TRACE_FUNC_EXIT + return KErrGeneral; + } + TInt i; + TInt count = aLists->Count(); + for ( i=0; i* CATExtListen::NewImplementationList() + { + TRACE_FUNC_ENTRY + CArrayFixFlat* newList = NULL; + TRAPD( retTrap, DoGetNewImplementationListL(newList) ); + if ( retTrap != KErrNone ) + { + DeleteLists( newList ); + TRACE_FUNC_EXIT + return NULL; + } + TRACE_FUNC_EXIT + return newList; + } + +// --------------------------------------------------------------------------- +// New list of UID implementation UIDs based on the iCurrentLists list of +// interface UIDs. Used by NewImplementationList(). +// --------------------------------------------------------------------------- +// +void CATExtListen::DoGetNewImplementationListL( + CArrayFixFlat*& aNewList ) + { + TRACE_FUNC_ENTRY + TInt i; + TInt count = iCurrentLists->Count(); + aNewList = NULL; + aNewList = new (ELeave) CArrayFixFlat( KGranularity ); + for ( i=0; iAppendL( newInfo ); + CleanupStack::Pop( &newInfo.iUidList ); + } + TRACE_FUNC_EXIT + } + +// --------------------------------------------------------------------------- +// Checks for existing plugin uninstallation. When a change is detected the +// change is notified by plugin uninstallation callback. +// --------------------------------------------------------------------------- +// +TBool CATExtListen::CheckPluginUninstall( + CArrayFixFlat* aNewLists ) + { + TRACE_FUNC_ENTRY + if ( !aNewLists || !iCurrentLists || + aNewLists->Count() != iCurrentLists->Count() ) + { + TRACE_FUNC_EXIT + return EFalse; + } + TInt i; + TInt j; + TInt ifDataCount = iCurrentLists->Count(); + for ( i=0; i= pluginCountNew ) + { + outOfBounds = ETrue; + } + CImplementationInformation* implCurrent = ifDataCurrent.iUidList[j]; + TUid pluginUidCurrent = implCurrent->ImplementationUid(); + if ( !outOfBounds ) + { + CImplementationInformation* implNew = ifDataNew.iUidList[j]; + TUid pluginUidNew = implNew->ImplementationUid(); + if ( pluginUidNew != pluginUidCurrent ) + { + differentUids = ETrue; + } + } + if ( outOfBounds || differentUids ) + { + iCallback->NotifyPluginUninstallation( ifDataCurrent.iIfUid, + pluginUidCurrent ); + return ETrue; + } + } + } + TRACE_FUNC_EXIT + return EFalse; + } + +// --------------------------------------------------------------------------- +// Checks for new plugin installation. When a change is detected the change is +// is notified by plugin installation callback. +// --------------------------------------------------------------------------- +// +TBool CATExtListen::CheckPluginInstall( + CArrayFixFlat* aNewLists ) + { + TRACE_FUNC_ENTRY + if ( !aNewLists || !iCurrentLists || + aNewLists->Count() != iCurrentLists->Count() ) + { + TRACE_FUNC_EXIT + return EFalse; + } + TInt i; + TInt j; + TInt ifDataCount = iCurrentLists->Count(); + for ( i=0; i= pluginCountCurrent ) + { + outOfBounds = ETrue; + } + CImplementationInformation* implNew = ifDataNew.iUidList[j]; + TUid pluginUidNew = implNew->ImplementationUid(); + if ( !outOfBounds ) + { + CImplementationInformation* implCurrent = ifDataCurrent.iUidList[j]; + TUid pluginUidCurrent = implCurrent->ImplementationUid(); + if ( pluginUidCurrent != pluginUidNew ) + { + differentUids = ETrue; + } + } + if ( outOfBounds || differentUids ) + { + iCallback->NotifyPluginInstallation( ifDataNew.iIfUid, + implNew ); + return ETrue; + } + } + } + TRACE_FUNC_EXIT + return EFalse; + } + +// --------------------------------------------------------------------------- +// Checks for plugin version upgrade/downgrade change. When a change is +// detected the change is notified by plugin uninstallation and installation +// callbacks. +// --------------------------------------------------------------------------- +// +TBool CATExtListen::CheckPluginVersionChange( + CArrayFixFlat* aNewLists ) + { + TRACE_FUNC_ENTRY + if ( !aNewLists || !iCurrentLists || + aNewLists->Count() != iCurrentLists->Count() ) + { + TRACE_FUNC_EXIT + return EFalse; + } + TInt i; + TInt j; + TInt ifDataCount = iCurrentLists->Count(); + for ( i=0; iImplementationUid(); + TUid pluginUidNew = implNew->ImplementationUid(); + if ( implCurrent->Version()!=implNew->Version() && + pluginUidCurrent==pluginUidNew ) + { + iCallback->NotifyPluginUninstallation( ifDataCurrent.iIfUid, + pluginUidCurrent ); + iCallback->NotifyPluginInstallation( ifDataNew.iIfUid, + implNew ); + TRACE_FUNC_EXIT + return ETrue; + } + } + } + TRACE_FUNC_EXIT + return EFalse; + } + +// --------------------------------------------------------------------------- +// From CActive. +// Gets called when ECOM plugin registration data change is detected +// --------------------------------------------------------------------------- +// +void CATExtListen::RunL() + { + TRACE_FUNC_ENTRY + IssueRequest(); + // First get the new list + CArrayFixFlat* newLists = NewImplementationList(); + if ( !newLists ) + { + TRACE_FUNC_EXIT + return; + } + SortArrays( newLists ); + SortArrays( iCurrentLists ); + // Next check the cases of plugin uninstall. This happens if an entry in the + // iCurrentLists can't be found from the new list. + TBool uninstalled = CheckPluginUninstall( newLists ); + // Next check the cases of plugin install. This happens if an entry in the + // new list can't be found from the iCurrentList. + TBool installed = EFalse; + if ( !uninstalled ) + { + installed = CheckPluginInstall( newLists ); + } + if ( !uninstalled && !installed ) + { + CheckPluginVersionChange( newLists ); + } + // Delete existing iCurrentLists and set newLists + DeleteLists( iCurrentLists ); + iCurrentLists = newLists; + TRACE_FUNC_EXIT + } + +// --------------------------------------------------------------------------- +// From class CActive. +// Gets called on cancel +// --------------------------------------------------------------------------- +// +void CATExtListen::DoCancel() + { + TRACE_FUNC_ENTRY + iSession.CancelNotifyOnChange( iStatus ); + TRACE_FUNC_EXIT + }