ncdengine/provider/server/src/ncdnodeupgradeimpl.cpp
changeset 0 ba25891c3a9e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2006-2008 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:   Implements CNcdNodeUpgrade class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdnodeupgradeimpl.h"
       
    20 
       
    21 #include "ncdnodemetadataimpl.h"
       
    22 #include "ncddownloadinfo.h"
       
    23 #include "catalogssession.h"
       
    24 #include "catalogsbasemessage.h"
       
    25 #include "ncdnodefunctionids.h"
       
    26 #include "ncdnodeclassids.h"
       
    27 #include "catalogsconstants.h"
       
    28 #include "ncd_pp_dataentity.h"
       
    29 #include "ncd_pp_dataentitycontent.h"
       
    30 #include "ncd_pp_entitydependency.h"
       
    31 #include "ncd_cp_query.h"
       
    32 #include "ncdnodeidentifier.h"
       
    33 #include "ncddependencyinfo.h"
       
    34 #include "catalogsutils.h"
       
    35 #include "ncderrors.h"
       
    36 #include "ncdproviderutils.h"
       
    37 #include "ncdattributes.h"
       
    38 
       
    39 #include "catalogsdebug.h"
       
    40 
       
    41 
       
    42 CNcdNodeUpgrade::CNcdNodeUpgrade( CNcdNodeMetaData& aParentMetaData, 
       
    43                                   NcdNodeClassIds::TNcdNodeClassId aClassId )
       
    44 : CNcdCommunicable(),
       
    45   iParentMetaData( aParentMetaData ),
       
    46   iClassId( aClassId )
       
    47     {
       
    48     }
       
    49 
       
    50 void CNcdNodeUpgrade::ConstructL()
       
    51     {
       
    52     // These values have to be set.
       
    53     iUpgradeData = CNcdAttributes::NewL( EUpgradeDataInternal );
       
    54     }
       
    55 
       
    56 
       
    57 CNcdNodeUpgrade* CNcdNodeUpgrade::NewL( CNcdNodeMetaData& aParentMetaData )
       
    58     {
       
    59     CNcdNodeUpgrade* self =   
       
    60         CNcdNodeUpgrade::NewLC( aParentMetaData );
       
    61     CleanupStack::Pop( self );
       
    62     return self;        
       
    63     }
       
    64 
       
    65 CNcdNodeUpgrade* CNcdNodeUpgrade::NewLC( CNcdNodeMetaData& aParentMetaData )
       
    66     {
       
    67     CNcdNodeUpgrade* self = 
       
    68         new( ELeave ) CNcdNodeUpgrade( 
       
    69             aParentMetaData,
       
    70             NcdNodeClassIds::ENcdNodeUpgradeClassId );
       
    71     CleanupClosePushL( *self );
       
    72     self->ConstructL();
       
    73     return self;        
       
    74     }
       
    75 
       
    76 
       
    77 CNcdNodeUpgrade::~CNcdNodeUpgrade()
       
    78     {
       
    79     DLTRACEIN((""));
       
    80 
       
    81     // Delete member variables here
       
    82     iUpgradeNodeTargets.ResetAndDestroy();
       
    83     iUpgradeContentTargets.ResetAndDestroy();
       
    84     delete iUpgradeData;
       
    85     // Do not delete parent metadata because it is not owned here.
       
    86 
       
    87     DLTRACEOUT((""));
       
    88     }        
       
    89 
       
    90 
       
    91 NcdNodeClassIds::TNcdNodeClassId CNcdNodeUpgrade::ClassId() const
       
    92     {
       
    93     return iClassId;
       
    94     }
       
    95 
       
    96 
       
    97 const RPointerArray<CNcdDownloadInfo>& CNcdNodeUpgrade::ContentTargets() const
       
    98     {
       
    99     return iUpgradeContentTargets;
       
   100     }
       
   101 
       
   102 
       
   103 const RPointerArray<CNcdDependencyInfo>& CNcdNodeUpgrade::NodeTargets() const
       
   104     {
       
   105     return iUpgradeNodeTargets;
       
   106     }
       
   107 
       
   108 
       
   109 // Internalization from the protocol
       
   110 
       
   111 void CNcdNodeUpgrade::InternalizeL( 
       
   112     MNcdPreminetProtocolDataEntity& aData,
       
   113     const TDesC& aVersion )
       
   114     {
       
   115     DLTRACEIN((""));
       
   116 
       
   117     // First create the new values
       
   118 
       
   119     // Notice that ownerships are not transferred from the parser objects.
       
   120     const MNcdPreminetProtocolDataEntityContent* downloadableContent = 
       
   121         aData.DownloadableContent();
       
   122     if ( downloadableContent == NULL )
       
   123         {
       
   124         DLINFO(("No data present"));
       
   125         // Content data not present.
       
   126         User::Leave( KErrNotFound );
       
   127         }
       
   128 
       
   129     // Reset the array here.
       
   130     // If something here fails after this. Then, the owner of this class object 
       
   131     // should remove this class object from the metadata anyway.
       
   132     iUpgradeNodeTargets.ResetAndDestroy();
       
   133 
       
   134     const MNcdPreminetProtocolEntityDependency* dependency( NULL );
       
   135     CNcdNodeIdentifier* identifier( NULL );
       
   136     CNcdDependencyInfo* upgradeInfo( NULL );    
       
   137     for ( TInt i = 0; i < downloadableContent->EntityDependencyCount(); ++i )
       
   138         {
       
   139         // Check what nodes depend on this node.
       
   140         dependency = &downloadableContent->EntityDependencyL( i );
       
   141         if ( dependency->Type() == EUpgradeDependency )
       
   142             {
       
   143             // Check if the upgrade should be loaded as a node when
       
   144             // the download responsibility is transferred to the proxy side
       
   145             // or should we just download the content directly in server side.
       
   146             if ( dependency->EntityId() != KNullDesC )
       
   147                 {
       
   148                 DLINFO((_L("Upgrade entity id: %S"), &dependency->EntityId()));
       
   149                 // The dependecy information contains  the
       
   150                 // entity id of the target node.
       
   151                 identifier = 
       
   152                     CNcdNodeIdentifier::NewL( iParentMetaData.Identifier().NodeNameSpace(),
       
   153                                               dependency->EntityId(),                                           
       
   154                                               iParentMetaData.Identifier().ServerUri(),
       
   155                                               iParentMetaData.Identifier().ClientUid() );
       
   156                 // Note, that identifier ownership is transferred here.
       
   157                 upgradeInfo = 
       
   158                     CNcdDependencyInfo::NewLC( dependency->Name(),
       
   159                                                aVersion,
       
   160                                                dependency->ContentId(),
       
   161                                                identifier );
       
   162                 iUpgradeNodeTargets.AppendL( upgradeInfo );
       
   163                 CleanupStack::Pop( upgradeInfo );   
       
   164 
       
   165                 }
       
   166             else
       
   167                 {
       
   168                 // Ownership is not transferred here.
       
   169                 const MNcdPreminetProtocolDownload* downloadDetails( 
       
   170                     dependency->DownloadDetails() );
       
   171                 if ( downloadDetails != NULL )
       
   172                     {
       
   173                     DLINFO(("Download the content directly. New node will not be created."));
       
   174                     // Copy the content object and insert it into the content array.
       
   175                     // The purchase operation may use the array content when checking
       
   176                     // if upgrades should be downloaded and installed.
       
   177                     CNcdDownloadInfo* content( 
       
   178                         CNcdDownloadInfo::NewLC( *dependency ) );
       
   179                     iUpgradeContentTargets.AppendL( content );
       
   180                     content->SetContentUsage( MNcdPurchaseDownloadInfo::EUpgrade );
       
   181                     // Array took ownership. So, do not delete.
       
   182                     CleanupStack::Pop( content );                    
       
   183                     }
       
   184                 }
       
   185             }
       
   186         }
       
   187 
       
   188     if ( iUpgradeNodeTargets.Count() == 0
       
   189          && iUpgradeContentTargets.Count() == 0 )
       
   190         {
       
   191         // No upgrade data was found. 
       
   192         // So, inform about that to the owner of this class object.
       
   193         DLINFO(("No content"));
       
   194         User::Leave( KErrNotFound );
       
   195         }
       
   196 
       
   197     DLTRACEOUT((""));
       
   198     }
       
   199 
       
   200 
       
   201 
       
   202 TBool CNcdNodeUpgrade::AllUpgradesInstalledL() const
       
   203     {
       
   204     DLTRACEIN(("Checking %d upgrades", 
       
   205         iUpgradeContentTargets.Count() ));
       
   206         
       
   207     // Check if the upgrades have already been installed
       
   208     // Note that missing app is also considered as installed because
       
   209     // we can't upgrade "nothing" :)
       
   210     for ( TInt i = 0; i < iUpgradeContentTargets.Count(); ++i ) 
       
   211         {
       
   212         if ( CNcdProviderUtils::IsApplicationInstalledL( 
       
   213                 iUpgradeContentTargets[i]->ContentId(), 
       
   214                 iUpgradeContentTargets[i]->ContentVersion() ) 
       
   215              == ENcdApplicationOlderVersionInstalled )
       
   216             {
       
   217             DLTRACEOUT(("All upgrades have not been installed yet"));
       
   218             return EFalse;
       
   219             }
       
   220         }
       
   221 
       
   222     // Check if the upgrades have already been installed
       
   223     for ( TInt i = 0; i < iUpgradeNodeTargets.Count(); ++i ) 
       
   224         {
       
   225         if ( CNcdProviderUtils::IsApplicationInstalledL( 
       
   226                 iUpgradeNodeTargets[i]->Uid(), 
       
   227                 iUpgradeNodeTargets[i]->Version() ) 
       
   228              == ENcdApplicationOlderVersionInstalled )
       
   229             {
       
   230             DLTRACEOUT(("All upgrade node contents have not been installed yet"));
       
   231             return EFalse;
       
   232             }
       
   233         }
       
   234     
       
   235     DLTRACEOUT(("All upgrades have been installed"));
       
   236     return ETrue;
       
   237     }
       
   238 
       
   239 
       
   240 void CNcdNodeUpgrade::SetContentUpgradesL( 
       
   241     TBool aContentUpgrades, 
       
   242     const TUid& aUid,
       
   243     const TDesC& aVersion )
       
   244     {
       
   245     DLTRACEIN(("aContentUpgrades = %d", aContentUpgrades ));
       
   246     iContentUpgrades = aContentUpgrades;        
       
   247     
       
   248     iUpgradeData->SetAttributeL( EUpgradeDataVersion, aVersion );
       
   249     iUpgradeData->SetAttributeL( EUpgradeDataUid, aUid.iUid );
       
   250     
       
   251     }
       
   252 
       
   253 TBool CNcdNodeUpgrade::ContentUpgrades() const
       
   254     {
       
   255     DLTRACEIN(("ContentUpgrades: %d", iContentUpgrades));
       
   256     return iContentUpgrades;
       
   257     }
       
   258 
       
   259 
       
   260 // Internalization from and externalization to the database
       
   261     
       
   262 void CNcdNodeUpgrade::ExternalizeL( RWriteStream& aStream )
       
   263     {
       
   264     DLTRACEIN((""));
       
   265 
       
   266     // The upgrade may be provided even if arrays are empty if
       
   267     // the content upgrade flag is set.
       
   268     if ( iUpgradeNodeTargets.Count() == 0
       
   269          && iUpgradeContentTargets.Count() == 0
       
   270          && !ContentUpgrades() )
       
   271         {
       
   272         DLERROR(("No content"));
       
   273         DASSERT( EFalse );
       
   274         User::Leave( KErrNotFound );
       
   275         }
       
   276 
       
   277     // First insert data that the creator of this class object will use to
       
   278     // create this class object. Class id informs what class object
       
   279     // will be created.
       
   280     
       
   281     aStream.WriteInt32L( iClassId );
       
   282     
       
   283     ExternalizeNodeUpgradeArrayL( aStream );
       
   284     ExternalizeContentUpgradeArrayL( aStream );
       
   285     aStream.WriteInt32L( iContentUpgrades );
       
   286     }
       
   287     
       
   288 void CNcdNodeUpgrade::InternalizeL( RReadStream& aStream )
       
   289     {
       
   290     DLTRACEIN((""));
       
   291 
       
   292     // Read the class id first because it is set to the stream in internalize
       
   293     // function and it is not read from the stream anywhere else.
       
   294     TInt classId( aStream.ReadInt32L() );
       
   295     if ( classId != ClassId() )
       
   296         {
       
   297         DLTRACE(("Wrong class id"));
       
   298         DASSERT( EFalse );
       
   299         // Leave because the stream does not match this class object
       
   300         User::Leave( KErrCorrupt );
       
   301         }
       
   302 
       
   303     InternalizeNodeUpgradeArrayL( aStream ); 
       
   304     InternalizeContentUpgradeArrayL( aStream );
       
   305 
       
   306     iContentUpgrades = aStream.ReadInt32L();
       
   307     DLTRACEOUT((""));
       
   308     }
       
   309 
       
   310 
       
   311 void CNcdNodeUpgrade::ReceiveMessage( MCatalogsBaseMessage* aMessage,
       
   312                                       TInt aFunctionNumber )
       
   313     {
       
   314     DLTRACEIN((""));    
       
   315 
       
   316     DASSERT( aMessage );
       
   317     
       
   318     // Now, we can be sure that rest of the time iMessage exists.
       
   319     // This member variable is set for the CounterPartLost function.
       
   320     iMessage = aMessage;
       
   321     
       
   322     TInt trapError( KErrNone );
       
   323     
       
   324     // Check which function is called by the proxy side object.
       
   325     // Function number are located in ncdnodefunctinoids.h file.
       
   326     switch( aFunctionNumber )
       
   327         {
       
   328         case NcdNodeFunctionIds::ENcdInternalize:
       
   329             // Internalize the proxy side according to the data
       
   330             // of this object.
       
   331             TRAP( trapError, InternalizeRequestL( *aMessage ) );
       
   332             break;
       
   333 
       
   334         case NcdNodeFunctionIds::ENcdRelease:
       
   335             // The proxy does not want to use this object anymore.
       
   336             // So, release the handle from the session.
       
   337             ReleaseRequest( *aMessage );
       
   338             break;
       
   339                     
       
   340         default:
       
   341             DLERROR(("Unidentified function request"));
       
   342             DASSERT( EFalse );
       
   343             break;
       
   344         }
       
   345 
       
   346     if ( trapError != KErrNone )
       
   347         {
       
   348         // Because something went wrong, the complete has not been
       
   349         // yet called for the message.
       
   350         // So, inform the client about the error if the
       
   351         // message is still available.
       
   352         aMessage->CompleteAndRelease( trapError );
       
   353         }
       
   354 
       
   355     // Because the message should not be used after this, set it NULL.
       
   356     // So, CounterPartLost function will know that no messages are
       
   357     // waiting the response at the moment.
       
   358     iMessage = NULL;        
       
   359     
       
   360     DLTRACEOUT((""));
       
   361     }
       
   362 
       
   363 void CNcdNodeUpgrade::CounterPartLost( const MCatalogsSession& aSession )
       
   364     {
       
   365     // This function may be called whenever -- when the message is waiting
       
   366     // response or when the message does not exist.
       
   367     // iMessage may be NULL here, because in the end of the
       
   368     // ReceiveMessage it is set to NULL. The life time of the message
       
   369     // ends shortly after CompleteAndRelease is called.
       
   370     if ( iMessage != NULL )
       
   371         {
       
   372         iMessage->CounterPartLost( aSession );
       
   373         }
       
   374     }
       
   375                 
       
   376 
       
   377 void CNcdNodeUpgrade::InternalizeRequestL( MCatalogsBaseMessage& aMessage )
       
   378     {
       
   379     DLTRACEIN((""));
       
   380     
       
   381     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
   382     CleanupStack::PushL( buf );
       
   383     
       
   384     RBufWriteStream stream( *buf );
       
   385     CleanupClosePushL( stream );
       
   386 
       
   387 
       
   388     // Include all the necessary node data to the stream
       
   389     ExternalizeDataForRequestL( stream );     
       
   390     
       
   391     
       
   392     // Commits data to the stream when closing.
       
   393     CleanupStack::PopAndDestroy( &stream );
       
   394 
       
   395 
       
   396     // If this leaves, ReceiveMessage will complete the message.
       
   397     // NOTE: that here we expect that the buffer contains at least
       
   398     // some data. So, make sure that ExternalizeDataForRequestL inserts
       
   399     // something to the buffer.
       
   400     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );        
       
   401         
       
   402     
       
   403     DLTRACE(("Deleting the buf"));
       
   404     CleanupStack::PopAndDestroy( buf );
       
   405         
       
   406     DLTRACEOUT((""));
       
   407     }
       
   408     
       
   409 
       
   410 void CNcdNodeUpgrade::ExternalizeDataForRequestL( RWriteStream& aStream )
       
   411     {
       
   412     DLTRACEIN((""));
       
   413 
       
   414     // Also, check if the interface should be shown even if there is nothing to be
       
   415     // installed.
       
   416     if ( AllUpgradesInstalledL()
       
   417          && !ContentUpgrades() )
       
   418         {
       
   419         DLINFO(("No installable node targets. Leave with KErrNotFound."));
       
   420         User::Leave( KErrNotFound );        
       
   421         }
       
   422 
       
   423     if ( IsObsolete() )
       
   424         {
       
   425         DLINFO(("Set as obsolete. This means that server has removed the object."));
       
   426         User::Leave( KNcdErrorObsolete );
       
   427         }
       
   428     
       
   429     // First insert data that the creator of this class object will use to
       
   430     // create this class object. Class id informs what class object
       
   431     // will be created.
       
   432     
       
   433     aStream.WriteInt32L( iClassId );
       
   434         
       
   435     ExternalizeNodeUpgradeArrayL( aStream );
       
   436 
       
   437     // Also externalize some information about the possible content dependencies for the
       
   438     // proxy
       
   439     ExternalizeContentUpgradeArrayForRequestL( aStream );
       
   440     
       
   441     DASSERT( iUpgradeData );
       
   442     if ( ContentUpgrades() )
       
   443         {
       
   444         aStream.WriteInt8L( 1 );
       
   445         iUpgradeData->ExternalizeL( aStream );                        
       
   446         }
       
   447     else
       
   448         {
       
   449         aStream.WriteInt8L( 0 );
       
   450         }
       
   451     
       
   452     DLTRACEOUT((""));
       
   453     }
       
   454     
       
   455 
       
   456 void CNcdNodeUpgrade::ReleaseRequest( MCatalogsBaseMessage& aMessage ) const
       
   457     {
       
   458     DLTRACEIN((""));
       
   459 
       
   460     // Decrease the reference count for this object.
       
   461     // When the reference count reaches zero, this object will be destroyed
       
   462     // and removed from the session.
       
   463     MCatalogsSession& requestSession( aMessage.Session() );
       
   464     TInt handle( aMessage.Handle() );
       
   465 
       
   466     // Send complete information back to proxy.
       
   467     aMessage.CompleteAndRelease( KErrNone );
       
   468         
       
   469     // Remove this object from the session.
       
   470     requestSession.RemoveObject( handle );
       
   471         
       
   472     DLTRACEOUT((""));
       
   473     }
       
   474 
       
   475 
       
   476 void CNcdNodeUpgrade::ExternalizeNodeUpgradeArrayL( RWriteStream& aStream )
       
   477     {
       
   478     DLTRACEIN((""));
       
   479 
       
   480     aStream.WriteInt32L( iUpgradeNodeTargets.Count() );
       
   481     for ( TInt i = 0; i < iUpgradeNodeTargets.Count(); ++i )
       
   482         {
       
   483         iUpgradeNodeTargets[ i ]->ExternalizeL( aStream );
       
   484         }
       
   485 
       
   486     DLTRACEOUT((""));
       
   487     }
       
   488 
       
   489 void CNcdNodeUpgrade::InternalizeNodeUpgradeArrayL( RReadStream& aStream )
       
   490     {
       
   491     DLTRACEIN((""));
       
   492 
       
   493     CNcdDependencyInfo* upgradeInfo( NULL );
       
   494     TInt count( aStream.ReadInt32L() );
       
   495 
       
   496     iUpgradeNodeTargets.ResetAndDestroy();
       
   497     for( TInt i = 0; i < count; ++i )
       
   498         {
       
   499         upgradeInfo = CNcdDependencyInfo::NewLC( aStream );
       
   500         iUpgradeNodeTargets.AppendL( upgradeInfo );
       
   501         CleanupStack::Pop( upgradeInfo );
       
   502         }
       
   503 
       
   504     DLTRACEOUT((""));
       
   505     }
       
   506 
       
   507 
       
   508 void CNcdNodeUpgrade::ExternalizeContentUpgradeArrayForRequestL( RWriteStream& aStream )
       
   509     {
       
   510     DLTRACEIN((""));
       
   511 
       
   512     aStream.WriteInt32L( iUpgradeContentTargets.Count() );
       
   513     CNcdDownloadInfo* downloadInfo( NULL );
       
   514     CNcdDependencyInfo* upgradeInfo( NULL );
       
   515     // Notice that here we will give dependency info objects to the proxy side.
       
   516     for ( TInt i = 0; i < iUpgradeContentTargets.Count(); ++i )
       
   517         {
       
   518         downloadInfo = iUpgradeContentTargets[ i ];
       
   519         upgradeInfo = CNcdDependencyInfo::NewLC( downloadInfo->ContentName(), 
       
   520                                                  downloadInfo->ContentVersion(), 
       
   521                                                  downloadInfo->ContentId(),
       
   522                                                  NULL );
       
   523         upgradeInfo->ExternalizeL( aStream );
       
   524         CleanupStack::PopAndDestroy( upgradeInfo );
       
   525         upgradeInfo = NULL;
       
   526         }
       
   527 
       
   528     DLTRACEOUT((""));
       
   529     }
       
   530 
       
   531 void CNcdNodeUpgrade::ExternalizeContentUpgradeArrayL( RWriteStream& aStream )
       
   532     {
       
   533     DLTRACEIN((""));
       
   534 
       
   535     aStream.WriteInt32L( iUpgradeContentTargets.Count() );
       
   536     for ( TInt i = 0; i < iUpgradeContentTargets.Count(); ++i )
       
   537         {
       
   538         iUpgradeContentTargets[ i ]->ExternalizeL( aStream );
       
   539         }
       
   540 
       
   541     DLTRACEOUT((""));
       
   542     }
       
   543 
       
   544 void CNcdNodeUpgrade::InternalizeContentUpgradeArrayL( RReadStream& aStream )
       
   545     {
       
   546     DLTRACEIN((""));
       
   547 
       
   548     CNcdDownloadInfo* content( NULL );
       
   549     TInt count( aStream.ReadInt32L() );
       
   550 
       
   551     iUpgradeContentTargets.ResetAndDestroy();
       
   552     for( TInt i = 0; i < count; ++i )
       
   553         {
       
   554         content = CNcdDownloadInfo::NewLC();
       
   555         content->InternalizeL( aStream );
       
   556         iUpgradeContentTargets.AppendL( content );
       
   557         CleanupStack::Pop( content );
       
   558         }
       
   559 
       
   560     DLTRACEOUT((""));
       
   561     }
       
   562 
       
   563