presencefwsimpleadpt/src/simplepluginwatcher.cpp
branchRCL_3
changeset 18 fbd2e7cec7ef
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/presencefwsimpleadpt/src/simplepluginwatcher.cpp	Wed Sep 01 12:23:14 2010 +0100
@@ -0,0 +1,784 @@
+/*
+* Copyright (c) 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:    SIMPLE Protocol implementation for Presence Framework
+*
+*/
+
+
+
+
+#include <e32std.h>
+#include <utf.h>
+
+#include <personpresenceinfo.h>
+
+#include <presenceinfo.h>
+#include <presenceinfofieldcollection.h>
+#include <presenceinfofield.h>
+#include <presenceinfofieldvaluetext.h>
+#include <presenceinfofieldvalueenum.h>
+#include <presenceobjectfactory.h>
+#include <presenceerrors.hrh>
+
+#include <presentitygroupmemberinfo.h>
+
+#include <protocolpresencedatahost.h>
+#include <protocolpresentitygroupsdatahost.h>
+#include <protocolpresencewatchingdatahost.h>
+
+#include <ximpdatasubscriptionstate.h>
+#include <ximperrors.hrh>
+#include <ximpidentity.h>
+#include <ximpobjectcollection.h>
+#include <ximpobjectfactory.h>
+#include <ximpprotocolconnectionhost.h>
+#include <ximpstatus.h>
+
+#include <simplefactory.h>
+#include <simpleerrors.h>
+#include <msimplewinfo.h>
+#include <msimplewatcher.h>
+#include <msimpledocument.h>
+#include <msimpleelement.h>
+
+#include "simpleplugincommon.h"
+#include "simplepluginwatcher.h"
+#include "simplepluginentitywatcher.h"
+#include "simpleplugindebugutils.h"
+#include "simpleutils.h"
+#include "simplepluginxdmutils.h"
+#include "simpleplugindata.h"
+#include "simplepluginconnection.h"
+
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::CSimplePluginWatcher
+// ---------------------------------------------------------------------------
+//
+CSimplePluginWatcher::CSimplePluginWatcher(
+    MSimplePluginSettings& aConnSets,
+    MSimplePluginConnectionObs& aObs,
+    MSimpleConnection& aConn )
+: CActive( CActive::EPriorityStandard ),
+  iConnSets( aConnSets), iConnObs(aObs), iConnection(aConn), iCompleted( ETrue ),
+  iOperation( EPluginUndef ), iXdmState( EPluginIdle )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::ConstructL( )
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::NewL
+// ---------------------------------------------------------------------------
+//
+CSimplePluginWatcher* CSimplePluginWatcher::NewL(
+    MSimplePluginSettings& aConnSets,
+    MSimplePluginConnectionObs& aObs,
+    MSimpleConnection& aConn )
+    {
+    CSimplePluginWatcher* self =
+        new( ELeave ) CSimplePluginWatcher( aConnSets, aObs, aConn );
+    CleanupStack::PushL( self );
+    self->ConstructL(  );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::~CSimplePluginWatcher
+// ---------------------------------------------------------------------------
+//
+CSimplePluginWatcher::~CSimplePluginWatcher()
+    {
+    iWatchers.ResetAndDestroy();
+    iWatchers.Close();
+    delete iPresIdentity;
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoSubscribePresentityPresenceL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoSubscribePresentityPresenceL(
+    const MXIMPIdentity& aPresentityId,
+    const MPresenceInfoFilter& /*aPif*/,   // notice: aPif filter not supported
+    TXIMPRequestId aReqId )
+    {
+#ifdef _DEBUG
+    PluginLogger::Log(_L("PluginWatcher: DoSubscribePresentityPresenceL"));
+#endif
+
+    TRAPD( err, DoDoSubscribePresentityPresenceL(aPresentityId, aReqId ));
+    if ( err )
+        {
+        User::Leave( CSimplePluginConnection::HarmonizeErrorCode( err ));
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoDoSubscribePresentityPresenceL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoDoSubscribePresentityPresenceL(
+    const MXIMPIdentity& aPresentityId,
+    TXIMPRequestId aReqId )
+    {
+    iOperation = EPluginUndef;
+    iXdmState = EPluginIdle;
+
+    SetPresIdentityL( aPresentityId );
+    iPrFwId = aReqId;
+    iCompleted = EFalse;
+
+  HBufC8* pres8 = NULL;
+    pres8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L( iPresIdentity->Des() );
+    CleanupStack::PushL( pres8 ); // << pres8
+
+    CSimplePluginEntityWatcher* watcher = MatchWatcher2L( pres8->Des(), ETrue );
+    watcher->StartSubscribeL( pres8->Des() );
+    CleanupStack::PopAndDestroy( pres8 );  // >> pres8
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoUpdatePresentityPresenceSubscriptionPifL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoUpdatePresentityPresenceSubscriptionPifL(
+    const MXIMPIdentity& /*aPresentityId*/,
+    const MPresenceInfoFilter& /*aPif*/,
+    TXIMPRequestId /*aReqId*/ )
+    {
+#ifdef _DEBUG
+    PluginLogger::Log(
+        _L("PluginWatcher: DoUpdatePresentityPresenceSubscriptionPifL"));
+#endif
+
+    iOperation = EPluginUndef;
+
+    // notice: aPif filter not supported
+    User::Leave( KErrNotSupported );
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoUnsubscribePresentityPresenceL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoUnsubscribePresentityPresenceL(
+    const MXIMPIdentity& aPresentityId,
+    TXIMPRequestId aReqId )
+    {
+#ifdef _DEBUG
+    PluginLogger::Log(_L("PluginWatcher: DoUnsubscribePresentityPresenceL"));
+#endif
+
+    TRAPD( err, DoDoUnsubscribePresentityPresenceL( aPresentityId, aReqId ) );
+    if ( err )
+        {
+        User::Leave( CSimplePluginConnection::HarmonizeErrorCode( err ));
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoDoUnsubscribePresentityPresenceL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoDoUnsubscribePresentityPresenceL(
+    const MXIMPIdentity& aPresentityId,
+    TXIMPRequestId aReqId )
+    {
+
+    iOperation = EPluginUndef;
+    iXdmState = EPluginIdle;
+
+    SetPresIdentityL( aPresentityId );
+    iPrFwId = aReqId;
+    iCompleted = EFalse;
+
+  HBufC8* pres8 = NULL;
+    pres8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L( iPresIdentity->Des() );
+    CleanupStack::PushL( pres8 ); // << pres8
+
+    CSimplePluginEntityWatcher* watcher = MatchWatcher2L( pres8->Des(), EFalse );
+    if ( !watcher )
+        {
+        User::Leave( KErrNotFound ); // Notice: error code
+        }
+    else
+        {
+#ifdef _DEBUG
+        PluginLogger::Log(_L("PluginWatcher: -> StopSubscribeL"));
+#endif
+        watcher->StopSubscribeL();
+        }
+    CleanupStack::PopAndDestroy( pres8 );  // >> pres8
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoSubscribePresentityGroupMembersPresenceL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoSubscribePresentityGroupMembersPresenceL(
+    const MXIMPIdentity& aGroupId,
+    const MPresenceInfoFilter& /*aPif*/,   // notice: aPif filter not supported
+    TXIMPRequestId aReqId )
+    {
+#ifdef _DEBUG
+    PluginLogger::Log(
+        _L("PluginWatcher: DoSubscribePresentityGroupMembersPresenceL"));
+#endif
+
+    iOperation = EPluginSubscribeGroup;
+    iXdmState = EPluginIdle;
+
+    SetPresIdentityL( aGroupId );
+    iPrFwId = aReqId;
+    iCompleted = EFalse;
+
+    // Get Shared XDM lists first and create RLS service first
+    StartXdmOperationL();
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoUpdatePresentityGroupMembersPresenceSubscriptionPifL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoUpdatePresentityGroupMembersPresenceSubscriptionPifL(
+    const MXIMPIdentity& /*aGroupId*/,
+    const MPresenceInfoFilter& /*aPif*/,
+    TXIMPRequestId /*aReqId*/ )
+    {
+#ifdef _DEBUG
+    PluginLogger::Log(
+  _L("PluginWatcher: DoUpdatePresentityGroupMembersPresenceSubscriptionPifL"));
+#endif
+    // notice: aPif filter not supported
+    User::Leave( KErrNotSupported );
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoUnsubscribePresentityGroupMembersPresenceL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoUnsubscribePresentityGroupMembersPresenceL(
+    const MXIMPIdentity& aGroupId,
+    TXIMPRequestId aReqId )
+    {
+#ifdef _DEBUG
+    PluginLogger::Log(
+        _L("PluginWatcher: DoUnsubscribePresentityGroupMembersPresenceL"));
+#endif
+    TRAPD( err, DoDoUnsubscribePresentityGroupMembersPresenceL( aGroupId, aReqId ));
+    if ( err )
+        {
+        User::Leave( CSimplePluginConnection::HarmonizeErrorCode( err ));
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoDoUnsubscribePresentityGroupMembersPresenceL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoDoUnsubscribePresentityGroupMembersPresenceL(
+    const MXIMPIdentity& aGroupId,
+    TXIMPRequestId aReqId )
+    {
+    iOperation = EPluginUnsubscribeGroup;
+    iXdmState = EPluginIdle;
+
+    SetPresIdentityL( aGroupId );
+    iPrFwId = aReqId;
+    iCompleted = EFalse;
+
+    HBufC* buf16 = iXdmUtils->RlsServiceByResourceListLC( iPresIdentity->Des() ); // << buf16
+
+    HBufC8* buf = CnvUtfConverter::ConvertFromUnicodeToUtf8L( buf16->Des() );
+    CleanupStack::PushL( buf );  // << buf
+
+    CSimplePluginEntityWatcher* watcher = MatchWatcher2L( buf->Des(), EFalse );
+
+    CleanupStack::PopAndDestroy( buf );  // >> buf
+    CleanupStack::PopAndDestroy( buf16 );  // >> buf16
+
+    if ( !watcher )
+        {
+        User::Leave( KErrNotFound ); // Notice: error code
+        }
+    else
+        {
+        watcher->StopSubscribeL();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::GetInterface
+// ---------------------------------------------------------------------------
+//
+TAny* CSimplePluginWatcher::GetInterface(
+        TInt32 aInterfaceId,
+        TIfGetOps aOptions )
+    {
+    if ( aInterfaceId == GetInterfaceId() )
+        {
+        // caller wants this interface
+        MProtocolPresenceWatching* myIf = this;
+        return myIf;
+        }
+    if ( aOptions == MXIMPBase::EPanicIfUnknown )
+        {
+        User::Panic( _L("CSimplePlugin"), KErrExtensionNotSupported );
+        }
+    return NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::GetInterface
+// ---------------------------------------------------------------------------
+//
+const TAny* CSimplePluginWatcher::GetInterface(
+    TInt32 aInterfaceId,
+    TIfGetOps aOptions ) const
+    {
+    if ( aInterfaceId == GetInterfaceId() )
+        {
+        // caller wants this interface
+        const MProtocolPresenceWatching* myIf = this;
+        return myIf;
+        }
+    if ( aOptions == MXIMPBase::EPanicIfUnknown )
+        {
+        User::Panic( _L("CSimplePlugin"), KErrExtensionNotSupported );
+        }
+    return NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::GetInterfaceId
+// ---------------------------------------------------------------------------
+//
+TInt32 CSimplePluginWatcher::GetInterfaceId() const
+    {
+    return MProtocolPresenceWatching::KInterfaceId;
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::MatchWatcher2L
+// ---------------------------------------------------------------------------
+//
+CSimplePluginEntityWatcher* CSimplePluginWatcher::MatchWatcher2L(
+    const TDesC8& aPresentityid, TBool aCreate )
+    {
+    TInt count = iWatchers.Count();
+    for ( TInt i = 0; i < count; i++ )
+        {
+        CSimplePluginEntityWatcher* temp = (iWatchers[i]);
+        if ( !temp->PresentityId().CompareF( aPresentityid ))
+            {
+            return temp;
+            }
+        }
+
+    // If watcher was not found, crete it when wanted so.
+    if ( !aCreate )
+        {
+        return NULL;
+        }
+    else
+        {
+        CSimplePluginEntityWatcher* watcher = CSimplePluginEntityWatcher::NewL(
+            iConnObs, iConnection, *this );
+        iWatchers.AppendL( watcher );
+        return watcher;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DeleteWatcher
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DeleteWatcher(
+    const TDesC8& aPresentityid )
+    {
+
+#ifdef _DEBUG
+    PluginLogger::Log( _L("PluginWatcher: DeleteWatcher **"));
+#endif
+
+    TInt count = iWatchers.Count();
+    for ( TInt i = 0; i < count; i++ )
+        {
+        CSimplePluginEntityWatcher* temp = (iWatchers[i]);
+        if ( !temp->PresentityId().CompareF( aPresentityid ) )
+            {
+            iWatchers.Remove( i );
+            iWatchers.GranularCompress();
+            delete temp;
+            break;
+            }
+        else
+            {
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::GetEntitiesInListL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::GetEntitiesInListL(
+    const TDesC& aList, MXIMPObjectCollection& aMembers )
+    {
+    __ASSERT_DEBUG( iXdmUtils, User::Leave( KErrCorrupt ) );
+
+    const TInt KMyGran = 10;
+    CPtrCArray* ids = new (ELeave) CPtrCArray( KMyGran );
+    CleanupStack::PushL( ids );      // << ids
+
+    CPtrCArray* dispNames = new (ELeave) CPtrCArray( KMyGran );
+    CleanupStack::PushL( dispNames  );      // << dispNames
+
+    iXdmUtils->GetEntitiesInListL( aList, *ids, *dispNames );
+
+    CopyGroupMembersToCollectionL( *ids, *dispNames, aMembers );
+
+    CleanupStack::PopAndDestroy( dispNames );
+    CleanupStack::PopAndDestroy( ids );
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::StartWatchingRlsL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::StartWatchingRlsL()
+    {
+    HBufC* buf = iXdmUtils->RlsServiceByResourceListLC( iPresIdentity->Des() );  // << buf
+
+    HBufC8* buf2 = NULL;
+    buf2 = CnvUtfConverter::ConvertFromUnicodeToUtf8L( buf->Des() );
+    CleanupStack::PushL( buf2 ); // << buf2
+
+    CSimplePluginEntityWatcher* watcher = MatchWatcher2L( buf2->Des(), ETrue );
+
+    watcher->StartSubscribeListL( buf2->Des() );
+
+    watcher->SetSimpleNameL( buf2->Des() );
+
+    CleanupStack::PopAndDestroy( buf2 );  // >> buf2
+    CleanupStack::PopAndDestroy( buf );  // >> buf
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::SetPresIdentityL()
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::SetPresIdentityL(
+     const MXIMPIdentity& aPresentityId )
+     {
+     delete iPresIdentity;
+     iPresIdentity = NULL;
+     iPresIdentity = aPresentityId.Identity().AllocL();
+     }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::CompletePrFwReq
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::CompletePrFwReq( TInt aStatus )
+    {
+#ifdef _DEBUG
+    PluginLogger::Log(_L("PluginWatcher: CompletePrFwReq status=%d"), aStatus );
+#endif
+    iXdmState = EPluginIdle;
+
+    if ( !iCompleted )
+        {
+        iCompleted = ETrue;
+        // Convert error code when needed
+        if ( aStatus == KSimpleErrNotFound &&
+             ( iOperation == EPluginSubscribeGroup ||
+               iOperation == EPluginUnsubscribeGroup ))
+            {
+            aStatus = KPresenceErrUnknownPresentityGroup;
+            }
+        else if ( aStatus == KSimpleErrNotFound )
+            {
+            aStatus = KPresenceErrUnknownPresentity;
+            }
+        else
+            {
+            }
+        iConnObs.CompleteReq( iPrFwId, aStatus );
+        iPrFwId = TXIMPRequestId();
+        iOperation = EPluginUndef;
+        }
+    else
+        {
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::CompleteWatcher
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::CompleteWatcher( TInt aStatus )
+    {
+#ifdef _DEBUG
+    PluginLogger::Log(_L("PluginWatcher: CompleteWatcher status=%d"), aStatus );
+#endif
+    // start to remove RLS service when needed.
+    if ( iOperation == EPluginUnsubscribeGroup && iXdmState == EPluginIdle )
+        {
+        TRAPD( err, iXdmUtils->FetchRlsL( iStatus ));
+        if ( err )
+            {
+            CompletePrFwReq( err );
+            }
+        else
+            {
+            iXdmState = EPluginFetchRls;
+            SetActive();
+            }
+        }
+    else
+        {
+        CompletePrFwReq( aStatus );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::StartXdmOperationL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::StartXdmOperationL()
+    {
+    TRAPD( err, DoStartXdmOperationL() );
+    if ( err )
+        {
+        User::Leave( CSimplePluginConnection::HarmonizeErrorCode( err ));
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoStartXdmOperationL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoStartXdmOperationL()
+    {
+    __ASSERT_DEBUG( !IsActive(), User::Leave( KErrCorrupt ) );
+    if ( !iXdmUtils )
+        {
+        iXdmUtils = iConnObs.XdmUtilsL();
+        }
+    iXdmUtils->InitializeXdmsOnlyL( iStatus );
+
+    iXdmState = EPluginInitXdm;
+
+    SetActive();
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoCancel
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoCancel(  )
+    {
+    iXdmUtils->Cancel();
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::RunL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::RunL(  )
+    {
+
+    TInt status = iStatus.Int();
+
+#ifdef _DEBUG
+    PluginLogger::Log(_L("PluginWatcher: RunL %d"), status );
+#endif
+    if ( !status )
+        {
+        // create RLS service first here
+        if ( iOperation == EPluginSubscribeGroup )
+            {
+            DoRunForSubscriptionL();
+            }
+        // remove RLS service when needed.
+        else if ( iOperation == EPluginUnsubscribeGroup )
+            {
+            DoRunForUnsubscriptionL();
+            }
+        else
+            {
+            // Idle state should not be completed. We should not come here
+            // because of PrFw core makes one request at a time.
+            }
+        }
+    else
+        {
+        CompletePrFwReq( status );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::RunError
+// ---------------------------------------------------------------------------
+//
+TInt CSimplePluginWatcher::RunError( TInt aError )
+    {
+    CompletePrFwReq( aError );
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::GetListContentL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::GetListContentL()
+    {
+    MXIMPObjectFactory& myFactory = iConnObs.ObjectFactory();
+    MProtocolPresentityGroupsDataHost& dataHost =
+        iConnObs.Host()->ProtocolPresenceDataHost().GroupsDataHost();
+
+    MXIMPObjectCollection* entities =
+        myFactory.NewObjectCollectionLC();          // << entities
+    GetEntitiesInListL( iPresIdentity->Des(), *entities );
+
+    // callback for data
+    MXIMPIdentity* id = myFactory.NewIdentityLC();  // << id
+    id->SetIdentityL( iPresIdentity->Des() );
+#ifdef _DEBUG
+    PluginLogger::Log(
+        _L("PluginWatcher: callback HandlePresentityGroupContentL"));
+#endif
+    dataHost.HandlePresentityGroupContentL( id, entities );
+    CleanupStack::Pop();                            // >> id
+    CleanupStack::Pop();                            // >> entities
+
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::CopyGroupMembersToCollectionL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::CopyGroupMembersToCollectionL(
+    CPtrCArray& aIds, CPtrCArray& aNames, MXIMPObjectCollection& aCollection)
+    {
+    MXIMPObjectFactory& myFactory = iConnObs.ObjectFactory();
+    MPresenceObjectFactory& myPresenceFactory = iConnObs.PresenceObjectFactory();
+    TInt count = aIds.Count();
+    for ( TInt i=0; i < count; i++ )
+        {
+        // create here MPresentityGroupMemberInfo
+        MPresentityGroupMemberInfo* info = myPresenceFactory.NewPresentityGroupMemberInfoLC(); // << info
+        MXIMPIdentity* id = myFactory.NewIdentityLC();  // << id
+        id->SetIdentityL( aIds[i] );
+        info->SetGroupMemberIdL( id );
+        CleanupStack::Pop(); // >> id
+
+        info->SetGroupMemberDisplayNameL( aNames[i] );
+        aCollection.AddObjectL( info );
+        CleanupStack::Pop(); // >> info
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoRunForSubscriptionL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoRunForSubscriptionL( )
+    {
+    if ( iXdmState == EPluginInitXdm )
+        {
+        // get members of the list first
+        GetListContentL();
+
+        // Fetch RLS document first before modifying the data.
+        TRAPD( err, iXdmUtils->FetchRlsL( iStatus ));
+        if ( err )
+            {
+            CompletePrFwReq( err );
+            }
+        else
+            {
+            iXdmState = EPluginFetchRls;
+            SetActive();
+            }
+        }
+    else if ( iXdmState == EPluginFetchRls )
+        {
+        // Create RLS document service
+        iXdmUtils->AddRlsGroupL( iPresIdentity->Des() );
+        iXdmState = EPluginAddGroupMember;
+        iXdmUtils->CommitRlsL( iStatus );
+        SetActive();
+        }
+    else
+        {
+        StartWatchingRlsL();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CSimplePluginWatcher::DoRunForUnsubscriptionL
+// ---------------------------------------------------------------------------
+//
+void CSimplePluginWatcher::DoRunForUnsubscriptionL( )
+    {
+    TInt status = iStatus.Int();
+    if ( iXdmState == EPluginIdle )
+        {
+        TRAPD( err, iXdmUtils->FetchRlsL( iStatus ));
+        if ( err )
+            {
+            CompletePrFwReq( err );
+            }
+        else
+            {
+            iXdmState = EPluginFetchRls;
+            SetActive();
+            }
+        }
+    else if ( iXdmState == EPluginFetchRls )
+        {
+        TRAPD( err, iXdmUtils->RemoveRlsServiceByResourceListL( iPresIdentity->Des(), iStatus ));
+        if ( err )
+            {
+            CompletePrFwReq( err );
+            }
+        else
+            {
+            iXdmState = EPluginRemoveGroupMember;
+            SetActive();
+            }
+        }
+    else
+        {
+        CompletePrFwReq( status );
+        }
+    }
+
+
+
+// End of file