ncdengine/provider/client/src/ncdsubscriptionmanagerproxy.cpp
changeset 0 ba25891c3a9e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Contains CNcdSubscriptionManagerProxy class implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdsubscriptionmanagerproxy.h"
       
    20 #include "ncdsubscriptiongroupproxy.h"
       
    21 #include "ncdsubscriptionproxy.h"
       
    22 #include "ncdsubscriptionoperationproxy.h"
       
    23 #include "ncdoperationimpl.h"
       
    24 #include "ncddownloadoperationproxy.h"
       
    25 #include "ncdoperationmanagerproxy.h"
       
    26 #include "ncdoperationdatatypes.h"
       
    27 #include "catalogsclientserver.h"
       
    28 #include "ncdnodeidentifier.h"
       
    29 #include "ncdnodefunctionids.h"
       
    30 #include "ncdnodeclassids.h"
       
    31 #include "catalogsinterfaceidentifier.h"
       
    32 #include "catalogsutils.h"
       
    33 #include "ncdutils.h"
       
    34 #include "catalogsconstants.h"
       
    35 #include "ncdsubscriptionmanagerlistener.h"
       
    36 
       
    37 #include "catalogsdebug.h"
       
    38 
       
    39 // ======== PUBLIC MEMBER FUNCTIONS ========
       
    40 
       
    41 CNcdSubscriptionManagerProxy::CNcdSubscriptionManagerProxy(
       
    42     MCatalogsClientServer& aSession,
       
    43     TInt aHandle,
       
    44     CCatalogsInterfaceBase* aParent,
       
    45     CNcdOperationManagerProxy& aOperationManager )
       
    46     : CNcdInterfaceBaseProxy( aSession, aHandle, aParent ),
       
    47       iOperationManager( aOperationManager )
       
    48     {
       
    49     }
       
    50 
       
    51 
       
    52 void CNcdSubscriptionManagerProxy::ConstructL()
       
    53     {
       
    54     DLTRACEIN((""));
       
    55     
       
    56     // Register the interface
       
    57     MNcdSubscriptionManager* interface( this );
       
    58     AddInterfaceL( CCatalogsInterfaceIdentifier::NewL( 
       
    59                         interface, this,
       
    60                         MNcdSubscriptionManager::KInterfaceUid ) );
       
    61                         
       
    62     // Create listener.
       
    63     iListener = CNcdSubscriptionManagerListener::NewL( *this );
       
    64     
       
    65     iInputBuf.CreateL( 1 );
       
    66     iOutputBuf.CreateL( 1 );
       
    67     
       
    68     
       
    69     // Is it ok if internalization fails here?
       
    70     // Earlier comment: Do not let the internalization leave here.
       
    71     //                  This object may be reinternalized later.
       
    72     InternalizeL();
       
    73     
       
    74     // Send an asynchronous message to server side subscription manager to be notified
       
    75     // when subscription states are changed in server side.
       
    76     ClientServerSession().SendAsync(
       
    77         NcdNodeFunctionIds::ENcdListenerEnrollment,
       
    78         iOutputBuf,
       
    79         iInputBuf,
       
    80         Handle(),
       
    81         iListener->iStatus );
       
    82             
       
    83     iListener->Activate();
       
    84         
       
    85     DLTRACEOUT((""));
       
    86     }
       
    87 
       
    88 
       
    89 CNcdSubscriptionManagerProxy* CNcdSubscriptionManagerProxy::NewL(
       
    90     MCatalogsClientServer& aSession,
       
    91     TInt aHandle,
       
    92     CCatalogsInterfaceBase* aParent,
       
    93     CNcdOperationManagerProxy& aOperationManager )
       
    94     {
       
    95     CNcdSubscriptionManagerProxy* self = 
       
    96         CNcdSubscriptionManagerProxy::NewLC( aSession,
       
    97                                              aHandle,
       
    98                                              aParent,
       
    99                                              aOperationManager );
       
   100     CleanupStack::Pop( self );
       
   101     return self;
       
   102     }
       
   103 
       
   104 CNcdSubscriptionManagerProxy* CNcdSubscriptionManagerProxy::NewLC(
       
   105     MCatalogsClientServer& aSession,
       
   106     TInt aHandle,
       
   107     CCatalogsInterfaceBase* aParent,
       
   108     CNcdOperationManagerProxy& aOperationManager )
       
   109     {
       
   110     CNcdSubscriptionManagerProxy* self = 
       
   111         new( ELeave ) CNcdSubscriptionManagerProxy( aSession,
       
   112                                                     aHandle,
       
   113                                                     aParent,
       
   114                                                     aOperationManager );
       
   115     // Using PushL because the object does not have any references yet
       
   116     CleanupStack::PushL( self );
       
   117     self->ConstructL();
       
   118     return self;
       
   119     }
       
   120 
       
   121 
       
   122 CNcdSubscriptionManagerProxy::~CNcdSubscriptionManagerProxy()
       
   123     {
       
   124     // Remove interfaces implemented by this class from the interface list.
       
   125     // So, the interface list is up to date when this class object is deleted.
       
   126     RemoveInterface( MNcdSubscriptionManager::KInterfaceUid );
       
   127     
       
   128     iSubscriptionGroups.ResetAndDestroy();
       
   129     
       
   130     delete iListener;
       
   131     iInputBuf.Close();
       
   132     iOutputBuf.Close();
       
   133     }
       
   134 
       
   135 
       
   136 void CNcdSubscriptionManagerProxy::SetNodeManager(
       
   137     CNcdNodeManagerProxy* aManager )
       
   138     {
       
   139     // Not owned so no deletion needed for possible previous object
       
   140     iNodeManager = aManager;
       
   141     }
       
   142 
       
   143 void CNcdSubscriptionManagerProxy::InternalizeL()
       
   144     {
       
   145     DLTRACEIN((""));
       
   146     
       
   147     // Request the subscription group identifiers from server.
       
   148     RPointerArray<CNcdKeyValuePair> groupIds = SubscriptionGroupIdentifiersL();    
       
   149     CleanupResetAndDestroyPushL( groupIds );
       
   150     
       
   151     DLINFO(("Amount of ids received: %d", groupIds.Count() ));
       
   152     
       
   153     // Release the subscription groups that don't exist in server side.
       
   154     DeleteMissingSubscriptionGroups( groupIds );
       
   155     
       
   156     // Reinternalize existing subscriptiongroup.
       
   157     InternalizeSubscriptionGroupsL();
       
   158     
       
   159     // Remove the subscription groups from the array which are up to date currently.
       
   160     for ( TInt i = groupIds.Count() - 1; i >= 0; i-- ) 
       
   161         {
       
   162         if ( SubscriptionGroup( groupIds[i]->Value(), groupIds[i]->Key() ) != NULL ) 
       
   163             {
       
   164             delete groupIds[i];
       
   165             groupIds.Remove( i );
       
   166             }
       
   167         }
       
   168                
       
   169     // Request handles to the new subscription groups
       
   170     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
   171     CleanupStack::PushL( buf );
       
   172     
       
   173     RBufWriteStream writeStream( *buf );
       
   174     CleanupClosePushL( writeStream );
       
   175     
       
   176     writeStream.WriteInt32L( groupIds.Count() );
       
   177     for ( TInt i = 0; i < groupIds.Count(); i++ ) 
       
   178         {
       
   179         groupIds[i]->ExternalizeL( writeStream );
       
   180         }
       
   181         
       
   182     CleanupStack::PopAndDestroy( &writeStream );
       
   183             
       
   184     
       
   185     HBufC8* dataToSend = HBufC8::NewL( buf->Size() );
       
   186     dataToSend->Des().Copy( buf->Ptr( 0 ) );
       
   187     CleanupStack::PopAndDestroy( buf );
       
   188     CleanupStack::PushL( dataToSend );
       
   189 
       
   190     HBufC8* data( NULL );
       
   191     
       
   192     DLINFO(("Request buffer: %S", dataToSend ));
       
   193         
       
   194     // Because we do not know the exact size of the data, use
       
   195     // the alloc method, which creates the buffer of the right size
       
   196     // and sets the pointer to point to the created buffer.
       
   197     // Get all the data that is necessary to internalize this object
       
   198     // from the server side.
       
   199     User::LeaveIfError(
       
   200         ClientServerSession().
       
   201         SendSyncAlloc( NcdNodeFunctionIds::ENcdInternalize,
       
   202                        *dataToSend,
       
   203                        data,
       
   204                        Handle(),
       
   205                        0 ) );
       
   206 
       
   207     if ( data == NULL )
       
   208         {
       
   209         DLERROR((""));
       
   210         User::Leave(  KErrNotFound );
       
   211         }
       
   212         
       
   213     CleanupStack::PopAndDestroy( dataToSend );
       
   214     CleanupStack::PushL( data );
       
   215 
       
   216     // Read the data from the stream and insert it to the memeber variables
       
   217     RDesReadStream stream( *data );
       
   218     CleanupClosePushL( stream );
       
   219     
       
   220     TRAPD( internalizeError, InternalizeDataL( stream ) );
       
   221     if ( internalizeError != KErrNone )
       
   222         {
       
   223         // Should check that no handles are left to the
       
   224         // stream. If there are, release messages should
       
   225         // be sent to the server side with those handles.
       
   226         iSubscriptionGroups.ResetAndDestroy();
       
   227         User::Leave( internalizeError );
       
   228         }
       
   229     
       
   230     // Closes the stream
       
   231     CleanupStack::PopAndDestroy( &stream ); 
       
   232     CleanupStack::PopAndDestroy( data );
       
   233     CleanupStack::PopAndDestroy( &groupIds );
       
   234 
       
   235     DLTRACEOUT((""));    
       
   236     }
       
   237 
       
   238 
       
   239 TBool CNcdSubscriptionManagerProxy::ActiveSubscriptionExists(
       
   240     const TDesC& aEntityId,
       
   241     const TDesC& aNamespace,
       
   242     const TDesC& aPurchaseOptionId )
       
   243     {
       
   244     DLTRACEIN((""));
       
   245     CNcdSubscriptionProxy* searchedSubscription( NULL );
       
   246     searchedSubscription = Subscription( aEntityId,
       
   247                                          aNamespace,
       
   248                                          aPurchaseOptionId );
       
   249 
       
   250     if ( searchedSubscription != NULL )
       
   251         {
       
   252         if ( searchedSubscription->SubscriptionStatus() ==
       
   253                  MNcdSubscription::ESubscriptionActive )
       
   254             {
       
   255             DLTRACEOUT(("Return ETrue"));
       
   256             return ETrue;
       
   257             }
       
   258         }    
       
   259     DLTRACEOUT(("Return EFalse"));
       
   260     return EFalse;
       
   261     }
       
   262 
       
   263 CNcdSubscriptionProxy* CNcdSubscriptionManagerProxy::Subscription(
       
   264     const TDesC& aEntityId,
       
   265     const TDesC& aNamespace,
       
   266     const TDesC& aPurchaseOptionId )
       
   267     {
       
   268     DLTRACEIN((""));    
       
   269     CNcdSubscriptionProxy* resultSubscription( NULL );
       
   270     
       
   271     // First find the subscription group...
       
   272     CNcdSubscriptionGroupProxy* group( NULL );
       
   273     group = SubscriptionGroup( aEntityId, aNamespace );
       
   274     
       
   275     if ( group != NULL )
       
   276         {        
       
   277         // then subscription...
       
   278         resultSubscription = group->Subscription( aPurchaseOptionId );
       
   279         }
       
   280     
       
   281     DLTRACEOUT((""));
       
   282     return resultSubscription;
       
   283     }
       
   284 
       
   285 void CNcdSubscriptionManagerProxy::SubscriptionsChangedL() 
       
   286     {
       
   287     DLTRACEIN((""));
       
   288     
       
   289     // Send new listener enrollment message to server side.
       
   290     ClientServerSession().SendAsync(
       
   291         NcdNodeFunctionIds::ENcdListenerEnrollment,
       
   292         iOutputBuf,
       
   293         iInputBuf,
       
   294         Handle(),
       
   295         iListener->iStatus );
       
   296     iListener->Activate();
       
   297         
       
   298     // Internalize the data from server.
       
   299     InternalizeL();
       
   300     }
       
   301         
       
   302 
       
   303 
       
   304 // MNcdSubscriptionManager functions
       
   305     
       
   306 
       
   307 
       
   308 // ---------------------------------------------------------------------------
       
   309 // Subscriptions are now under subscription groups so they are not
       
   310 // kept in one large array.
       
   311 // Benefit from the one large array would be that the returning of
       
   312 // all subscriptions in this function would be easy but because
       
   313 // the array would have to be updated or remade after every
       
   314 // update from server (which is always before this function) it seems
       
   315 // that keeping up the large array does not benefit us. Atleast
       
   316 // not in this function.
       
   317 // ---------------------------------------------------------------------------
       
   318 //
       
   319 RCatalogsArray<MNcdSubscription> 
       
   320     CNcdSubscriptionManagerProxy::SubscriptionsL() const
       
   321     {
       
   322     DLTRACEIN(( "" ));
       
   323     
       
   324     // When ui asks for subscriptions it does it in the
       
   325     // management view so the ui should update the subscriptions
       
   326     // from the server before this function. Update is not done here.
       
   327 
       
   328     // Let's make one array out of the subscriptions
       
   329     RCatalogsArray<MNcdSubscription> subscriptions;
       
   330     
       
   331     // in case of leave, destroy its contents (release)
       
   332     CleanupResetAndDestroyPushL( subscriptions );
       
   333 
       
   334     
       
   335     TInt groupCount( iSubscriptionGroups.Count() );
       
   336     TInt groupIndexer( 0 );
       
   337     
       
   338     DLINFO(( "Coming to while" ));
       
   339     while ( groupIndexer < groupCount )
       
   340         {
       
   341         // through all groups
       
   342         const RPointerArray<CNcdSubscriptionProxy>& subscriptionsOfGroup
       
   343             = iSubscriptionGroups[groupIndexer]->Subscriptions();
       
   344         
       
   345         TInt subscriptionCount( subscriptionsOfGroup.Count() );
       
   346         TInt subscriptionIndexer( 0 );
       
   347         
       
   348         DLINFO(( "Coming to while2" ));
       
   349         while ( subscriptionIndexer < subscriptionCount )
       
   350             {
       
   351             // through all subscriptions of group
       
   352             subscriptions.AppendL(
       
   353                 subscriptionsOfGroup[subscriptionIndexer] );
       
   354             subscriptionsOfGroup[subscriptionIndexer]->AddRef();        
       
   355             ++subscriptionIndexer;
       
   356             }
       
   357         
       
   358         ++groupIndexer;
       
   359         }
       
   360     CleanupStack::Pop( &subscriptions );
       
   361     
       
   362     DLTRACEOUT(( "" ));
       
   363     return subscriptions;
       
   364     }
       
   365 
       
   366 
       
   367 MNcdSubscriptionOperation* 
       
   368     CNcdSubscriptionManagerProxy::RefreshSubscriptionsL(
       
   369         MNcdSubscriptionOperationObserver& aObserver )
       
   370     {
       
   371     DLTRACEIN((""));
       
   372 
       
   373     CNcdSubscriptionOperationProxy* operation( NULL );
       
   374 
       
   375     operation =
       
   376         iOperationManager.CreateSubscriptionRefreshOperationL( aObserver );
       
   377 
       
   378     DLTRACEOUT((""));
       
   379 
       
   380     return operation;
       
   381     }
       
   382 
       
   383 
       
   384 
       
   385 // Other functions
       
   386 
       
   387 CNcdOperationManagerProxy&
       
   388     CNcdSubscriptionManagerProxy::OperationManager() const
       
   389     {
       
   390     return iOperationManager;
       
   391     }
       
   392 
       
   393 
       
   394 
       
   395 void CNcdSubscriptionManagerProxy::InternalizeDataL( RReadStream& aStream )
       
   396     {
       
   397     DLTRACEIN((""));    
       
   398 
       
   399     TInt handleAmount( 0 );
       
   400     handleAmount = aStream.ReadInt32L();
       
   401     
       
   402     DLTRACE(( "Amount of subscriptiongroup handles received: %d",
       
   403               handleAmount ));
       
   404 
       
   405     TInt tmpProxyHandle( -1 ); // handle of a proxy read from stream
       
   406     
       
   407     // temporary pointer to subscription group that is going to be
       
   408     // added to subscriptiongroups-array
       
   409     CNcdSubscriptionGroupProxy* tmpSubscriptionGroup( NULL );
       
   410     
       
   411 
       
   412     // In error handling, objects with received handles
       
   413     // should be released from the server side session
       
   414     // if proxies for them cannot be created.
       
   415 
       
   416     TInt handleIndex( 0 );
       
   417     while ( handleIndex < handleAmount )
       
   418         {
       
   419         tmpProxyHandle = aStream.ReadInt32L();
       
   420         
       
   421         DLTRACE(( "Received subscriptiongroup handle: %i",
       
   422                   tmpProxyHandle ));
       
   423                       
       
   424         tmpSubscriptionGroup = CNcdSubscriptionGroupProxy::NewL( 
       
   425                                 ClientServerSession(),
       
   426                                 tmpProxyHandle,
       
   427                                 OperationManager(),
       
   428                                 *iNodeManager );                
       
   429 
       
   430         TRAPD( addError, iSubscriptionGroups.AppendL( tmpSubscriptionGroup ) );
       
   431         if ( addError != KErrNone )
       
   432             {
       
   433             delete tmpSubscriptionGroup;
       
   434             User::Leave( addError );
       
   435             }
       
   436 
       
   437         ++handleIndex;
       
   438         }
       
   439 
       
   440     DLTRACEOUT((""));
       
   441     }
       
   442 
       
   443 RPointerArray<CNcdKeyValuePair> CNcdSubscriptionManagerProxy::SubscriptionGroupIdentifiersL() const 
       
   444     {
       
   445     DLTRACEIN((""));
       
   446     
       
   447     HBufC8* data( NULL );
       
   448 
       
   449     // Because we do not know the exact size of the data, use
       
   450     // the alloc method, which creates the buffer of the right size
       
   451     // and sets the pointer to point to the created buffer.
       
   452     User::LeaveIfError(
       
   453         ClientServerSession().
       
   454         SendSyncAlloc( NcdNodeFunctionIds::ENcdSubscriptionGroupIdentifiers,
       
   455                        KNullDesC8,
       
   456                        data,
       
   457                        Handle(),
       
   458                        0 ) );
       
   459 
       
   460     if ( data == NULL )
       
   461         {
       
   462         DLERROR((""));
       
   463         User::Leave(  KErrNotFound );
       
   464         }
       
   465         
       
   466     CleanupStack::PushL( data );
       
   467 
       
   468     // Read the data from the stream and insert it to the memeber variables
       
   469     RDesReadStream stream( *data );
       
   470     CleanupClosePushL( stream );
       
   471      
       
   472     TInt32 identifierCount = stream.ReadInt32L();
       
   473     RPointerArray<CNcdKeyValuePair> identifiers;
       
   474     CleanupResetAndDestroyPushL( identifiers );
       
   475     identifiers.ReserveL( identifierCount );
       
   476     for ( TInt i = 0 ; i < identifierCount; i++ ) 
       
   477         {
       
   478         CNcdKeyValuePair* pair = CNcdKeyValuePair::NewL( stream );
       
   479         TInt err = identifiers.Append( pair );
       
   480         // Error should not be possible since there should be enough room to append.
       
   481         DASSERT( err == KErrNone );
       
   482         }
       
   483         
       
   484     CleanupStack::Pop( &identifiers );
       
   485     CleanupStack::PopAndDestroy( &stream );
       
   486     CleanupStack::PopAndDestroy( data );
       
   487      
       
   488     return identifiers;
       
   489     }
       
   490     
       
   491 void CNcdSubscriptionManagerProxy::DeleteMissingSubscriptionGroups(
       
   492     const RPointerArray<CNcdKeyValuePair>& aGroupIdentifiers ) 
       
   493     {
       
   494     DLTRACEIN((""));
       
   495     
       
   496     for ( TInt i = iSubscriptionGroups.Count() - 1; i >= 0; i-- ) 
       
   497         {
       
   498         const TDesC& nameSpace = iSubscriptionGroups[i]->Namespace();
       
   499         const TDesC& entityId = iSubscriptionGroups[i]->EntityId();
       
   500         
       
   501         TBool found = EFalse;
       
   502         for ( TInt idIndexer = 0; idIndexer < aGroupIdentifiers.Count(); idIndexer++ ) 
       
   503             {
       
   504             if ( aGroupIdentifiers[idIndexer]->Key() == nameSpace &&
       
   505                  aGroupIdentifiers[idIndexer]->Value() == entityId ) 
       
   506                 {
       
   507                 found = ETrue;
       
   508                 break;
       
   509                 }
       
   510             }
       
   511         
       
   512         if ( !found ) 
       
   513             {
       
   514             delete iSubscriptionGroups[i];
       
   515             iSubscriptionGroups.Remove( i );
       
   516             }            
       
   517         }
       
   518     }        
       
   519     
       
   520 void CNcdSubscriptionManagerProxy::InternalizeSubscriptionGroupsL() const 
       
   521     {
       
   522     DLTRACEIN((""));
       
   523     for ( TInt i = 0; i < iSubscriptionGroups.Count(); i++ ) 
       
   524         {
       
   525         iSubscriptionGroups[i]->InternalizeL();
       
   526         }
       
   527     }
       
   528 
       
   529 CNcdSubscriptionGroupProxy* CNcdSubscriptionManagerProxy::SubscriptionGroup(
       
   530     const TDesC& aEntityId,
       
   531     const TDesC& aNamespace )
       
   532     {
       
   533     DLTRACEIN((""));
       
   534     // Search for the subscription group
       
   535 
       
   536     TInt groupCount( iSubscriptionGroups.Count() );
       
   537     TInt groupIndexer( 0 );
       
   538     while ( groupIndexer < groupCount )
       
   539         {        
       
   540         const TDesC& groupsEntityId =
       
   541             iSubscriptionGroups[groupIndexer]->EntityId();
       
   542         const TDesC& groupsNamespace =
       
   543             iSubscriptionGroups[groupIndexer]->Namespace();
       
   544 
       
   545         DLINFO(( _L("Searched entityid: %S, now entityid: %S"),
       
   546                  &aEntityId,
       
   547                  &groupsEntityId ));        
       
   548         
       
   549         if ( aEntityId == groupsEntityId )
       
   550             {
       
   551 
       
   552             DLINFO(( _L("Searched namespace: %S, now namespace: %S"),
       
   553                      &aNamespace,
       
   554                      &groupsNamespace ));
       
   555                  
       
   556             if ( aNamespace == groupsNamespace )
       
   557                 {
       
   558                 DLTRACEOUT(("Found."));
       
   559                 return iSubscriptionGroups[groupIndexer];
       
   560                 }
       
   561             
       
   562             }
       
   563         
       
   564         ++groupIndexer;
       
   565         }
       
   566 
       
   567     DLTRACEOUT(("Not found."));
       
   568     return NULL;
       
   569     }
       
   570