ncdengine/provider/server/src/ncdnodeinstallimpl.cpp
changeset 0 ba25891c3a9e
child 18 3ba40be8e484
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:   Implements CNcdNodeInstall class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdnodeinstallimpl.h"
       
    20 
       
    21 #include <f32file.h>
       
    22 #include <s32mem.h>
       
    23 #include <bautils.h>
       
    24 
       
    25 
       
    26 #include "catalogssession.h"
       
    27 #include "catalogsbasemessage.h"
       
    28 #include "ncdnodefunctionids.h"
       
    29 #include "ncdnodeclassids.h"
       
    30 #include "catalogsconstants.h"
       
    31 #include "ncd_pp_dataentity.h"
       
    32 #include "ncd_cp_query.h"
       
    33 #include "catalogsutils.h"
       
    34 #include "ncdutils.h"
       
    35 #include "ncdpurchaseinstallinfo.h"
       
    36 #include "ncdpurchasedetails.h"
       
    37 #include "ncdpurchasehistorydbimpl.h"
       
    38 #include "ncdinstallinfo.h"
       
    39 #include "ncdfileinfo.h"
       
    40 #include "ncdextendedinstallinfo.h"
       
    41 #include "ncdproviderutils.h"
       
    42 #include "ncdinstallationservice.h"
       
    43 #include "ncdnodemetadataimpl.h"
       
    44 #include "ncdnodecontentinfoimpl.h"
       
    45 #include "ncdpanics.h"
       
    46 #include "ncdpurchasehistoryutils.h"
       
    47 #include "ncdproviderdefines.h"
       
    48 #include "ncdnodecontentinfoimpl.h"
       
    49 #include "ncdnodemanager.h"
       
    50 #include "ncdnodeidentifier.h"
       
    51 
       
    52 #include "catalogsdebug.h"
       
    53 
       
    54 
       
    55 // Maximum number of content file opening attempts if the first
       
    56 // one fails with KErrInUse
       
    57 const TInt KMaxRetries = 3;
       
    58 
       
    59 // Delay between content file opening attempts if the first
       
    60 // one fails with KErrInUse
       
    61 const TInt KOpenDelay = 500000;
       
    62 
       
    63 static TInt CallBackOpenFile( TAny* aObject )
       
    64     {
       
    65     DLTRACEIN((""));
       
    66     static_cast<CNcdNodeInstall*>( aObject )->OpenContentFileRunner();
       
    67     return KErrNone;
       
    68     }
       
    69 
       
    70 // ---------------------------------------------------------------------------
       
    71 // CNcdNodeInstall
       
    72 // ---------------------------------------------------------------------------
       
    73 //  
       
    74 
       
    75 
       
    76 CNcdNodeInstall::CNcdNodeInstall( NcdNodeClassIds::TNcdNodeClassId aClassId,
       
    77     const CNcdNodeMetaData& aMetadata )
       
    78 : CCatalogsCommunicable(),
       
    79   iClassId( aClassId ),
       
    80   iMetadata( aMetadata )
       
    81     {
       
    82     }
       
    83 
       
    84 void CNcdNodeInstall::ConstructL()
       
    85     {
       
    86     DLTRACEIN((""));    
       
    87     iDownloadedFiles = new(ELeave) CDesCArrayFlat( KListGranularity );
       
    88     DLTRACEOUT((""));
       
    89     }
       
    90 
       
    91 
       
    92 CNcdNodeInstall* CNcdNodeInstall::NewL( const CNcdNodeMetaData& aMetadata )
       
    93     {
       
    94     CNcdNodeInstall* self =   
       
    95         CNcdNodeInstall::NewLC( aMetadata );
       
    96     CleanupStack::Pop( self );
       
    97     return self;        
       
    98     }
       
    99 
       
   100 CNcdNodeInstall* CNcdNodeInstall::NewLC( const CNcdNodeMetaData& aMetadata )
       
   101     {
       
   102     CNcdNodeInstall* self = 
       
   103         new( ELeave ) CNcdNodeInstall( 
       
   104             NcdNodeClassIds::ENcdNodeInstallClassId, aMetadata );
       
   105     CleanupClosePushL( *self );
       
   106     self->ConstructL();
       
   107     return self;        
       
   108     }
       
   109 
       
   110 
       
   111 CNcdNodeInstall::~CNcdNodeInstall()
       
   112     {
       
   113     DLTRACEIN((""));
       
   114 
       
   115     // Delete member variables here
       
   116     iInstallInfos.ResetAndDestroy();
       
   117     delete iDownloadedFiles;
       
   118     
       
   119     delete iInstalledContent;
       
   120     delete iPeriodic;
       
   121 
       
   122     DLTRACEOUT((""));
       
   123     }        
       
   124 
       
   125 NcdNodeClassIds::TNcdNodeClassId CNcdNodeInstall::ClassId() const
       
   126     {
       
   127     return iClassId;
       
   128     }
       
   129 
       
   130 
       
   131 
       
   132 
       
   133 // ---------------------------------------------------------------------------
       
   134 // Set node data from purchase details
       
   135 // ---------------------------------------------------------------------------
       
   136 //  
       
   137 TBool CNcdNodeInstall::InternalizeL( const MNcdPurchaseDetails& aDetails )
       
   138     {
       
   139     DLTRACEIN(("this-ptr: %X", this));
       
   140 
       
   141     if ( !aDetails.DownloadInfoL().Count() ) 
       
   142         {
       
   143         DLTRACEOUT(("No downloadinfos so there's nothing to install"));
       
   144         return EFalse;
       
   145         }
       
   146 
       
   147     DLTRACE(("Copying paths of downloaded files"));
       
   148     
       
   149     CDesCArray* tempDownloads = new(ELeave) CDesCArrayFlat( KListGranularity );
       
   150     CleanupStack::PushL( tempDownloads );
       
   151     
       
   152     TBool atLeastOneFile = EFalse;
       
   153     // Get names of downloaded files
       
   154     for ( TInt i = 0; i < aDetails.DownloadedFiles().MdcaCount(); ++i ) 
       
   155         {
       
   156         const TDesC& filepath( aDetails.DownloadedFiles().MdcaPoint( i ) );
       
   157         atLeastOneFile = atLeastOneFile || filepath.Length();
       
   158             
       
   159         // append even empty descriptors so that the arrays stay identical
       
   160         tempDownloads->AppendL( filepath );
       
   161         
       
   162         DLINFO(( _L("Downloaded: %S"), 
       
   163             &aDetails.DownloadedFiles().MdcaPoint( i ) ));
       
   164         }
       
   165 
       
   166     TArray<MNcdPurchaseInstallInfo*> info ( aDetails.InstallInfoL() );
       
   167         
       
   168     // Check download status
       
   169     if ( !atLeastOneFile && !info.Count() ) 
       
   170         {
       
   171         CleanupStack::PopAndDestroy( tempDownloads );
       
   172         DLINFO(("Nothing has been downloaded or installed"));
       
   173         return EFalse;
       
   174         }
       
   175            
       
   176     TArray<MNcdPurchaseDownloadInfo*> dlInfo ( aDetails.DownloadInfoL() );               
       
   177     
       
   178 
       
   179     DLTRACE(("Internalizing install infos, count: %d", info.Count() ));
       
   180 
       
   181     RPointerArray<CNcdExtendedInstallInfo> tempInfos;
       
   182     CleanupResetAndDestroyPushL( tempInfos );
       
   183     
       
   184     tempInfos.ReserveL( info.Count() );
       
   185     iLaunchable = EFalse;        
       
   186     
       
   187     CNcdExtendedInstallInfo* tempInstall = NULL;
       
   188     TBool launchable = EFalse;
       
   189     
       
   190     TBool atLeastOneLauncher = EFalse;
       
   191     TBool atLeastOneLaunchableLauncher = EFalse;
       
   192     TBool atLeastOneLauncherOpen = EFalse;
       
   193     
       
   194     // If there are more install infos than download infos we assume that
       
   195     // the first install infos are for rights files
       
   196     TInt dlIndex = dlInfo.Count() - info.Count();
       
   197     if ( dlIndex > 0 ) 
       
   198         {
       
   199         dlIndex = 0;
       
   200         }
       
   201     
       
   202     // Internalize infos
       
   203     for ( TInt i = 0; i < info.Count(); ++i, ++dlIndex )
       
   204         {
       
   205         const MNcdPurchaseInstallInfo& install( *info[i] );
       
   206         
       
   207         if ( dlIndex >= 0 ) 
       
   208             {            
       
   209             const MNcdPurchaseDownloadInfo& download( *dlInfo[dlIndex] );
       
   210             
       
   211             launchable = download.IsLaunchable();
       
   212             DLTRACE(("Launchable from purchase history: %d", launchable ));
       
   213             
       
   214             TBool isLauncher = IsOneOf( download.ContentUsage(), 
       
   215                        MNcdPurchaseDownloadInfo::ELauncher,
       
   216                        MNcdPurchaseDownloadInfo::ELauncherOpen );
       
   217             
       
   218             // Themes are not launchable. This also checks for reinstalled themes            
       
   219             if ( install.ThemeName() != KNullDesC || 
       
   220                  ( install.ThemeName() == KNullDesC &&
       
   221                    install.ApplicationUid() == TUid::Null() &&
       
   222                    install.Filename() == KNullDesC ) )
       
   223                 {
       
   224                 launchable = EFalse;
       
   225                 }
       
   226             // check launcher apps
       
   227             else if ( isLauncher )
       
   228                 {
       
   229                 atLeastOneLauncher = ETrue;
       
   230                 // Can't use IsContentInstalledL since it uses iInstallInfos-array
       
   231                 // which is generated here
       
   232                 if ( CNcdProviderUtils::IsApplicationInstalledL(
       
   233                         install.ApplicationUid(), 
       
   234                         install.ApplicationVersion() ) <= ENcdApplicationNotInstalled  )
       
   235                     {
       
   236                     DLTRACE(("Setting launchable=EFalse"));
       
   237                     launchable = EFalse;            
       
   238                     }
       
   239                 else 
       
   240                     {
       
   241                     atLeastOneLaunchableLauncher = ETrue;
       
   242                     }
       
   243                }
       
   244              
       
   245             
       
   246             tempInstall = CNcdExtendedInstallInfo::NewLC( install,
       
   247                 download.ContentMimeType(), launchable );
       
   248 
       
   249             tempInstall->SetUriExists( download.ContentUri().Length() != 0 );
       
   250             // Sets content type to tempInstall according to download's contentUsage
       
   251             SetContentType( *tempInstall, download );
       
   252             
       
   253             
       
   254             if ( download.ContentUsage() == 
       
   255                     MNcdPurchaseDownloadInfo::ELauncherOpen ) 
       
   256                 {                
       
   257                 atLeastOneLauncherOpen = ETrue;
       
   258                 }
       
   259              
       
   260             // Set item as launchable if at least one file is launchable    
       
   261             if ( launchable ) 
       
   262                 {
       
   263                 iLaunchable = ETrue;
       
   264                 }
       
   265             }
       
   266         else 
       
   267             {
       
   268             DLTRACE(("Rights file"));
       
   269             tempInstall = CNcdExtendedInstallInfo::NewLC( install,
       
   270                 KNullDesC, ETrue );
       
   271             }        
       
   272         
       
   273         tempInfos.AppendL( tempInstall );
       
   274         CleanupStack::Pop( tempInstall );
       
   275         tempInstall = NULL;        
       
   276             
       
   277         DLTRACE(("Info added, iInstallInfo count: %d", iInstallInfos.Count() ));
       
   278         }
       
   279     
       
   280     if ( atLeastOneLauncher && !atLeastOneLaunchableLauncher )
       
   281         {
       
   282         DLTRACE(("No launchable launchers, setting everything unlaunchable"));
       
   283         iLaunchable = EFalse;
       
   284         TInt count = tempInfos.Count();
       
   285         while ( count-- ) 
       
   286             {
       
   287             tempInfos[ count ]->SetLaunchable( EFalse );
       
   288             }
       
   289         }
       
   290 
       
   291     // There was at least one launcher/open dependency so we need to go through
       
   292     // the install infos and try to find a suitable file for opening
       
   293     if ( atLeastOneLauncherOpen && 
       
   294          tempInfos.Count() <= dlInfo.Count() ) 
       
   295         {
       
   296         DLTRACE(("Setting launcher param"));
       
   297         TInt count = tempInfos.Count();
       
   298         
       
   299         for ( TInt i = 0; i < count; ++i )
       
   300             {
       
   301             const MNcdPurchaseDownloadInfo& download( *dlInfo[ i ] );
       
   302             if ( download.ContentUsage() == MNcdPurchaseDownloadInfo::ELauncherOpen ) 
       
   303                 {
       
   304                 SetLaunchParameterL( tempInfos, i );
       
   305                 }            
       
   306             }
       
   307         }
       
   308         
       
   309     DLTRACE(("Replacing old values with new ones"));
       
   310 
       
   311 
       
   312     // Read installed status
       
   313     iInstalled = ( aDetails.State() == MNcdPurchaseDetails::EStateInstalled );
       
   314         
       
   315     DLINFO(( "Installed: %d", iInstalled ));
       
   316     
       
   317     // Get purpose
       
   318     iPurpose = aDetails.ItemPurpose();
       
   319     DLINFO(( "Purpose: %d", iPurpose ));        
       
   320     
       
   321     // Replace old values
       
   322     iInstallInfos.ResetAndDestroy();    
       
   323     iInstallInfos = tempInfos;
       
   324     CleanupStack::Pop( &tempInfos );
       
   325     
       
   326     
       
   327     delete iDownloadedFiles;
       
   328     iDownloadedFiles = tempDownloads;
       
   329     CleanupStack::Pop( tempDownloads );
       
   330     
       
   331     TInt depCount = DependencyCount( dlInfo );
       
   332 
       
   333     if ( !iInstalled && 
       
   334          depCount &&
       
   335          // must be more download infos than just deps
       
   336          dlInfo.Count() > depCount &&
       
   337          // install info count must be at least the amount of dlInfos 
       
   338          // since deps have equal number of install and dl infos and
       
   339          // all content must have been installed before
       
   340          info.Count() >= dlInfo.Count() )
       
   341         {
       
   342         iInstalled = ETrue;
       
   343         DLTRACE(("Dependency has already been installed, setting iInstalled to ETrue"));
       
   344         }
       
   345 
       
   346     
       
   347     if ( iInstalledContent ) 
       
   348         {
       
   349         DASSERT( iInstalledContent->ApplicationUid() != TUid::Null() );
       
   350         
       
   351         // Disable launching if protocol says so. 
       
   352         // By default apps defined in content info are launchable
       
   353         iInstalledContent->SetLaunchable( iLaunchable );
       
   354         
       
   355         // Delete iInstalledContent if it is duplicated in purchase history
       
   356         for ( TInt i = 0; i < iInstallInfos.Count(); ++i ) 
       
   357             {
       
   358             
       
   359             if ( iInstalledContent->ApplicationUid() == 
       
   360                  iInstallInfos[i]->ApplicationUid() )
       
   361                 {
       
   362                 DLTRACE(("App has been bought and installed"));
       
   363                 delete iInstalledContent;
       
   364                 iInstalledContent = NULL;
       
   365                 break;
       
   366                 }
       
   367             }        
       
   368         }
       
   369     
       
   370     SetContentVersionL( aDetails.Version() );
       
   371     DLTRACEOUT(("iLaunchable: %d", iLaunchable));
       
   372     return ETrue;
       
   373     }
       
   374 
       
   375 
       
   376 void CNcdNodeInstall::ReceiveMessage( MCatalogsBaseMessage* aMessage,
       
   377                                       TInt aFunctionNumber )
       
   378     {
       
   379     DLTRACEIN(("this-ptr: %X", this));    
       
   380 
       
   381     DASSERT( aMessage );
       
   382 
       
   383     // Now, we can be sure that rest of the time iMessage exists.
       
   384     // This member variable is set for the CounterPartLost function.
       
   385     iMessage = aMessage;
       
   386     
       
   387     TInt trapError( KErrNone );
       
   388     
       
   389     // Check which function is called by the proxy side object.
       
   390     // Function number are located in ncdnodefunctinoids.h file.
       
   391     switch( aFunctionNumber )
       
   392         {
       
   393         case NcdNodeFunctionIds::ENcdInternalize:
       
   394             // Internalize the proxy side according to the data
       
   395             // of this object.
       
   396             TRAP( trapError, InternalizeRequestL( *aMessage ) );
       
   397             break;
       
   398 
       
   399         case NcdNodeFunctionIds::ENcdRelease:
       
   400             // The proxy does not want to use this object anymore.
       
   401             // So, release the handle from the session.
       
   402             ReleaseRequest( *aMessage );
       
   403             break;
       
   404             
       
   405         case NcdNodeFunctionIds::ENcdInstallOpenFile:
       
   406             TRAP( trapError, OpenContentFileL( *aMessage ) );
       
   407             break;
       
   408 
       
   409         case NcdNodeFunctionIds::ENcdSetApplicationInstalled:
       
   410             TRAP( trapError, SetApplicationInstalledRequestL( *aMessage ) );
       
   411             break;
       
   412                     
       
   413         default:
       
   414             DLERROR(("Unidentified function request"));
       
   415             DASSERT( EFalse );
       
   416             break;
       
   417         }
       
   418 
       
   419     if ( trapError != KErrNone )
       
   420         {
       
   421         // Because something went wrong, the complete has not been
       
   422         // yet called for the message.
       
   423         // So, inform the client about the error if the
       
   424         // message is still available.
       
   425         aMessage->CompleteAndRelease( trapError );
       
   426         }
       
   427 
       
   428     // Because the message should not be used after this, set it NULL.
       
   429     // So, CounterPartLost function will know that no messages are
       
   430     // waiting the response at the moment.
       
   431     if ( !iPeriodic ) 
       
   432         {        
       
   433         iMessage = NULL;        
       
   434         }
       
   435     
       
   436     DLTRACEOUT((""));
       
   437     }
       
   438 
       
   439 
       
   440 void CNcdNodeInstall::CounterPartLost( const MCatalogsSession& aSession )
       
   441     {
       
   442     // This function may be called whenever -- when the message is waiting
       
   443     // response or when the message does not exist.
       
   444     // iMessage may be NULL here, because in the end of the
       
   445     // ReceiveMessage it is set to NULL. The life time of the message
       
   446     // ends shortly after CompleteAndRelease is called.
       
   447     if ( iMessage != NULL )
       
   448         {
       
   449         iMessage->CounterPartLost( aSession );
       
   450         }
       
   451     }
       
   452                 
       
   453 
       
   454 
       
   455 const MDesCArray& CNcdNodeInstall::DownloadedFiles() const
       
   456     {
       
   457     DASSERT( iDownloadedFiles );
       
   458     return *iDownloadedFiles;
       
   459     }
       
   460                 
       
   461 
       
   462 TNcdApplicationStatus CNcdNodeInstall::IsContentInstalledL( 
       
   463     TInt aIndex,
       
   464     TBool aIgnoreMissingUri )
       
   465     {
       
   466     DLTRACEIN(("aIndex: %d", aIndex));
       
   467     DASSERT( aIndex >= 0 );
       
   468 
       
   469     if ( aIndex >= ContentCount() ) 
       
   470         {
       
   471         DLTRACEOUT(("Index out of range (count = %d), returning EFalse", 
       
   472             ContentCount() ));
       
   473         return ENcdApplicationNotInstalled;
       
   474         }
       
   475 
       
   476     CNcdExtendedInstallInfo& info = *iInstallInfos[aIndex];
       
   477             
       
   478     TNcdApplicationStatus status = ENcdApplicationNotInstalled;
       
   479     
       
   480     if ( info.Filename() != KNullDesC ) 
       
   481         {
       
   482         DLTRACE(("Content: file"));
       
   483         if ( BaflUtils::FileExists( 
       
   484                 CNcdProviderUtils::FileSession(),
       
   485                 info.Filename() ) ) 
       
   486             {
       
   487             DLTRACE(( _L("File %S exists"), &info.Filename() ));
       
   488             status = ENcdApplicationInstalled;
       
   489             }
       
   490         }
       
   491     else if ( info.ApplicationUid() != TUid::Null() )
       
   492         {
       
   493         DLTRACE(("Content: application"));
       
   494         if ( aIgnoreMissingUri && !info.UriExists() ) 
       
   495             {
       
   496             DLTRACE(("No uri and ignoring missing uris"));
       
   497             status = ENcdApplicationInstalled;
       
   498             }
       
   499         else 
       
   500             {            
       
   501             status = CNcdProviderUtils::IsApplicationInstalledL(
       
   502                 info.ApplicationUid(), 
       
   503                 info.ApplicationVersion() );            
       
   504             }
       
   505         }
       
   506     else if ( info.ThemeName() != KNullDesC )
       
   507         {
       
   508         DLTRACE(("Content: theme"));
       
   509         if ( CNcdProviderUtils::InstallationServiceL().IsThemeInstalledL(
       
   510             info.ThemeName() ) )
       
   511             {
       
   512             status = ENcdApplicationInstalled;
       
   513             }
       
   514         }
       
   515     info.SetInstalledStatus( status );
       
   516     
       
   517     return status;
       
   518     }
       
   519 
       
   520 
       
   521 TInt CNcdNodeInstall::ContentCount() const
       
   522     {
       
   523     return iInstallInfos.Count();
       
   524     }
       
   525 
       
   526     
       
   527 TBool CNcdNodeInstall::IsAllContentInstalledL()
       
   528     {
       
   529     DLTRACEIN((""));
       
   530         
       
   531     for ( TInt i = 0; i < iInstallInfos.Count(); ++i ) 
       
   532         {        
       
   533         // Don't care whether older or newer version is installed as long as
       
   534         // some version is installed, ignores application that don't have content URIs
       
   535 
       
   536         if ( IsContentInstalledL( i, ETrue ) == ENcdApplicationNotInstalled ) 
       
   537             {
       
   538             return EFalse;
       
   539             }
       
   540         }
       
   541     DLTRACEOUT(("All installed"));
       
   542     return ETrue;
       
   543     }
       
   544 
       
   545 
       
   546 // ---------------------------------------------------------------------------
       
   547 // 
       
   548 // ---------------------------------------------------------------------------
       
   549 //  
       
   550 TBool CNcdNodeInstall::InternalizeContentInfoL()
       
   551     {
       
   552     DLTRACEIN((""));
       
   553     
       
   554     if ( iInstallInfos.Count() ) 
       
   555         {
       
   556         DLTRACEOUT(("Already installed something"));
       
   557         return EFalse;
       
   558         }
       
   559     
       
   560     const CNcdNodeContentInfo* info = NULL;
       
   561     TRAPD( err, info = &iMetadata.ContentInfoL() );
       
   562     
       
   563     TBool installed = EFalse;
       
   564     if ( err == KErrNone && info->Uid() != TUid::Null() ) 
       
   565         {
       
   566         DLINFO(("Uid: %x", info->Uid().iUid ));
       
   567         TNcdApplicationStatus status = 
       
   568             CNcdProviderUtils::IsApplicationInstalledL(
       
   569                 info->Uid(), 
       
   570                 info->Version() );
       
   571         
       
   572         // Application can be older version for it to be considered installed
       
   573         // Upgrade will be available for the user
       
   574         installed = status != ENcdApplicationNotInstalled;
       
   575 
       
   576         delete iInstalledContent;
       
   577         iInstalledContent = NULL;
       
   578 
       
   579         iInstalled = installed;    
       
   580         iLaunchable = installed;
       
   581                             
       
   582         if ( installed ) 
       
   583             {
       
   584             DLTRACE(("Application installed"));
       
   585             CNcdExtendedInstallInfo* install = CNcdExtendedInstallInfo::NewLC();
       
   586             install->SetApplicationUid( info->Uid() );
       
   587             
       
   588             // This ensures that CNcdInstalledApplication actually checks the 
       
   589             // application's version number when it checks if it's installed
       
   590             // or not
       
   591             install->SetUriExists( ETrue );
       
   592 
       
   593             // This will be used to determine whether the app is actually installed
       
   594             // or not
       
   595             install->SetApplicationVersionL( info->Version() );
       
   596             install->SetLaunchable( ETrue );
       
   597             
       
   598             // don't set because it can mess upgrade handling in 
       
   599             // CNcdNodeMetadata::HandleContentUpgradeL
       
   600             iContentVersion = TCatalogsVersion();
       
   601 
       
   602             iInstalledContent = install;
       
   603             CleanupStack::Pop( install );
       
   604             }
       
   605         }
       
   606     return installed;
       
   607     }
       
   608 
       
   609 
       
   610 // ---------------------------------------------------------------------------
       
   611 // Content version getter
       
   612 // ---------------------------------------------------------------------------
       
   613 //  
       
   614 const TCatalogsVersion& CNcdNodeInstall::ContentVersion() const
       
   615     {
       
   616     return iContentVersion;
       
   617     }
       
   618 
       
   619     
       
   620 
       
   621 void CNcdNodeInstall::InternalizeRequestL( MCatalogsBaseMessage& aMessage )
       
   622     {
       
   623     DLTRACEIN((""));
       
   624     
       
   625     CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
       
   626     CleanupStack::PushL( buf );
       
   627     
       
   628     RBufWriteStream stream( *buf );
       
   629     CleanupClosePushL( stream );
       
   630 
       
   631 
       
   632     // Include all the necessary node data to the stream
       
   633     ExternalizeDataForRequestL( stream );     
       
   634     
       
   635     
       
   636     // Commits data to the stream when closing.
       
   637     CleanupStack::PopAndDestroy( &stream );
       
   638 
       
   639 
       
   640     // If this leaves, ReceiveMessage will complete the message.
       
   641     // NOTE: that here we expect that the buffer contains at least
       
   642     // some data. So, make sure that ExternalizeDataForRequestL inserts
       
   643     // something to the buffer.
       
   644     aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone );        
       
   645         
       
   646     
       
   647     DLTRACE(("Deleting the buf"));
       
   648     CleanupStack::PopAndDestroy( buf );
       
   649         
       
   650     DLTRACEOUT((""));
       
   651     }
       
   652     
       
   653 
       
   654 void CNcdNodeInstall::ExternalizeDataForRequestL( RWriteStream& aStream )
       
   655     {
       
   656     DLTRACEIN(("this-ptr: %X", this));
       
   657 
       
   658     // Install existed. So, insert info that meta data was found.
       
   659     aStream.WriteInt32L( ClassId() );
       
   660 
       
   661     // Add additional content to the stream.
       
   662     // Make sure that this matches to the order that is used in the proxy
       
   663     // side when this stream is internalized.
       
   664     // NOTE: Be careful with the 8- and 16-bit descriptors. Remember to check
       
   665     // if the proxy wants the data in 16 or 8 bits?    
       
   666 
       
   667     aStream.WriteInt32L( iPurpose );
       
   668 
       
   669     aStream.WriteInt32L( iInstalled );
       
   670     
       
   671     aStream.WriteInt32L( iLaunchable );
       
   672     
       
   673     TInt count = iInstallInfos.Count();
       
   674     
       
   675     if ( iInstalledContent ) 
       
   676         {
       
   677         DLTRACE(("App from content info is installed, adding install info"));        
       
   678         aStream.WriteInt32L( count + 1 );    
       
   679         iInstalledContent->ExternalizeL( aStream );
       
   680         }
       
   681     else
       
   682         {
       
   683         aStream.WriteInt32L( count );
       
   684         }
       
   685         
       
   686     DLTRACE(("Externalizing infos, count: %d", count ));
       
   687         
       
   688     for ( TInt i = 0; i < count; ++i )
       
   689         {
       
   690         iInstallInfos[i]->ExternalizeL( aStream );        
       
   691         }  
       
   692 
       
   693     DLTRACEOUT((""));
       
   694     }
       
   695     
       
   696 
       
   697 // ---------------------------------------------------------------------------
       
   698 // Handle release requests
       
   699 // ---------------------------------------------------------------------------
       
   700 //  
       
   701 void CNcdNodeInstall::ReleaseRequest( MCatalogsBaseMessage& aMessage ) const
       
   702     {
       
   703     DLTRACEIN((""));
       
   704 
       
   705     // Decrease the reference count for this object.
       
   706     // When the reference count reaches zero, this object will be destroyed
       
   707     // and removed from the session.
       
   708     MCatalogsSession& requestSession( aMessage.Session() );
       
   709     TInt handle( aMessage.Handle() );
       
   710 
       
   711     // Send complete information back to proxy.
       
   712     aMessage.CompleteAndRelease( KErrNone );
       
   713         
       
   714     // Remove this object from the session.
       
   715     requestSession.RemoveObject( handle );
       
   716         
       
   717     DLTRACEOUT((""));
       
   718     }
       
   719 
       
   720 
       
   721 // ---------------------------------------------------------------------------
       
   722 // Opens a content file
       
   723 // ---------------------------------------------------------------------------
       
   724 //  
       
   725 void CNcdNodeInstall::OpenContentFileL( MCatalogsBaseMessage& aMessage )
       
   726     {
       
   727     DLTRACEIN((""));
       
   728     RBuf8 buf;
       
   729     buf.CreateL( aMessage.InputLength() );
       
   730     CleanupClosePushL( buf );
       
   731     User::LeaveIfError( aMessage.ReadInput( buf ) );
       
   732     
       
   733     // Read the requested file index    
       
   734     TInt fileIndex = Des8ToInt( buf );
       
   735     if ( fileIndex < 0 || fileIndex >= iInstallInfos.Count() ) 
       
   736         {
       
   737         DLERROR(( "Index: %d out of range 0-%d", 
       
   738             fileIndex, iInstallInfos.Count() ));
       
   739         User::Leave( KErrArgument );
       
   740         }
       
   741         
       
   742     DLTRACE(( _L("Opening file %S from index: %d"), 
       
   743         &iInstallInfos[fileIndex]->Filename(), fileIndex ));
       
   744     
       
   745     iRetryCount = 0;
       
   746     iFileIndex = fileIndex;        
       
   747     
       
   748     // Try to open the file
       
   749     TRAPD( err, OpenContentFileL() );
       
   750     
       
   751     // N-series hackfix: if the file is in use, 
       
   752     // retry opening it about 0.5 seconds later
       
   753     if ( err == KErrInUse ) 
       
   754         {
       
   755         DLTRACE(("File in use, retry a little bit later"));
       
   756         if ( iPeriodic ) 
       
   757             {
       
   758             iPeriodic->Cancel();
       
   759             }
       
   760         else
       
   761             {            
       
   762             iPeriodic = CPeriodic::NewL( 0 );
       
   763             }
       
   764         TTimeIntervalMicroSeconds32 delay( KOpenDelay );
       
   765         iPeriodic->Start( delay, delay, TCallBack( CallBackOpenFile, this ) );
       
   766         }
       
   767     else
       
   768         {
       
   769         User::LeaveIfError( err );
       
   770         }
       
   771     
       
   772     CleanupStack::PopAndDestroy( &buf ); // buf    
       
   773     DLTRACEOUT((""));
       
   774     }
       
   775 
       
   776 
       
   777 void CNcdNodeInstall::SetApplicationInstalledRequestL( MCatalogsBaseMessage& aMessage )
       
   778     {
       
   779     DLTRACEIN((""));
       
   780 
       
   781     // Note! 
       
   782     // This function is only meant for the proxy side usage and for
       
   783     // certain specific exception cases. Also, this will only allow 
       
   784     // application info updates. For example, themes are not handled here.
       
   785 
       
   786 
       
   787     // Get the data that was sent from the proxy side.
       
   788     HBufC8* input = HBufC8::NewLC( aMessage.InputLength() );
       
   789     TPtr8 inputPtr = input->Des();
       
   790     aMessage.ReadInput( inputPtr );
       
   791     RDesReadStream inputStream( *input );
       
   792     CleanupClosePushL( inputStream );
       
   793 
       
   794     TInt errorCode( inputStream.ReadInt32L() );
       
   795     DLINFO(( "Error code from message: %d", errorCode ));
       
   796 
       
   797     CleanupStack::PopAndDestroy( &inputStream );
       
   798     CleanupStack::PopAndDestroy( input );    
       
   799     
       
   800     
       
   801     CNcdPurchaseHistoryDb& purchaseHistoryDb( 
       
   802         iMetadata.NodeManager().PurchaseHistory() );
       
   803 
       
   804     CNcdPurchaseDetails* details( 
       
   805         NcdPurchaseHistoryUtils::PurchaseDetailsLC(
       
   806             purchaseHistoryDb,
       
   807             iMetadata.Identifier().ClientUid(),
       
   808             iMetadata.Identifier(),
       
   809             EFalse ) );
       
   810 
       
   811     if ( details == NULL )
       
   812         {
       
   813         // Because contents have already been downloaded, there should always
       
   814         // be some details available. Because content has been installed, we
       
   815         // suppose that the content is already downloaded also.
       
   816         User::Leave( KErrNotFound );
       
   817         }
       
   818     else
       
   819         {
       
   820         // We got the newest details.
       
   821         if ( errorCode == KErrNone )
       
   822             {
       
   823             if ( details->State() != MNcdPurchaseDetails::EStateInstalled )
       
   824                 {
       
   825                 DLINFO(("Content not installed yet"));
       
   826                 // Update the fileinfo only if the state is not already installed.
       
   827                 // If the state is installed, then the fileinfo is already
       
   828                 // up-to-date.
       
   829                 const CNcdNodeContentInfo& contentInfo(
       
   830                     iMetadata.ContentInfoL() );
       
   831                 if ( ( contentInfo.Purpose() 
       
   832                        & ENcdItemPurposeTheme ) != 0 )
       
   833                     {
       
   834                     DLINFO(("Content purpose is theme. Not allowed."));
       
   835                     // A minor sanity check because themes may have an UID given.
       
   836                     // So, if the metadata suggests that the content is theme,
       
   837                     // then leave here. Otherwise, trust the user.
       
   838                     User::Leave( KErrAbort );
       
   839                     }
       
   840                 TUid contentUid( contentInfo.Uid() );
       
   841                 const TDesC& version( contentInfo.Version() );
       
   842                 // The item state is installed when installed info count
       
   843                 // corresponds the download info count
       
   844                 TInt installCount( details->InstallInfoCount() );
       
   845                 TInt downloadCount( details->DownloadInfoCount() );
       
   846                 for ( TInt i = installCount; i < downloadCount; ++i )
       
   847                     {
       
   848                     // Set missing install infos.
       
   849                     // Notice, that we only know the main content UID and version.
       
   850                     // So, if the content is a bundle, then we need to fake
       
   851                     // the UIDs and version here and just use the one that 
       
   852                     // metadata content info can provide us.
       
   853                     CNcdPurchaseInstallInfo* installInfo(
       
   854                         CNcdPurchaseInstallInfo::NewLC() );
       
   855                     installInfo->SetApplicationUid( contentUid );
       
   856                     installInfo->SetApplicationVersionL( version );
       
   857                     // Insert new details in the end of the array.
       
   858                     details->InsertInstallInfoL( installInfo, 
       
   859                                                  details->InstallInfoCount() );
       
   860                     CleanupStack::Pop( installInfo );
       
   861                     }
       
   862                 }
       
   863 
       
   864             // Because error code was KErrNone, the content is thought as
       
   865             // successfully installed. So, delete unnecessary installation
       
   866             // files. Notice, that there may be installation files available
       
   867             // even if the details state is EStateInstalled because download
       
   868             // could also  be done again even though installation has been 
       
   869             // successfull already during the first time. 
       
   870             // Get details file information.
       
   871             const MDesCArray& files = details->DownloadedFiles();
       
   872             for( TInt i = 0; i < files.MdcaCount(); ++i )
       
   873                 {
       
   874                 const TDesC& filePath( files.MdcaPoint( i ) );
       
   875                 DLINFO((_L("Delete file: %S"), &filePath));
       
   876                 // Notice, that we need to do the deletion here in the server side.
       
   877                 // The installation files may exist in the NCD Engine server
       
   878                 // private directory and that directory is normally
       
   879                 // accessable only by the NCD Engine server side.
       
   880                 TInt deleteError( 
       
   881                     CNcdProviderUtils::InstallationServiceL().
       
   882                         DeleteFile( filePath ) );
       
   883                 DLINFO(( "Files: %d, delete error: %d", i, deleteError ));
       
   884                 }            
       
   885             }
       
   886 
       
   887         // Set the error code and the lates operation time
       
   888         details->SetLastOperationErrorCode( errorCode );
       
   889         details->SetLastUniversalOperationTime();
       
   890             
       
   891         // Save purhcase details into the purchase history.
       
   892         // This will replace the old detail.
       
   893         // But, do not replace old icon, because we did not load it
       
   894         // for the details above.
       
   895         purchaseHistoryDb.SavePurchaseL( *details, EFalse );
       
   896         
       
   897         CleanupStack::PopAndDestroy( details );
       
   898         details = NULL;
       
   899         }
       
   900 
       
   901     // Complete the message because everything went ok. 
       
   902     // If some operations above left, then ReceiveMessage will handle
       
   903     // those cases.
       
   904     aMessage.CompleteAndRelease( KErrNone );
       
   905     }
       
   906 
       
   907 // ---------------------------------------------------------------------------
       
   908 // Opens a content file, called by CallbackOpenFile
       
   909 // ---------------------------------------------------------------------------
       
   910 //  
       
   911 void CNcdNodeInstall::OpenContentFileRunner()
       
   912     {
       
   913     DLTRACEIN((""));
       
   914     TRAPD( err, OpenContentFileL() );
       
   915     iRetryCount++;
       
   916     if ( err != KErrInUse || iRetryCount >= KMaxRetries ) 
       
   917         {
       
   918         DASSERT( iPeriodic ) 
       
   919         DLTRACE(("Deleting periodic timer"));
       
   920         delete iPeriodic;
       
   921         iPeriodic = NULL;
       
   922 
       
   923         if ( err != KErrNone )
       
   924             {
       
   925             DLTRACE(("Handling other errors"));
       
   926             iMessage->CompleteAndRelease( err );
       
   927             iMessage = NULL;
       
   928             }
       
   929         
       
   930         }
       
   931     }
       
   932 
       
   933 // ---------------------------------------------------------------------------
       
   934 // Opens a content file
       
   935 // ---------------------------------------------------------------------------
       
   936 //  
       
   937 void CNcdNodeInstall::OpenContentFileL()
       
   938     {
       
   939     DLTRACEIN((""));
       
   940     RFs fs;
       
   941     User::LeaveIfError( fs.Connect() );
       
   942     CleanupClosePushL( fs );
       
   943     
       
   944     DLTRACE(("Sharing the file server"));
       
   945     User::LeaveIfError( fs.ShareProtected() );
       
   946     
       
   947     DLTRACE(("Trying to open the file"));
       
   948     RFile file;
       
   949     CleanupClosePushL( file );
       
   950     User::LeaveIfError( file.Open( fs, 
       
   951         iInstallInfos[iFileIndex]->Filename(),
       
   952         NcdProviderDefines::KNcdSharableFileOpenFlags ) );
       
   953         
       
   954         
       
   955     DLTRACE(("File open, transferring to client"));
       
   956     DASSERT( iMessage );
       
   957     iMessage->CompleteAndReleaseL( fs, file );
       
   958     iMessage = NULL;
       
   959     DLTRACE(("File transferred"));
       
   960     CleanupStack::PopAndDestroy( 2, &fs ); // file, fs    
       
   961     }
       
   962 
       
   963 
       
   964 // ---------------------------------------------------------------------------
       
   965 // Calculate the number of dependencies
       
   966 // ---------------------------------------------------------------------------
       
   967 //  
       
   968 TInt CNcdNodeInstall::DependencyCount( 
       
   969     const TArray<MNcdPurchaseDownloadInfo*>& aInfos ) const
       
   970     {
       
   971     DLTRACEIN((""));
       
   972     TInt depCount = 0;
       
   973     for ( TInt i = 0; i < aInfos.Count(); ++i )    
       
   974         {
       
   975         if ( NcdPurchaseHistoryUtils::IsDependency( *aInfos[i] ) )
       
   976             {
       
   977             depCount++;
       
   978             }
       
   979         }
       
   980     return depCount;
       
   981     }
       
   982 
       
   983 
       
   984 // ---------------------------------------------------------------------------
       
   985 // 
       
   986 // ---------------------------------------------------------------------------
       
   987 //  
       
   988 void CNcdNodeInstall::SetContentType( 
       
   989     CNcdExtendedInstallInfo& aInstall,
       
   990     const MNcdPurchaseDownloadInfo& aDownload ) const
       
   991     {
       
   992     DLTRACEIN((""));
       
   993     switch( aDownload.ContentUsage() ) 
       
   994         {
       
   995         case MNcdPurchaseDownloadInfo::EDownloadable:
       
   996             {
       
   997             aInstall.SetContentType( MNcdInstalledContent::EInstalledContent );
       
   998             break;
       
   999             }
       
  1000 
       
  1001         case MNcdPurchaseDownloadInfo::EDependency:
       
  1002             {
       
  1003             aInstall.SetContentType( MNcdInstalledContent::EInstalledDependency );
       
  1004             break;
       
  1005             }
       
  1006         
       
  1007         case MNcdPurchaseDownloadInfo::ELauncher:  // flowthrough      
       
  1008         case MNcdPurchaseDownloadInfo::ELauncherOpen:
       
  1009             {
       
  1010             aInstall.SetContentType( MNcdInstalledContent::EInstalledLauncher );
       
  1011             break;
       
  1012             }
       
  1013                 
       
  1014         default: 
       
  1015             {
       
  1016             NCD_ASSERT_ALWAYS( 0, ENcdPanicIndexOutOfRange );
       
  1017             }
       
  1018         }
       
  1019     }
       
  1020 
       
  1021 
       
  1022 // ---------------------------------------------------------------------------
       
  1023 // 
       
  1024 // ---------------------------------------------------------------------------
       
  1025 //  
       
  1026 void CNcdNodeInstall::SetLaunchParameterL( 
       
  1027     RPointerArray<CNcdExtendedInstallInfo>& aInstalls, 
       
  1028     TInt aIndex ) const
       
  1029     {
       
  1030     DLTRACEIN((""));
       
  1031     TInt count = aInstalls.Count();
       
  1032     CNcdExtendedInstallInfo& launcher( *aInstalls[ aIndex ] );
       
  1033     
       
  1034     // aIndex is the index of aInstall so increase it
       
  1035     aIndex++;
       
  1036     while ( aIndex < count ) 
       
  1037         {        
       
  1038         if ( aInstalls[ aIndex ]->Filename().Length() && 
       
  1039              aInstalls[ aIndex ]->IsLaunchable() ) 
       
  1040             {
       
  1041             DLTRACE(( _L("Found \"%S\", setting as parameter"), 
       
  1042                 &aInstalls[ aIndex ]->Filename() ));
       
  1043             launcher.SetParameterL( aInstalls[ aIndex ]->Filename() );
       
  1044             break;
       
  1045             }
       
  1046         aIndex++;
       
  1047         }
       
  1048     }
       
  1049 
       
  1050 
       
  1051 // ---------------------------------------------------------------------------
       
  1052 // 
       
  1053 // ---------------------------------------------------------------------------
       
  1054 //  
       
  1055 void CNcdNodeInstall::SetContentVersionL( const TDesC& aVersion ) 
       
  1056     {
       
  1057     DLTRACEIN((""));
       
  1058     iContentVersion = TCatalogsVersion();    
       
  1059     
       
  1060     // Convert the version number in purchase history to TCatalogsVersion    
       
  1061     TRAPD( err, TCatalogsVersion::ConvertL( 
       
  1062         iContentVersion, aVersion ) );
       
  1063         
       
  1064     LeaveIfNotErrorL( err, KErrArgument, KErrGeneral );
       
  1065     
       
  1066     }