codhandler/codeng/src/CodEngBase.cpp
changeset 0 dd21522fd290
child 16 a359256acfc6
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2002 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 the License "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: 
       
    15 *      Implementation of class CCodEngBase.   
       
    16 *      
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 
       
    23 #include "CodEngBase.h"
       
    24 #include "Connection.h"
       
    25 #include "HttpLoader.h"
       
    26 #include "CodSaver.h"
       
    27 #include "FileSaver.h"
       
    28 #include "RoapSaver.h"
       
    29 #include "CodData.h"
       
    30 #include "CodLoadObserver.h"
       
    31 #include "CodError.h"
       
    32 #include "CodStatus.h"
       
    33 #include "CodPanic.h"
       
    34 #include "CodUtil.h"
       
    35 #include "CodLogger.h"
       
    36 #include "RoapData.h"
       
    37 #include "CodProgress.h"
       
    38 #include "MediaObject.h"
       
    39 #include "DownloadDataClient.h"
       
    40 
       
    41 #include <AiwGenericParam.h>
       
    42 #include <DocumentHandler.h>
       
    43 #include <ApmStd.h>
       
    44 #include <Oma2Agent.h>
       
    45 #include <RoapDef.h>
       
    46 #include <f32file.h>
       
    47 #include <BodyPart.h>
       
    48 #include <SysUtil.h>
       
    49 #include <pathinfo.h>
       
    50 #include "CodDefs.h"
       
    51 #include <CodUi.rsg>
       
    52 #include <AknQueryDialog.h>
       
    53 #include <stringloader.h>
       
    54 #include  <bautils.h>
       
    55 #include    "FileExt.h"
       
    56 
       
    57 #ifdef __SYNCML_DM_FOTA
       
    58 #include <fotaengine.h>
       
    59 #include "FotaSaver.h"
       
    60 /// FOTA Update Package type.
       
    61 _LIT8( KFotaPackageDataType, "application/vnd.nokia.swupd.dp2" );
       
    62 /// Default FOTA package id.
       
    63 LOCAL_D const TInt KCodDefaultFotaPkgId = -1;
       
    64 #endif /*def __SYNCML_DM_FOTA */
       
    65 
       
    66 #ifdef RD_MULTIPLE_DRIVE
       
    67 #include <centralrepository.h>
       
    68 #include <driveinfo.h>
       
    69 #include <BrowserUiSDKCRKeys.h>
       
    70 #endif //RD_MULTIPLE_DRIVE
       
    71 
       
    72 #include <bldvariant.hrh>
       
    73 
       
    74 // ================= CONSTANTS =======================
       
    75 const TInt KDownloadInfoIncrSize = 2*4096;     // used for DownloadInfo
       
    76 
       
    77 /// Name of UTF-8 character set.
       
    78 _LIT8( KCodUtf8, "utf-8" );
       
    79 
       
    80 #ifdef RD_MULTIPLE_DRIVE
       
    81 _LIT( KDefaultDriveListSep, ";" );
       
    82 _LIT( KDefaultDriveList, "C;E" );
       
    83 #endif
       
    84 // ================= MEMBER FUNCTIONS =======================
       
    85 
       
    86 // ---------------------------------------------------------
       
    87 // CCodEngBase::~CCodEngBase()
       
    88 // ---------------------------------------------------------
       
    89 //
       
    90 EXPORT_C CCodEngBase::~CCodEngBase()
       
    91     {
       
    92     Cancel();
       
    93     delete iRoapData;
       
    94 
       
    95     if(iSaver)
       
    96         {
       
    97         iSaver->Cleanup( !Pausable() );
       
    98         }
       
    99 
       
   100     delete iSaver;
       
   101     delete iDocHandler;
       
   102     delete iLoader;
       
   103     delete iConn;
       
   104     delete iCodBuf;
       
   105     delete iData;
       
   106     iFs.Close();
       
   107     CLOG(( ECodEng, 2, _L("CCodEngBase::~CCodEngBase") ));
       
   108     CLOG(( ECodEng, 2, _L("*****************") ));
       
   109     }
       
   110 
       
   111 // ---------------------------------------------------------
       
   112 // CCodEngBase::SetL()
       
   113 // ---------------------------------------------------------
       
   114 //
       
   115 EXPORT_C void CCodEngBase::SetL
       
   116         (
       
   117         const TDesC8& aBuf,
       
   118         TRequestStatus* aStatus,
       
   119         const CAiwGenericParamList* aParams,
       
   120         const RPointerArray<CBodyPart>* aParts
       
   121         )
       
   122     {
       
   123     CLOG(( ECodEng, 0, _L("-> CCodEngBase::SetL aParams=0x%x, aParts=0x%x"), \
       
   124         &aParams, aParts ));
       
   125 
       
   126     // Misuse asserts.
       
   127     __ASSERT_ALWAYS( aStatus, CodPanic( ECodInvalidArguments ) );
       
   128     __ASSERT_ALWAYS( iState == EInit || iState == EReady, \
       
   129                                             CodPanic( ECodOffState ) );
       
   130     // Internal asserts.
       
   131     __ASSERT_DEBUG( !iConn, CodPanic( ECodInternal ) );
       
   132     __ASSERT_DEBUG( !iLoader, CodPanic( ECodInternal ) );
       
   133     __ASSERT_DEBUG( !iParentStatus, CodPanic( ECodInternal ) );
       
   134     __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
       
   135     __ASSERT_DEBUG( !iCodBuf, CodPanic( ECodInternal ) );
       
   136 
       
   137     ResetPaths();
       
   138     delete iSaver;
       
   139     iSaver = NULL;
       
   140     iData->Reset();
       
   141     iParts = aParts;
       
   142     iParams = aParams;
       
   143     iType = TDataType();
       
   144     iHandler = TUid::Null();
       
   145     delete iRoapData;
       
   146     iRoapData = NULL;
       
   147 
       
   148     // Default parameters.
       
   149     TPtrC8 sourceUri;
       
   150     TPtrC8 charset( KCodUtf8 );
       
   151     iPreferredIap = 0;
       
   152     
       
   153     // Get params from GenericParams.
       
   154     if ( iParams )
       
   155         {
       
   156         CodUtil::GetDesParamLC( sourceUri, EGenericParamURL, *iParams );
       
   157         CodUtil::GetDesParamLC( charset, EGenericParamCharSet, *iParams );
       
   158         CodUtil::GetUint32Param( iPreferredIap, EGenericParamAccessPoint, *iParams );
       
   159         
       
   160         CodUtil::GetUint32Param( iDownloadId, EGenericParamDownloadId, *iParams );
       
   161         
       
   162         TUint32 AppUId(0);
       
   163         CodUtil::GetUint32Param( AppUId, EGenericParamApplication, *iParams );
       
   164         iAppUId.iUid = AppUId;
       
   165 
       
   166 		// Generate COD DL Info folder name - C:\system\dmgr\<appuid>\codinfo\
       
   167 		
       
   168 		TBuf<KMaxPath> folderName;
       
   169 		CODDownloadInfoFolder(folderName);
       
   170 		
       
   171 		// TO DO - Create the folder if it does not exist
       
   172 		
       
   173         iCodDlInfoPath.Format( _L("%S%d"), &folderName,iDownloadId  );
       
   174 
       
   175         }
       
   176 
       
   177     iData->SetSourceUriL( sourceUri );
       
   178     iCodBuf = CodUtil::ConvertToUcs2L( aBuf, charset, iFs );
       
   179 
       
   180     if ( iParams )
       
   181         {
       
   182         CleanupStack::PopAndDestroy( 2 );   // Two pushed temp buffer.
       
   183         }
       
   184         
       
   185     iParentStatus = aStatus;
       
   186     *iParentStatus = KRequestPending;
       
   187 
       
   188     Continue( ESet );
       
   189 
       
   190     CLOG(( ECodEng, 0, _L("<- CCodEngBase::SetL (user 8-bit)") ));
       
   191     }
       
   192 
       
   193 
       
   194 
       
   195 
       
   196 // ---------------------------------------------------------
       
   197 // CCodEngBase::SetL()
       
   198 // ---------------------------------------------------------
       
   199 //
       
   200 EXPORT_C void CCodEngBase::SetL
       
   201         (
       
   202         const TInt aDownloadId,
       
   203         const TUid aDlUid,
       
   204         //TRequestStatus* aStatus,        
       
   205         const RPointerArray<CBodyPart>* aParts
       
   206         )
       
   207 
       
   208 	{
       
   209     ResetPaths();
       
   210     delete iSaver;
       
   211     iSaver = NULL;
       
   212     iData->Reset();
       
   213     iParts = aParts;
       
   214     //iParams = aParams;
       
   215     iType = TDataType();
       
   216     iHandler = TUid::Null();
       
   217     delete iRoapData;
       
   218     iRoapData = NULL;
       
   219     
       
   220 
       
   221     // Default parameters.
       
   222     TPtrC8 sourceUri;
       
   223     TPtrC8 charset( KCodUtf8 );
       
   224     iPreferredIap = 0;
       
   225   	//iLoader->LoadDownloadInfoL()
       
   226     //Read from info file
       
   227 	iAppUId = aDlUid;
       
   228 	iDownloadId = aDownloadId;
       
   229 	TBuf<KMaxPath> folderName;
       
   230 	CODDownloadInfoFolder(folderName); 
       
   231 	iCodDlInfoPath.Format( _L("%S%d"), &folderName,iDownloadId  );
       
   232 	
       
   233 	// Download resumed after Pause 
       
   234 	iResumedDownload = ETrue;   
       
   235    	
       
   236    	LoadInfoFilesL();
       
   237     	
       
   238 	}
       
   239 // ---------------------------------------------------------
       
   240 // CCodEngBase::CODDownloadInfoFolder()
       
   241 // ---------------------------------------------------------
       
   242 //
       
   243 void CCodEngBase::CODDownloadInfoFolder( TDes& aFolder ) const
       
   244     {
       
   245     aFolder.Format( KDownloadFolderFormat, 
       
   246                         &KDmDefaultDir, 
       
   247                         iAppUId,
       
   248                         &KInfoFilesCodDirName );
       
   249     }
       
   250 
       
   251 // ---------------------------------------------------------
       
   252 // CCodEngBase::Data()
       
   253 // ---------------------------------------------------------
       
   254 //
       
   255 EXPORT_C const CCodData& CCodEngBase::Data() const
       
   256     {
       
   257     return *iData;
       
   258     }
       
   259 
       
   260 // ---------------------------------------------------------
       
   261 // CCodEngBase::SetObserver()
       
   262 // ---------------------------------------------------------
       
   263 //
       
   264 EXPORT_C void CCodEngBase::SetObserver( MCodLoadObserver* aObserver )
       
   265     {
       
   266     CLOG(( ECodEng, 2, _L("CCodEngBase::SetObserver(0x%x)"), aObserver ));
       
   267     __ASSERT_ALWAYS( !(aObserver && iObserver), \
       
   268         CodPanic( ECodObserverAlreadySet ) );
       
   269     iObserver = aObserver;
       
   270     if ( iSaver )
       
   271         {
       
   272         iSaver->SetObserver( iObserver );
       
   273         }
       
   274     if ( iProgress )
       
   275         {
       
   276         iProgress->SetObserver( iObserver );
       
   277         }
       
   278     }
       
   279 
       
   280 // ---------------------------------------------------------
       
   281 // CCodEngBase::Accept()
       
   282 // ---------------------------------------------------------
       
   283 //
       
   284 EXPORT_C void CCodEngBase::Accept( TRequestStatus* aStatus )
       
   285     {
       
   286     CLOG(( ECodEng, 0, _L("-> CCodEngBase::Accept") ));
       
   287     // Misuse asserts.
       
   288     __ASSERT_ALWAYS( iData->IsValid(), CodPanic( ECodInvalidData ) );
       
   289     __ASSERT_ALWAYS( aStatus, CodPanic( ECodInvalidArguments ) );
       
   290     __ASSERT_ALWAYS( iState == EReady, CodPanic( ECodOffState ) );
       
   291     // Internal asserts.
       
   292     __ASSERT_DEBUG( !iConn, CodPanic( ECodInternal ) );
       
   293     __ASSERT_DEBUG( !iLoader, CodPanic( ECodInternal ) );
       
   294     __ASSERT_DEBUG( !iParentStatus, CodPanic( ECodInternal ) );
       
   295 
       
   296     iParentStatus = aStatus;
       
   297     *iParentStatus = KRequestPending;	
       
   298     /*
       
   299 	OMA 2: If the license element includes the order attribute and the order attribute
       
   300 	is equal to the post. The contents of the license element MUST NOT be passed 
       
   301 	to the License Agent unless the Media Object or Product is successfully downloaded		
       
   302     */
       
   303     if (iIsLicense && !iData->IsPostOrder())
       
   304 	{
       
   305 	  // dd2 case with license tag and order tag equals to "any", 
       
   306 	  // so we should install the ROAP trigger as soon as it became available
       
   307 	  Continue( EStartInstallRoap );
       
   308 	}
       
   309     else
       
   310 	{
       
   311 	  // we should install MO first		
       
   312 	  // 1) dd1 case
       
   313 	  // 2) dd2 without license tag
       
   314 	  // 3) dd2 with license tag and order tag = "POST"
       
   315 	  __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
       
   316 	  Continue( EStartConnect );
       
   317 	}
       
   318     CLOG(( ECodEng, 0, _L("<- CCodEngBase::Accept") ));
       
   319     }
       
   320 
       
   321 // ---------------------------------------------------------
       
   322 // CCodEngBase::Reject()
       
   323 // ---------------------------------------------------------
       
   324 //
       
   325 EXPORT_C void CCodEngBase::Reject( TRequestStatus* aStatus )
       
   326     {
       
   327     CLOG(( ECodEng, 0, _L("-> CCodEngBase::Reject") ));
       
   328     // Misuse asserts.
       
   329     __ASSERT_ALWAYS( iData->IsValid(), CodPanic( ECodInvalidData ) );
       
   330     __ASSERT_ALWAYS( aStatus, CodPanic( ECodInvalidArguments ) );
       
   331     __ASSERT_ALWAYS( iState == EReady, CodPanic( ECodOffState ) );
       
   332     // Internal asserts.
       
   333     __ASSERT_DEBUG( !iConn, CodPanic( ECodInternal ) );
       
   334     __ASSERT_DEBUG( !iLoader, CodPanic( ECodInternal ) );
       
   335     __ASSERT_DEBUG( !iParentStatus, CodPanic( ECodInternal ) );
       
   336 //TODO
       
   337 	if (!iIsLicense ) 
       
   338 	{
       
   339     __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
       
   340 	}
       
   341 
       
   342     iParentStatus = aStatus;
       
   343     *iParentStatus = KRequestPending;
       
   344 
       
   345     iResult = KErrAbort;
       
   346     iStatusCode = StatusCode( iResult, iState );
       
   347     Continue( EStartNotify );
       
   348     CLOG(( ECodEng, 0, _L("<- CCodEngBase::Reject") ));
       
   349     }
       
   350 
       
   351 // ---------------------------------------------------------
       
   352 // CCodEngBase::Stop()
       
   353 // ---------------------------------------------------------
       
   354 //
       
   355 EXPORT_C void CCodEngBase::Stop()
       
   356     {
       
   357     CLOG(( ECodEng, 0, _L("-> CCodEngBase::Stop iState(%d)"), iState ));
       
   358 
       
   359     // This method is almost the same as DoCancel, yet works differently:
       
   360     //
       
   361     // When Cancel()->DoCancel() is called, this Active Object is not longer
       
   362     // active (set inactive by the framework). That is, RunL will not be called
       
   363     // after Cancel(). Anything that is going on stopped abruptly, without
       
   364     // any further processing, we are Done() (parent is completed).
       
   365     //
       
   366     // When Stop is called, we still stay active, so after cancelling the
       
   367     // outstanding request (if any), we will complete (RunL will be called)
       
   368     // with KErrCancel. That triggers further processing, so we are not Done()
       
   369     // yet (parent is not completed).
       
   370     //
       
   371     // Having this method comes from the logic of how a downloading is
       
   372     // cancelled: after cancel, we may still have to continue with notify. In
       
   373     // effect, a download must be cancelled twice to stop it; this method
       
   374     // supports the double-cancel.
       
   375 
       
   376     if ( iStopInProgress )
       
   377         {
       
   378         // Prevent reentrant calls.
       
   379         // Reentrancy normally should not be possible: we call some Cancel()
       
   380         // here, and that should not return and should not allow other object
       
   381         // to run until done. But it does: disconnecting the WAP stack
       
   382         // unfortunately includes waiting on the disconnect_cnf event.
       
   383         // This means that there IS a Cancel which allows other objects run.
       
   384         CLOG(( ECodEng, 0, _L("<- CCodEngBase::Stop already stopping") ));
       
   385         return;
       
   386         }
       
   387     iStopInProgress = ETrue;
       
   388 
       
   389     switch ( iState )
       
   390         {
       
   391         case ESet:
       
   392             {
       
   393             // Cancelled before we could start.
       
   394             delete iCodBuf;
       
   395             iCodBuf = NULL;
       
   396             // Own status already completed (by self-completion).
       
   397             __ASSERT_DEBUG( iStatus != KRequestPending, \
       
   398                 CodPanic( ECodInternal ) );
       
   399             SelfComplete( KErrCancel );
       
   400             // Complete parent.
       
   401             iResult = KErrCancel;
       
   402             Done();
       
   403             break;
       
   404             }
       
   405 
       
   406         case EStartConnect:
       
   407         case EStartFetch:
       
   408         case EStartNotify:
       
   409             {
       
   410             // Already completed (by self-completion).
       
   411             __ASSERT_DEBUG( iStatus != KRequestPending, \
       
   412                 CodPanic( ECodInternal ) );
       
   413             SelfComplete( KErrCancel );
       
   414             break;
       
   415             }
       
   416 
       
   417         case EConnect:
       
   418             {
       
   419             __ASSERT_DEBUG( iConn, CodPanic( ECodInternal ) );
       
   420             iConn->Cancel();
       
   421             // We are not Done() - parent request is still outstanding, we
       
   422             // are still active. RunL will be called with KErrCancel.
       
   423             break;
       
   424             }
       
   425 
       
   426         case EFetch:
       
   427             {
       
   428             if ( iObserver && iNotificationStatus == ELoad )
       
   429                 {
       
   430                 CLOG(( ECodEng, 3, \
       
   431                     _L("-> CCodEngBase::Stop notify StartCancelL") ));
       
   432                 TRAP_IGNORE( iObserver->StartCancelL() );
       
   433                 iNotificationStatus = ECancel;
       
   434                 }
       
   435             __ASSERT_DEBUG( iLoader, CodPanic( ECodInternal ) );
       
   436             iLoader->Cancel();
       
   437             // We are not Done() - parent request is still outstanding, we
       
   438             // are still active. RunL will be called with KErrCancel.
       
   439             break;
       
   440             }
       
   441 
       
   442         case EInstall:
       
   443         case EInstallRoap:
       
   444             {
       
   445             __ASSERT_DEBUG( iSaver, CodPanic( ECodInternal ) );
       
   446             iSaver->CancelInstall();
       
   447             // We are not Done() - parent request is still outstanding, we
       
   448             // are still active. RunL will be called with KErrCancel.
       
   449             break;
       
   450             }
       
   451 
       
   452         case ENotify:
       
   453             {
       
   454             __ASSERT_DEBUG( iLoader, CodPanic( ECodInternal ) );
       
   455             iLoader->Cancel();
       
   456             // We are not Done() - parent request is still outstanding, we
       
   457             // are still active. RunL will be called with KErrCancel.
       
   458             break;
       
   459             }
       
   460 
       
   461         case EInit:
       
   462         case EReady:
       
   463         case EStartInstall:
       
   464         default:
       
   465             {
       
   466             if ( iObserver && iNotificationStatus == EPaused )
       
   467                 {
       
   468                 TRAP_IGNORE( iObserver->StartCancelL() );
       
   469                 iNotificationStatus = ECancel;
       
   470                 }
       
   471             // No request is outstanding, but as this is an user-callable
       
   472             // method, tolerate misuse (and do nothing).
       
   473             break;
       
   474             }
       
   475         }
       
   476     iStopInProgress = EFalse;
       
   477     CLOG(( ECodEng, 0, _L("<- CCodEngBase::Stop") ));
       
   478     }
       
   479 
       
   480 // ---------------------------------------------------------
       
   481 // CCodEngBase::RemovableMedia()
       
   482 // ---------------------------------------------------------
       
   483 //
       
   484 EXPORT_C TBool CCodEngBase::RemovableMedia() const
       
   485     {
       
   486     return iRemovableMedia;
       
   487     }
       
   488 
       
   489 // ---------------------------------------------------------
       
   490 // CCodEngBase::GetPath()
       
   491 // ---------------------------------------------------------
       
   492 //
       
   493 EXPORT_C TPtrC CCodEngBase::GetPath() const
       
   494     {
       
   495     if(!iData || !iData->Count() || !(*iData)[iData->ActiveDownload()]->iFullName )
       
   496         return KNullDesC();
       
   497     return *((*iData)[iData->ActiveDownload()]->iFullName);
       
   498     }
       
   499 
       
   500 // ---------------------------------------------------------
       
   501 // CCodEngBase::GetDestFilePath()
       
   502 // ---------------------------------------------------------
       
   503 //
       
   504 EXPORT_C TPtrC CCodEngBase::GetDestFilePath (TInt aMOIndex ) const
       
   505     {
       
   506     if(iData && aMOIndex >=1 && aMOIndex <= iData->Count())
       
   507         {
       
   508         if((*iData)[aMOIndex]->iFullName)
       
   509         	return *((*iData)[aMOIndex]->iFullName);
       
   510         }
       
   511     return TPtrC( KNullDesC );
       
   512     }   
       
   513 
       
   514 // ---------------------------------------------------------
       
   515 // CCodEngBase::GetType()
       
   516 // ---------------------------------------------------------
       
   517 //
       
   518 EXPORT_C const TDataType& CCodEngBase::GetType() const
       
   519     {
       
   520     return iType;
       
   521     }
       
   522 
       
   523 // ---------------------------------------------------------
       
   524 // CCodEngBase::GetHandler()
       
   525 // ---------------------------------------------------------
       
   526 //
       
   527 EXPORT_C TUid CCodEngBase::GetHandler() const
       
   528     {
       
   529     return iHandler;
       
   530     }
       
   531 
       
   532 // ---------------------------------------------------------
       
   533 // CCodEngBase::GetStatusCode()
       
   534 // ---------------------------------------------------------
       
   535 //
       
   536 EXPORT_C TInt CCodEngBase::GetStatusCode() const
       
   537     {
       
   538     return iStatusCode;
       
   539     }
       
   540 
       
   541 // ---------------------------------------------------------
       
   542 // CCodEngBase::GetRoapData()
       
   543 // ---------------------------------------------------------
       
   544 //
       
   545 EXPORT_C const CRoapData* CCodEngBase::GetRoapData() const
       
   546     {
       
   547     return iRoapData;
       
   548     }
       
   549 
       
   550 // ---------------------------------------------------------
       
   551 // CCodEngBase::SetCodDlAttached()
       
   552 // ---------------------------------------------------------
       
   553 //
       
   554 EXPORT_C void CCodEngBase::SetCodDlAttached(const TBool aValue)
       
   555     {
       
   556        iAttached = aValue;
       
   557        if(iSaver)
       
   558        {
       
   559         iSaver->SetProgressiveMode(aValue);	
       
   560        }
       
   561        
       
   562     }
       
   563     
       
   564 // ---------------------------------------------------------
       
   565 // CCodEngBase::CCodEngBase()
       
   566 // ---------------------------------------------------------
       
   567 //
       
   568 CCodEngBase::CCodEngBase( MCodLoadObserver* aObserver )
       
   569 : CActive( CActive::EPriorityStandard ),
       
   570   iState( EInit ),
       
   571   iObserver( aObserver ),
       
   572   iStopInProgress( EFalse ),
       
   573   iPreferredIap( 0 ),
       
   574   iNotificationStatus( ENull ),
       
   575   iFsUsed( EFalse ),
       
   576   iDownloadId( 0 ),
       
   577 #ifdef RD_MULTIPLE_DRIVE 
       
   578   iSpaceAvailOk( EFalse ),
       
   579   iAvailDriveSpace( -1 ),
       
   580 #else
       
   581   iPhoneMemoryOk( EFalse ),
       
   582   iMmcOk( EFalse ),
       
   583 #endif
       
   584   iRemovableMedia( EFalse ),
       
   585   iStatusCode( KHttp902UserCancelled ),
       
   586   iResult( KErrGeneral ),
       
   587   iContentTypeCheck ( EFalse ),
       
   588   iResumedDownload ( EFalse )  
       
   589     {
       
   590     CLOG(( ECodEng, 2, _L("") ));
       
   591     CLOG(( ECodEng, 2, _L("*****************") ));
       
   592     CLOG(( ECodEng, 2, _L("CCodEngBase::CCodEngBase") ));
       
   593     CLOG(( ECodEng, 2, _L8("Build time " __DATE__ " " __TIME__) ));
       
   594     CActiveScheduler::Add( this );
       
   595     }
       
   596 
       
   597 // ---------------------------------------------------------
       
   598 // CCodEngBase::ConstructL()
       
   599 // ---------------------------------------------------------
       
   600 //
       
   601 void CCodEngBase::ConstructL( CEikProcess* aProcess )
       
   602     {
       
   603     iData = CCodData::NewL();
       
   604     iDocHandler = CDocumentHandler::NewL( aProcess );
       
   605     User::LeaveIfError( iFs.Connect() );
       
   606 #ifdef RD_MULTIPLE_DRIVE
       
   607     QueryDriveListL();
       
   608 #endif
       
   609     }
       
   610 
       
   611 // ---------------------------------------------------------
       
   612 // CCodEngBase::DoCancel()
       
   613 // ---------------------------------------------------------
       
   614 //
       
   615 void CCodEngBase::DoCancel()
       
   616     {
       
   617     CLOG(( ECodEng, 2, _L("-> CCodEngBase::DoCancel iState(%d)"), iState ));
       
   618 
       
   619     switch ( iState )
       
   620         {
       
   621         case ESet:
       
   622         case EStartConnect:
       
   623         case EStartFetch:
       
   624         case EStartNotify:
       
   625             {
       
   626             // Already completed (by self-completion).
       
   627             __ASSERT_DEBUG( iStatus != KRequestPending, \
       
   628                 CodPanic( ECodInternal ) );
       
   629             SelfComplete( KErrCancel );
       
   630             break;
       
   631             }
       
   632 
       
   633         case EConnect:
       
   634             {
       
   635             // Instant abort, without any further processing
       
   636             // (no install, no notify).
       
   637             __ASSERT_DEBUG( iConn, CodPanic( ECodInternal ) );
       
   638             iConn->Cancel();
       
   639             break;
       
   640             }
       
   641             
       
   642         case EFetch:
       
   643         case ENotify:
       
   644             {
       
   645             // Instant abort, without any further processing
       
   646             // (no install, no notify).
       
   647             __ASSERT_DEBUG( iLoader, CodPanic( ECodInternal ) );
       
   648             iLoader->Cancel();
       
   649             break;
       
   650             }
       
   651 
       
   652         case EInstall:
       
   653             {
       
   654             // Instant abort, without any further processing (no notify).
       
   655             __ASSERT_DEBUG( iSaver, CodPanic( ECodInternal ) );
       
   656             iSaver->CancelInstall();
       
   657             break;
       
   658             }
       
   659             
       
   660         case EInit:
       
   661         case EReady:
       
   662         case EStartInstall:
       
   663         default:
       
   664             {
       
   665             // No requests should be outstanding in these states.
       
   666             CodPanic( ECodInternal );
       
   667             break;
       
   668             }
       
   669         }
       
   670 
       
   671     iStatusCode = KHttp902UserCancelled;    // "Clarity only" code.
       
   672     iResult = KErrCancel;                   // "Clarity only" code.
       
   673     Done();                                 // Complete parent.
       
   674     CLOG(( ECodEng, 2, _L("<- CCodEngBase::DoCancel") ));
       
   675     }
       
   676 
       
   677 
       
   678 EXPORT_C void CCodEngBase::Pause()
       
   679     {
       
   680     CLOG(( ECodEng, 2, _L("-> CCodEngBase::Pause iState(%d)"), iState ));
       
   681 
       
   682     switch ( iState )
       
   683         {
       
   684         case EFetch:
       
   685             {
       
   686             // Instant abort, without any further processing
       
   687             // (no install, no notify).
       
   688             __ASSERT_DEBUG( iLoader, CodPanic( ECodInternal ) );
       
   689             iLoader->Pause();
       
   690             //iLoader->CompleteTransaction();
       
   691             break;
       
   692             }
       
   693         }
       
   694 
       
   695     //Done();                                 // Complete parent.
       
   696     CLOG(( ECodEng, 2, _L("<- CCodEngBase::Pause") ));
       
   697     }
       
   698 
       
   699 // ---------------------------------------------------------
       
   700 // CCodEngBase::RunL()
       
   701 // ---------------------------------------------------------
       
   702 //
       
   703 void CCodEngBase::RunL()
       
   704     {
       
   705     CLOG(( ECodEng, 2, _L("-> CCodEngBase::RunL iStatus(%d) iState(%d)"), \
       
   706         iStatus.Int(), iState ));
       
   707 
       
   708     switch( iState )
       
   709         {
       
   710         case ESet:
       
   711             {
       
   712             SetL();
       
   713             break;
       
   714             }
       
   715 
       
   716         case EStartInstallRoap:
       
   717             {
       
   718             StartInstallRoapL();
       
   719             break;
       
   720             }
       
   721 
       
   722         case EInstallRoap:
       
   723             {
       
   724             EndInstallRoapL();
       
   725             break;
       
   726             }
       
   727 
       
   728         case EStartConnect:
       
   729             {
       
   730             StartConnectL();
       
   731             break;
       
   732             }
       
   733 
       
   734         case EConnect:
       
   735             {
       
   736             EndConnectL();
       
   737             break;
       
   738             }
       
   739 
       
   740         case EStartFetch:
       
   741             {
       
   742             StartFetchL();
       
   743             break;
       
   744             }
       
   745 
       
   746         case EFetch:
       
   747             {
       
   748             EndFetchL();
       
   749             break;
       
   750             }
       
   751 
       
   752         case EStartInstall:
       
   753             {
       
   754             StartInstallL();
       
   755             break;
       
   756             }
       
   757 
       
   758         case EInstall:
       
   759             {
       
   760             EndInstallL();
       
   761             break;
       
   762             }
       
   763             
       
   764         case EStartNotify:
       
   765             {
       
   766             StartNotifyL();
       
   767             break;
       
   768             }
       
   769 
       
   770         case ENotify:
       
   771             {
       
   772             EndNotifyL();
       
   773             break;
       
   774             }
       
   775         case EMediaChange:
       
   776         	{
       
   777         	ChangeMediaObjectL();
       
   778         	break;
       
   779         	}
       
   780         case EStartProductNotify:
       
   781             {
       
   782             StartProductNotifyL();
       
   783             break;
       
   784             }
       
   785         case EProductNotify:
       
   786             {
       
   787             EndProductNotifyL();
       
   788             break;            
       
   789             }
       
   790         case EInit:
       
   791         case EReady:
       
   792         default:
       
   793             {
       
   794             // No requests should be outstanding in these states.
       
   795             CLOG(( ECodEng, 0, _L("CCodEngBase::RunL: unexpected state") ));
       
   796             CodPanic( ECodInternal );
       
   797             break;
       
   798             }
       
   799         }
       
   800     CLOG(( ECodEng, 2, _L("<- CCodEngBase::RunL") ));
       
   801     }
       
   802 
       
   803 // ---------------------------------------------------------
       
   804 // CCodEngBase::RunError()
       
   805 // ---------------------------------------------------------
       
   806 //
       
   807 TInt CCodEngBase::RunError( TInt aError )
       
   808     {
       
   809     CLOG(( ECodEng, 2, \
       
   810         _L("-> CCodEngBase::RunError iStatus(%d) iState(%d) aError(%d)"), \
       
   811         iStatus.Int(), iState, aError ));
       
   812     switch( iState )
       
   813         {
       
   814         case ESet:
       
   815             {
       
   816             delete iCodBuf;
       
   817             iCodBuf = NULL;
       
   818             // Failed - classify reason and notify about failure.
       
   819             iStatusCode = StatusCode( aError, iState );
       
   820             iResult = aError;
       
   821             Continue( EStartNotify );
       
   822             break;
       
   823             }
       
   824 
       
   825         case EStartInstallRoap:
       
   826         case EInstallRoap:
       
   827 			{
       
   828             iStatusCode = StatusCode( aError, iState );
       
   829             iResult = aError;
       
   830             Continue( EStartNotify );
       
   831             break;
       
   832 			}
       
   833         case EStartConnect:
       
   834         case EConnect:
       
   835         case EStartFetch:
       
   836         case EFetch:
       
   837         case EStartInstall:
       
   838         case EInstall:
       
   839             {
       
   840             
       
   841             if(aError != KErrCodHttpServerError)
       
   842                 {
       
   843                 //if PreconditionFailed check if the updated DD URI is present
       
   844                 //cancel the download if not set
       
   845                 if( aError == KErrCodHttpPreconditionFailed )
       
   846                     {
       
   847                 if( iData && iData->UpdatedDDUriL().Length() )
       
   848                         {
       
   849                         iState = EInit;//in case of 412 we should restart from first state
       
   850                         iStatusCode =  StatusCode( aError, iState );
       
   851                     	TBuf<KMaxPath>   folderName;
       
   852                     	CODDownloadInfoFolder(folderName);
       
   853 
       
   854                     	HBufC* fileNameBuf = HBufC::NewLC( KMaxPath );
       
   855                     	TPtr fileName = fileNameBuf->Des();
       
   856 
       
   857                     	fileName.Format( _L("%S%d"), &folderName,iDownloadId  );
       
   858                         RFs fs;
       
   859                         User::LeaveIfError( fs.Connect() );
       
   860                         fs.Delete( fileName );//delete the info path as download has to begin from fresh state
       
   861                         CleanupStack::PopAndDestroy( fileNameBuf );	
       
   862                         fs.Close();                    
       
   863                         }
       
   864                     else
       
   865                         {
       
   866                         // Failed - classify reason and notify about failure.
       
   867                         iStatusCode = StatusCode( aError, iState );
       
   868                         iResult = aError;
       
   869                                             
       
   870                         //If ther is no Updated DD Uri. Cancel the download.
       
   871                         DoCancel();
       
   872                         break;
       
   873                         }
       
   874                     }
       
   875                 else
       
   876                     {
       
   877                     //If user cancel the download, delete the media object also.
       
   878                     //If paused due to other errors, delete the file if non-pausable.
       
   879                     if(iSaver)
       
   880                         {
       
   881                         TBool delContent = (aError == KErrCancel) ? ETrue : !( iData && (*iData)[iData->ActiveDownload()]->iPausable );
       
   882                         iSaver->Cleanup( delContent );
       
   883                         }
       
   884                     }
       
   885                 if( iObserver && KErrCodHttpPreconditionFailed != aError)
       
   886                     {
       
   887                     //TODO : Pass the error code if required
       
   888                     iObserver->DownloadPaused();
       
   889                     iNotificationStatus = EPaused;
       
   890                     } 
       
   891                     
       
   892                 }
       
   893             delete iSaver;  // Cleans up.
       
   894             iSaver = NULL;
       
   895 
       
   896             // Failed - classify reason and notify about failure.
       
   897             iStatusCode = StatusCode( aError, iState );
       
   898             iResult = aError;
       
   899             Continue( EStartNotify );
       
   900             break;
       
   901             }
       
   902 
       
   903         case EStartNotify:
       
   904         case ENotify:
       
   905             {
       
   906             //If Notify Fails do not delete download.
       
   907             //Ignore the error code.
       
   908             //End State Machine.Download is Successful.
       
   909             Done();
       
   910             break;
       
   911             }
       
   912         case EStartProductNotify:
       
   913         case EProductNotify:
       
   914             {
       
   915             Done();
       
   916             break;
       
   917             }
       
   918 
       
   919         case EInit:
       
   920         case EReady:
       
   921         default:
       
   922             {
       
   923             // No requests should be outstanding in these states.
       
   924             CLOG(( ECodEng, 0, _L("CCodEngBase::RunError: unexpected state") ));
       
   925             CodPanic( ECodInternal );
       
   926             break;
       
   927             }
       
   928         }
       
   929     
       
   930     if (iData && iData->Count())
       
   931     	{
       
   932 	    (*iData)[iData->ActiveDownload()]->iStatusCode = iStatusCode;
       
   933     	(*iData)[iData->ActiveDownload()]->iResult = iResult;
       
   934     	}
       
   935     
       
   936     CLOG(( ECodEng, 2, _L("<- CCodEngBase::RunError") ));
       
   937     return KErrNone;
       
   938     }
       
   939 
       
   940 // ---------------------------------------------------------
       
   941 // CCodEngBase::SetL()
       
   942 // ---------------------------------------------------------
       
   943 //
       
   944 void CCodEngBase::SetL()
       
   945     {
       
   946     CLOG(( ECodEng, 2, _L("-> CCodEngBase::SetL (internal)") ));
       
   947     __ASSERT_DEBUG( iState == ESet, CodPanic( ECodInternal ) );
       
   948     __ASSERT_DEBUG( iCodBuf, CodPanic( ECodInternal ) );
       
   949     
       
   950     ParseDataL();
       
   951 
       
   952     iData->SetActiveDownload ( 1 );
       
   953     if( !(*(*iData)[iData->ActiveDownload()]).Name().Length() )
       
   954     {
       
   955     //No name To display
       
   956     //add "unnamed"
       
   957      (*(*iData)[iData->ActiveDownload()]).SetNameL( _L("Unnamed") ); 
       
   958     }
       
   959     CLOG(( ECodEng, 4, _L("CCodEngBase::SetL: parsed OK") ));
       
   960     delete iCodBuf;
       
   961     iCodBuf = NULL;
       
   962     CheckDataL();   // TODO move that out from derived classes.
       
   963     
       
   964     TInt err = KErrNone;
       
   965     for( TInt i = 1; i <= iData->Count() ; ++i )
       
   966         {
       
   967         iData->SetActiveDownload ( i );
       
   968         //So that this download is considered when resume happens
       
   969         //only in progress download can resume
       
   970         (*iData)[ iData->ActiveDownload()]->iState = EInProgress; 
       
   971         TRAP( err , CapabilityCheckL());
       
   972         if( !err )
       
   973             {
       
   974             break;
       
   975             }
       
   976         else if( err != KErrCodInsufficientSpace )
       
   977             {
       
   978             User::Leave( err );            
       
   979             }        
       
   980         }
       
   981         
       
   982     if( err )
       
   983     	{
       
   984 	    User::Leave( err );
       
   985     	}
       
   986     iState = EReady;
       
   987     iResult = KErrNone;
       
   988     iStatusCode = StatusCode( iResult, iState );
       
   989 
       
   990     //Create info files
       
   991     //This would create info file for album and each media track
       
   992     
       
   993     StoreInfoFilesL();
       
   994     
       
   995     // Update album and track info in server
       
   996     UpdateMediaInfoL();
       
   997     
       
   998     if (iIsLicense && !iData->IsPostOrder())
       
   999 	{
       
  1000       // install Roap trigger first
       
  1001       DoneDD2();  
       
  1002 	}
       
  1003     else
       
  1004 	{
       
  1005       Done();
       
  1006 	}
       
  1007 
       
  1008     CLOG(( ECodEng, 2, _L("<- CCodEngBase::SetL (internal)") ));
       
  1009     }
       
  1010 
       
  1011 // ---------------------------------------------------------
       
  1012 // CCodEngBase::SetFileNameL()
       
  1013 // ---------------------------------------------------------
       
  1014 //
       
  1015 void CCodEngBase::SetFileNameL()
       
  1016     {
       
  1017 
       
  1018     // Full name that we need to construct
       
  1019     HBufC* fullName = HBufC::NewLC(KMaxFileName);
       
  1020     TPtr fullNamePtr( fullName->Des() );
       
  1021     fullNamePtr.Append( (*iData)[iData->ActiveDownload()]->iTempPath );            // "c:\\system\\temp\\"
       
  1022     fullNamePtr.Append( (*iData)[iData->ActiveDownload()]->Name() );        // "c:\\system\\temp\\myfile"
       
  1023     
       
  1024    
       
  1025     
       
  1026     const TDataType& type( (*iData)[iData->ActiveDownload()]->Types().MdcaPoint( 0) );
       
  1027     
       
  1028     //Following code is added to fix the bug DRAI-7KA8TT( File is not available in Gallery even when download list shows "Saved to Gallery".)
       
  1029     //Fix applied: Changing the content type that is passed to document handler to "application/vnd.oma.drm.content" when the received content type is
       
  1030     //"application/vnd.oma.drm.message"
       
  1031     //This is because document handler is not changing the extension when content type is passed as "application/vnd.oma.drm.message"  
       
  1032     if(0==type.Des8().Compare(KOma1DrmMessageContentType))
       
  1033         {
       
  1034         // Add extention to full name of file
       
  1035         iDocHandler->CheckFileNameExtension(fullNamePtr, TDataType(KOma1DcfContentType)); // "c:\\system\\temp\\myfile.mp3"    
       
  1036         }
       
  1037     else
       
  1038         {
       
  1039         // Add extention to full name of file
       
  1040         iDocHandler->CheckFileNameExtension(fullNamePtr, type ); // "c:\\system\\temp\\myfile.mp3"    
       
  1041         }
       
  1042 
       
  1043     CleanupStack::Pop(fullName);
       
  1044     
       
  1045     // This is the Full name that we want
       
  1046     delete (*iData)[iData->ActiveDownload()]->iFullName;
       
  1047     (*iData)[iData->ActiveDownload()]->iFullName = fullName;
       
  1048     
       
  1049     }
       
  1050 
       
  1051 // ---------------------------------------------------------
       
  1052 // CCodEngBase::SetUniqueFileNameL()
       
  1053 // ---------------------------------------------------------
       
  1054 //
       
  1055 void CCodEngBase::SetUniqueFileNameL()
       
  1056     {
       
  1057     HBufC* fullName = HBufC::NewLC(KMaxFileName);
       
  1058     TPtr fullNamePtr( fullName->Des() );
       
  1059     fullNamePtr.Append( (*iData)[iData->ActiveDownload()]->iFullName->Des() );
       
  1060     
       
  1061     // Get the file path
       
  1062     HBufC* filePath = HBufC::NewLC(KMaxFileName);
       
  1063     filePath->Des().Append( (*iData)[iData->ActiveDownload()]->iTempPath );        // "c:\\system\\temp\\"
       
  1064 
       
  1065     // Retrieve extention as a string
       
  1066     HBufC* extention = HBufC::NewLC(KMaxFileName);
       
  1067     TInt dotInd = fullNamePtr.LocateReverse( '.' );
       
  1068     if( dotInd != KErrNotFound )
       
  1069         // filename extension found.
       
  1070         {
       
  1071         extention->Des().Copy( fullNamePtr.Right( fullNamePtr.Length() - dotInd ) );
       
  1072         }
       
  1073 
       
  1074     // File name without extention
       
  1075     HBufC* fileName = HBufC::NewLC(KMaxFileName);
       
  1076     fileName->Des().Append( (*iData)[iData->ActiveDownload()]->Name() );    // "myfile"
       
  1077     TInt dot = fileName->LocateReverse( '.' );//check if Dot is part of name in DD file
       
  1078     // Find a unique file name. If fileName already exists, then this function will
       
  1079     // change fileName to some other unique name (like "myfile(1)")
       
  1080     if( dot != KErrNotFound )
       
  1081         {
       
  1082         //Remove Extension 
       
  1083         //File Name is with an extension.   
       
  1084         fileName->Des().Copy( fileName->Des().Left(dot));         
       
  1085         }        
       
  1086     iSaver->ConvertDownloadNameUniqueL( filePath, fileName, extention );
       
  1087     HBufC* dispName = HBufC::NewLC(KMaxFileName);
       
  1088     TPtr displayName(dispName->Des());
       
  1089     displayName.Append(*fileName);
       
  1090     if( dot != KErrNotFound )
       
  1091         {
       
  1092         //Since Name is with extension Append to Display Name
       
  1093         displayName.Append(*extention);
       
  1094         }
       
  1095     (*iData)[iData->ActiveDownload()]->SetNameL( displayName );
       
  1096     CleanupStack::PopAndDestroy(dispName);
       
  1097 
       
  1098 
       
  1099     // Now when we have a unique file name, create the full name (with path and extention)
       
  1100     fullNamePtr.Copy( *filePath );
       
  1101     fullNamePtr.Append( *fileName );
       
  1102 	fullNamePtr.Append( *extention );           // Example - "c:\\system\\temp\\myfile(1).mp3"
       
  1103     CleanupStack::PopAndDestroy(fileName);
       
  1104     CleanupStack::PopAndDestroy(extention);
       
  1105     CleanupStack::PopAndDestroy(filePath);
       
  1106     CleanupStack::Pop(fullName);
       
  1107     
       
  1108     // This is the Full name that we want
       
  1109     delete (*iData)[iData->ActiveDownload()]->iFullName;
       
  1110     (*iData)[iData->ActiveDownload()]->iFullName = fullName;
       
  1111 
       
  1112     }
       
  1113 
       
  1114 // ---------------------------------------------------------
       
  1115 // CCodEngBase::StartConnectL()
       
  1116 // ---------------------------------------------------------
       
  1117 //
       
  1118 void CCodEngBase::StartConnectL()
       
  1119     {
       
  1120     CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartConnectL") ));
       
  1121     __ASSERT_DEBUG( iState == EStartConnect, CodPanic( ECodInternal ) );		
       
  1122     if (!iIsLicense ) 
       
  1123 	{
       
  1124        __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
       
  1125 	}
       
  1126     __ASSERT_DEBUG( !iConn, CodPanic( ECodInternal ) );
       
  1127     
       
  1128 
       
  1129         //For the first track it is done already
       
  1130         CapabilityCheckL(); 
       
  1131 
       
  1132         //Inform server about the Active download
       
  1133         iObserver->SetActiveDownload( );
       
  1134         iObserver->ContentTypeChanged();
       
  1135         iObserver->MediaObjectNameChanged();
       
  1136                 
       
  1137         //Content type check should be done for subsequent tracks
       
  1138         iContentTypeCheck = EFalse;
       
  1139         
       
  1140         //Download is resumed for the current track in the album. For the subsequent tracks(downloads),iResumedDownload should be false
       
  1141         iResumedDownload = EFalse;
       
  1142         
       
  1143         
       
  1144         //Let all download that begin be in this state and then go to subsequent Succeeded state
       
  1145         (*iData)[iData->ActiveDownload()]->iState = EInProgress;     
       
  1146 
       
  1147     if ( iFsUsed && (*iData)[iData->ActiveDownload()]->iTempPath == KNullDesC )
       
  1148         {
       
  1149         // Select drive before IAP selection.
       
  1150         SetPathsL();
       
  1151         SetFileNameL();       
       
  1152         //Store in Info File
       
  1153         StoreSubInfoFileL( NULL, iData->ActiveDownload() );
       
  1154         }
       
  1155     else
       
  1156         {
       
  1157         //Paused Download change display name if not already done
       
  1158         iObserver->MediaObjectNameChanged();
       
  1159         }
       
  1160 
       
  1161     if ( CodUtil::IsCidSchemeL( (*iData)[iData->ActiveDownload()]->Url() ) &&
       
  1162          ( !(*iData)[iData->ActiveDownload()]->InstallNotify().Length() ||
       
  1163            CodUtil::IsCidSchemeL( (*iData)[iData->ActiveDownload()]->InstallNotify() )
       
  1164          )
       
  1165        )
       
  1166         {
       
  1167         CLOG(( ECodEng, 3, _L("  all URI-s are cid -> no connect") ));
       
  1168         // All URI-s are cid, no need to connect.
       
  1169         // Synchronous state change - we are already under RunL().
       
  1170         iState = EConnect;
       
  1171         EndConnectL();
       
  1172         }
       
  1173     else
       
  1174         {
       
  1175         // We have at least one non-cid scheme URI, need to connect.
       
  1176         CLOG(( ECodEng, 3, _L("  connecting") ));
       
  1177         iConn = CConnection::NewL();
       
  1178         iConn->ConnectL( iPreferredIap, &iStatus );
       
  1179         iState = EConnect;
       
  1180         SetActive();
       
  1181         if ( iObserver )
       
  1182             {
       
  1183             CLOG(( ECodEng, 3, \
       
  1184                 _L("-> CCodEngBase::StartConnectL notify StartLoadL(%d)"), \
       
  1185                 KHttp900Success ));
       
  1186             iObserver->StartLoadL( KHttp900Success );
       
  1187             iNotificationStatus = ELoad;
       
  1188             }
       
  1189         }
       
  1190 
       
  1191     CLOG(( ECodEng, 2, _L("<- CCodEngBase::StartConnectL") ));
       
  1192     }
       
  1193 
       
  1194 // ---------------------------------------------------------
       
  1195 // CCodEngBase::EndConnectL
       
  1196 // ---------------------------------------------------------
       
  1197 //
       
  1198 void CCodEngBase::EndConnectL()
       
  1199     {
       
  1200     CLOG(( ECodEng, 2, _L("-> CCodEngBase::EndConnectL iStatus(%d)"), \
       
  1201         iStatus.Int() ));
       
  1202     __ASSERT_DEBUG( iState == EConnect, CodPanic( ECodInternal ) );
       
  1203 
       
  1204     User::LeaveIfError( iStatus.Int() );        // Handle errors in RunError().
       
  1205 
       
  1206     // Synchronous state change - we are already under RunL().
       
  1207     iState = EStartFetch;
       
  1208     StartFetchL();
       
  1209     CLOG(( ECodEng, 2, _L("<- CCodEngBase::EndConnectL") ));
       
  1210     }
       
  1211 
       
  1212 // ---------------------------------------------------------
       
  1213 // CCodEngBase::StartFetchL()
       
  1214 // ---------------------------------------------------------
       
  1215 //
       
  1216 void CCodEngBase::StartFetchL()
       
  1217     {
       
  1218     CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartFetchL") ));
       
  1219     __ASSERT_DEBUG( iState == EStartFetch, CodPanic( ECodInternal ) );
       
  1220     __ASSERT_DEBUG( !iLoader, CodPanic( ECodInternal ) );
       
  1221     if (!iIsLicense )
       
  1222 	{
       
  1223       __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
       
  1224 	}
       
  1225 
       
  1226     // Setup progress.
       
  1227     // Fetch size is known. ROAP & notify traffic is estimated.
       
  1228     if(!iProgress)
       
  1229         {
       
  1230         iProgress = new (ELeave) TCodProgress( iObserver );
       
  1231 
       
  1232         TInt roapBytes = (*iData)[iData->ActiveDownload()]->Type().Compare( KOma2TriggerContentType ) ?
       
  1233             0 :
       
  1234             KRoapProgressMax;
       
  1235 /*
       
  1236             iProgress->Setup
       
  1237             (
       
  1238             iData->Size() + roapBytes ,
       
  1239             iData->InstallNotify().Length() ? KCodNotifyTraffic : 0 
       
  1240             );    
       
  1241 */
       
  1242             iProgress->Setup
       
  1243             (
       
  1244             (*iData)[iData->ActiveDownload()]->Size() + roapBytes ,
       
  1245             iData->InstallNotify().Length() ? KCodNotifyTraffic : 0 
       
  1246             ); 
       
  1247         }
       
  1248 
       
  1249     if ( CodUtil::IsCidSchemeL( (*iData)[iData->ActiveDownload()]->Url() ) )
       
  1250         {
       
  1251         if ( !iParts )
       
  1252             {
       
  1253             // Cannot resolve cid: scheme URI-s without the multipart parts!
       
  1254             CLOG(( ECodEng, 4, _L("  no multipart, fail") ));
       
  1255             User::Leave( KErrNotFound );
       
  1256             }
       
  1257         CBodyPart* part = CodUtil::PartByCidL( *iParts, (*iData)[iData->ActiveDownload()]->Url() );
       
  1258         if ( !part )
       
  1259             {
       
  1260             CLOG(( ECodEng, 4, _L("  part not found, fail") ));
       
  1261             User::Leave( KErrNotFound );
       
  1262             }
       
  1263 		CreateSaverL( part->ContentType() );
       
  1264         User::LeaveIfError( iSaver->AppendData( part->Body() ) );
       
  1265         iSaver->CloseStore();
       
  1266         iProgress->IncrementL( part->Body().Size() );
       
  1267         // Synchronous state change - we are already under RunL().
       
  1268         iState = EFetch;
       
  1269         EndFetchL();
       
  1270         }
       
  1271     else
       
  1272         {
       
  1273         __ASSERT_DEBUG( iConn, CodPanic( ECodInternal ) );
       
  1274         iLoader = CHttpLoader::NewL( *iConn, NULL, iProgress ,this);
       
  1275         HBufC8* url = CodUtil::AbsoluteUrlLC
       
  1276             ( iData->SourceUri(), (*iData)[iData->ActiveDownload()]->Url() );
       
  1277         iLoader->LoadL( *url, *this, &iStatus );
       
  1278         CleanupStack::PopAndDestroy( url );
       
  1279 
       
  1280         iState = EFetch;
       
  1281         SetActive();
       
  1282 	}
       
  1283     
       
  1284     CLOG(( ECodEng, 2, _L("<- CCodEngBase::StartFetchL") ));
       
  1285     }
       
  1286 
       
  1287 // ---------------------------------------------------------
       
  1288 // CCodEngBase::EndFetchL
       
  1289 // ---------------------------------------------------------
       
  1290 //
       
  1291 void CCodEngBase::EndFetchL()
       
  1292     {
       
  1293     CLOG(( ECodEng, 2, _L("-> CCodEngBase::EndFetchL iStatus(%d)"), \
       
  1294         iStatus.Int() ));
       
  1295     __ASSERT_DEBUG( iState == EFetch, CodPanic( ECodInternal ) );
       
  1296 
       
  1297     User::LeaveIfError( iStatus.Int() );        // Handle errors in RunError().
       
  1298 
       
  1299     __ASSERT_DEBUG( iSaver, CodPanic( ECodInternal ) );
       
  1300 //TODO: ??  iState == EStoreOpen (for dd2) EStoreClose - for dd1
       
  1301     iSaver->CheckResponseAttributesL( *iData ); // Leaves if response not OK.
       
  1302 
       
  1303 	if (iIsLicense)
       
  1304 	{
       
  1305     iStatusCode = KHttp956LicenseSuccess;
       
  1306 	}
       
  1307 	else
       
  1308 	{
       
  1309     iStatusCode = KHttp900Success;
       
  1310 	}
       
  1311     iResult = KErrNone;
       
  1312     // Synchronous state change - we are already under RunL().
       
  1313     iState = EStartInstall;
       
  1314     StartInstallL();
       
  1315     CLOG(( ECodEng, 2, _L("<- CCodEngBase::EndFetchL") ));
       
  1316     }
       
  1317 
       
  1318 // ---------------------------------------------------------
       
  1319 // CCodEngBase::StartInstallL()
       
  1320 // ---------------------------------------------------------
       
  1321 //
       
  1322 void CCodEngBase::StartInstallL()
       
  1323     {
       
  1324     CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartInstallL iStatusCode(%d)"), \
       
  1325         iStatusCode ));
       
  1326     __ASSERT_DEBUG( iState == EStartInstall, CodPanic( ECodInternal ) );
       
  1327     __ASSERT_DEBUG( iSaver, CodPanic( ECodInternal ) );
       
  1328 
       
  1329     //__ASSERT_DEBUG( iStatusCode == KHttp900Success, CodPanic( ECodInternal ) );
       
  1330 
       
  1331     (*iData)[iData->ActiveDownload()]->iState = ETobeInstalled;
       
  1332     
       
  1333     if( iData->Count() > 1)
       
  1334         {
       
  1335         // Check to see if all tracks are downloaded. Install will be done only at the end
       
  1336         for( TInt i = 1; i <= iData->Count() ; ++i )
       
  1337             {
       
  1338             TInt state ((*iData)[i]->iState);
       
  1339             if( state != ETobeInstalled && state != ESucceeded )
       
  1340         	    {
       
  1341         	    Continue(EInstall);
       
  1342         	    return;
       
  1343         	    }
       
  1344             }
       
  1345         }
       
  1346 
       
  1347     TInt installErr( KErrNone );
       
  1348 
       
  1349 	if (iObserver && (iObserver->ConnError() == KErrTimedOut))
       
  1350 	{
       
  1351 		User::LeaveIfError( KErrTimedOut );
       
  1352 	}
       
  1353 	else
       
  1354 	    {
       
  1355 	    if( iData->Count() > 1)
       
  1356 	        {
       
  1357             TRAP( installErr, iSaver->BulkInstallL( &iStatus, *iData, iAttached ));
       
  1358 	        }
       
  1359         else
       
  1360 	        {
       
  1361             if (!iIsDd2)
       
  1362                 {
       
  1363                 TRAP( installErr, iSaver->InstallL( &iStatus, (*iData)[iData->ActiveDownload()]->Name(), iAttached ));
       
  1364                 }
       
  1365             else
       
  1366                 {
       
  1367                 TRAP( installErr, iSaver->InstallL( &iStatus, (*iData)[iData->ActiveDownload()]->iFullName->Des(), iAttached )); 
       
  1368                 }
       
  1369             //Move has happened update destination file name
       
  1370 	        (*iData)[ iData->ActiveDownload()]->iFullName = iSaver->NameL();
       
  1371 	        }
       
  1372 	    }
       
  1373 
       
  1374     // if download is DRM-protected content with Preview-only rights
       
  1375     // then we cannot move content, but will launch it from the temp file
       
  1376     // that it is currently in.  For all other errors we leave.
       
  1377     if( installErr == KDRMErrPreviewRights )
       
  1378         {
       
  1379         iDrmPreviewOnly = ETrue;
       
  1380         }
       
  1381     else
       
  1382         {
       
  1383         User::LeaveIfError( installErr );
       
  1384         }
       
  1385     SetActive();
       
  1386     iState = EInstall;
       
  1387     CLOG(( ECodEng, 4, _L("<- CCodEngBase::StartInstallL") ));
       
  1388     }
       
  1389 
       
  1390 // ---------------------------------------------------------
       
  1391 // CCodEngBase::StartInstallRoapL()
       
  1392 // ---------------------------------------------------------
       
  1393 //
       
  1394 void CCodEngBase::StartInstallRoapL()
       
  1395     {
       
  1396     CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartInstallRoapL iStatusCode(%d)"), \
       
  1397         iStatusCode ));
       
  1398     __ASSERT_DEBUG( iState == EStartInstallRoap, CodPanic( ECodInternal ) );
       
  1399 //TODO check if we have a retry the iSaver could be NULL ?
       
  1400     if (iSaver)
       
  1401 	{
       
  1402 	iSaver->InstallL( &iStatus, (*iData)[iData->ActiveDownload()]->Name(), ETrue );
       
  1403 	}
       
  1404     // Synchronous state change - we are already under RunL().
       
  1405     iState = EInstallRoap;
       
  1406     SetActive();
       
  1407 
       
  1408     CLOG(( ECodEng, 4, _L("<- CCodEngBase::StartInstallRoapL") ));
       
  1409     }
       
  1410 
       
  1411 // ---------------------------------------------------------
       
  1412 // CCodEngBase::EndInstallRoapL()
       
  1413 // ---------------------------------------------------------
       
  1414 //
       
  1415 void CCodEngBase::EndInstallRoapL()
       
  1416     {
       
  1417     CLOG(( ECodEng, 2, _L("-> CCodEngBase::InstallRoapL iStatusCode(%d)"), \
       
  1418         iStatusCode ));
       
  1419 
       
  1420     User::LeaveIfError( iStatus.Int() );        // Handle errors in RunError().
       
  1421 //TODO: make sure that 956 and 900 sent
       
  1422     iStatusCode = KHttp956LicenseSuccess;
       
  1423     iResult = KErrNone;
       
  1424 //	iSaver->CloseStore();
       
  1425 	iState = EStartConnect;
       
  1426 	StartConnectL();
       
  1427     CLOG(( ECodEng, 4, _L("<- CCodEngBase::EndInstallRoapL") ));
       
  1428     }
       
  1429 
       
  1430 // ---------------------------------------------------------
       
  1431 // CCodEngBase::EndInstallL()
       
  1432 // ---------------------------------------------------------
       
  1433 //
       
  1434 void CCodEngBase::EndInstallL()
       
  1435     {
       
  1436     CLOG(( ECodEng, 2, _L("-> CCodEngBase::EndInstallL iStatus(%d)"), \
       
  1437         iStatus.Int() ));
       
  1438     __ASSERT_DEBUG( iState == EInstall, CodPanic( ECodInternal ) );
       
  1439 
       
  1440     User::LeaveIfError( iStatus.Int() );    // Handle errors in RunError().
       
  1441     // Synchronous state change - we are already under RunL().
       
  1442     iState = EStartNotify;
       
  1443     StartNotifyL();
       
  1444     CLOG(( ECodEng, 4, _L("<- CCodEngBase::EndInstallL") ));
       
  1445     }
       
  1446     
       
  1447 // ---------------------------------------------------------
       
  1448 // CCodEngBase::StartNotifyL
       
  1449 // ---------------------------------------------------------
       
  1450 //
       
  1451 void CCodEngBase::StartNotifyL()
       
  1452     {
       
  1453     __ASSERT_DEBUG( iState == EStartNotify, CodPanic( ECodInternal ) );
       
  1454 
       
  1455     if ( iData && iData->Count() > 0 && iData->ActiveDownload() && (*iData)[iData->ActiveDownload()]->InstallNotify().Length() )
       
  1456         {
       
  1457 	    CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartNotifyL iStatusCode(%d)"), \
       
  1458 	        iStatusCode ));
       
  1459 
       
  1460         CLOG(( ECodEng, 4, _L("CCodEngBase::StartNotifyL: init request") ));
       
  1461         if ( !iProgress )
       
  1462             {
       
  1463             // Setup notify-only progress.
       
  1464             iProgress = new (ELeave) TCodProgress( iObserver );
       
  1465             iProgress->Setup( 0, KCodNotifyTraffic );    
       
  1466             }
       
  1467         iProgress->StartPhaseL( TCodProgress::ENotify );
       
  1468         TBool notifyObserver = EFalse;
       
  1469         // When notifying after fetch, we already have a loader (and the
       
  1470         // observer has already been notified about load).
       
  1471         // When notifying without fetch, we don't have a loader yet (and the
       
  1472         // observer has not been notified about load yet).
       
  1473         if ( !iConn )
       
  1474             {
       
  1475             iConn = CConnection::NewL();
       
  1476             }
       
  1477         // For notify, attach only (do no create new connection).
       
  1478         iConn->AttachL( iPreferredIap );
       
  1479         if( !iLoader )
       
  1480             {
       
  1481             iLoader = CHttpLoader::NewL( *iConn, NULL, iProgress ,this );
       
  1482             notifyObserver = ETrue;
       
  1483             }
       
  1484         HBufC8* url = CodUtil::AbsoluteUrlLC
       
  1485             ( (*iData)[iData->ActiveDownload()]->SourceUri(), (*iData)[iData->ActiveDownload()]->InstallNotify() );
       
  1486         iLoader->NotifyL( *url, StatusText( iStatusCode ), &iStatus );
       
  1487         CleanupStack::PopAndDestroy( url );
       
  1488         iState = ENotify;
       
  1489         SetActive();
       
  1490         if ( iObserver && notifyObserver )
       
  1491             {
       
  1492             if ( iStatusCode == KHttp902UserCancelled ||
       
  1493                  iStatusCode == KHttp921UserAborted )
       
  1494                 {
       
  1495                 CLOG(( ECodEng, 3, \
       
  1496                     _L("-> CCodEngBase::StartNotifyL notify StartCancelL") ));
       
  1497                 iObserver->StartCancelL();
       
  1498                 iNotificationStatus = ECancel;
       
  1499                 }
       
  1500             else
       
  1501                 {
       
  1502                 CLOG(( ECodEng, 3, \
       
  1503                     _L("-> CCodEngBase::StartNotifyL notify StartLoadL(%d)"), \
       
  1504                     iStatusCode ));
       
  1505                 iObserver->StartLoadL( iStatusCode );
       
  1506                 iNotificationStatus = ELoad;
       
  1507                 }
       
  1508             }
       
  1509         }
       
  1510     else
       
  1511         {
       
  1512         // No install notify attribute, regarded as successful notification.
       
  1513         CLOG(( ECodEng, 4, _L("CCodEngBase::StartNotifyL: nothing to do") ));
       
  1514         Continue( ENotify );
       
  1515         }
       
  1516     CLOG(( ECodEng, 2, _L("<- CCodEngBase::StartNotifyL") ));
       
  1517     }
       
  1518 
       
  1519 // ---------------------------------------------------------
       
  1520 // CCodEngBase::EndNotifyL
       
  1521 // ---------------------------------------------------------
       
  1522 //
       
  1523 void CCodEngBase::EndNotifyL()
       
  1524     {
       
  1525     CLOG(( ECodEng, 2, _L("-> CCodEngBase::EndNotifyL iStatus(%d)"), \
       
  1526         iStatus.Int() ));
       
  1527     __ASSERT_DEBUG( iState == ENotify, CodPanic( ECodInternal ) );
       
  1528 
       
  1529     delete iLoader;
       
  1530     iLoader = NULL;
       
  1531     delete iConn;
       
  1532     iConn = NULL;
       
  1533 
       
  1534     User::LeaveIfError( iStatus.Int() );    // Handle errors in RunError().
       
  1535 
       
  1536     // Do not leave after this point! Notify was successful, we must keep
       
  1537     // downloaded content now.
       
  1538     
       
  1539     if ( iProgress )
       
  1540         {
       
  1541         TRAP_IGNORE( iProgress->DoneL() );
       
  1542         delete iProgress;
       
  1543         iProgress = NULL;
       
  1544         }
       
  1545 
       
  1546     if( iSaver && iResult == KErrNone )
       
  1547         {
       
  1548 //TODO: check if in case of PD we should release. It is already done.
       
  1549         iSaver->ReleaseContent( (*iData)[iData->ActiveDownload()]->iFileName, iHandler );
       
  1550 
       
  1551         if ((!(*iData)[iData->ActiveDownload()]->iFullName) || (!((*iData)[iData->ActiveDownload()]->iFullName->Compare(KNullDesC))))
       
  1552             {
       
  1553             delete (*iData)[iData->ActiveDownload()]->iFullName;
       
  1554             (*iData)[iData->ActiveDownload()]->iFullName = (*iData)[iData->ActiveDownload()]->iFileName.AllocL();
       
  1555             }
       
  1556         
       
  1557         iType = iSaver->DataType();
       
  1558         }
       
  1559 
       
  1560     //Done();
       
  1561     Continue ( EMediaChange );
       
  1562     CLOG(( ECodEng, 2, _L("<- CCodEngBase::EndNotifyL") ));
       
  1563     }
       
  1564 
       
  1565 // ---------------------------------------------------------
       
  1566 // CCodEngBase::Done
       
  1567 // ---------------------------------------------------------
       
  1568 //
       
  1569 void CCodEngBase::Done()
       
  1570     {
       
  1571     CLOG(( ECodEng, 2, _L("-> CCodEngBase::Done iResult(%d)"), iResult ));
       
  1572 
       
  1573     if( iSaver )
       
  1574         {
       
  1575         iSaver->Cleanup( !(*iData)[iData->ActiveDownload()]->iPausable );
       
  1576         }
       
  1577 
       
  1578     delete iSaver;  // Cleans up unless Release()-d.
       
  1579     iSaver = NULL;	
       
  1580     delete iLoader;
       
  1581     iLoader = NULL;
       
  1582     delete iConn;
       
  1583     iConn = NULL;
       
  1584     delete iCodBuf;
       
  1585     iCodBuf = NULL;
       
  1586     delete iProgress;
       
  1587     iProgress = NULL;
       
  1588 
       
  1589     if( iObserver )
       
  1590         {
       
  1591         CLOG(( ECodEng, 3, \
       
  1592             _L("CCodEngBase::Done notify Done code(%d) err(%d)"), \
       
  1593             iStatusCode, iResult ));
       
  1594         iObserver->Done( iStatusCode, iResult );
       
  1595         iNotificationStatus = ENull;
       
  1596         }
       
  1597 
       
  1598     // Reinit state.
       
  1599     iState = iData->IsValid() ? EReady : EInit;
       
  1600     // Notify parent.
       
  1601     __ASSERT_DEBUG( iParentStatus, CodPanic( ECodInternal ) );
       
  1602     User::RequestComplete( iParentStatus, iResult );
       
  1603     iParentStatus = NULL;
       
  1604     CLOG(( ECodEng, 2, _L("<- CCodEngBase::Done") ));
       
  1605     }
       
  1606 
       
  1607 // ---------------------------------------------------------
       
  1608 // CCodEngBase::DoneDD2
       
  1609 // ---------------------------------------------------------
       
  1610 //
       
  1611 void CCodEngBase::DoneDD2()
       
  1612     {
       
  1613     CLOG(( ECodEng, 2, _L("-> CCodEngBase::Done iResult(%d)"), iResult ));
       
  1614     delete iLoader;
       
  1615     iLoader = NULL;
       
  1616     delete iConn;
       
  1617     iConn = NULL;
       
  1618     delete iCodBuf;
       
  1619     iCodBuf = NULL;
       
  1620     delete iProgress;
       
  1621     iProgress = NULL;
       
  1622 
       
  1623     if( iObserver )
       
  1624         {
       
  1625         CLOG(( ECodEng, 3, \
       
  1626             _L("CCodEngBase::Done notify Done code(%d) err(%d)"), \
       
  1627             iStatusCode, iResult ));
       
  1628         iObserver->Done( iStatusCode, iResult );
       
  1629         iNotificationStatus = ENull;
       
  1630         }
       
  1631 
       
  1632     // Reinit state.
       
  1633     iState = iData->IsValid() ? EReady : EInit;
       
  1634     // Notify parent.
       
  1635     __ASSERT_DEBUG( iParentStatus, CodPanic( ECodInternal ) );
       
  1636     User::RequestComplete( iParentStatus, iResult );
       
  1637     iParentStatus = NULL;
       
  1638     CLOG(( ECodEng, 2, _L("<- CCodEngBase::Done") ));
       
  1639     }
       
  1640 
       
  1641 // ---------------------------------------------------------
       
  1642 // CCodEngBase::Continue
       
  1643 // ---------------------------------------------------------
       
  1644 //
       
  1645 void CCodEngBase::Continue( TState aNextState )
       
  1646     {
       
  1647     CLOG(( ECodEng, 2, _L("-> CCodEngBase::Continue nextState(%d)"), \
       
  1648         aNextState ));
       
  1649     __ASSERT_DEBUG( !IsActive(), CodPanic( ECodInternal ) );
       
  1650 
       
  1651     iState = aNextState;
       
  1652     TRequestStatus* ownStatus = &iStatus;
       
  1653     *ownStatus = KRequestPending;
       
  1654     SetActive();
       
  1655     User::RequestComplete( ownStatus, KErrNone );
       
  1656     CLOG(( ECodEng, 2, _L("<- CCodEngBase::Continue") ));
       
  1657     }
       
  1658 
       
  1659 // ---------------------------------------------------------
       
  1660 // CCodEngBase::SelfComplete
       
  1661 // ---------------------------------------------------------
       
  1662 //
       
  1663 void CCodEngBase::SelfComplete( TInt aError )
       
  1664     {
       
  1665     // This method safely handles the case when a request may be completed
       
  1666     // multiple times.
       
  1667     // The main use is for content viewing (EContentView state), where
       
  1668     // there is no real external request made and the request can complete
       
  1669     // the following ways:
       
  1670     // - Embedded viewer exits and calls NotifyExit()
       
  1671     // - CodEng is Cancelled (e.g. deleted, if Exit is issued inside the
       
  1672     //   embedded viewer.
       
  1673     CLOG(( ECodEng, 2, _L("CCodEngBase::SelfComplete(%d)"), aError ));
       
  1674     if ( iStatus == KRequestPending )
       
  1675         {
       
  1676         // Request is pending, complete now.
       
  1677         CLOG(( ECodEng, 4, _L("  completing now") ));
       
  1678         TRequestStatus* ownStatus = &iStatus;
       
  1679         User::RequestComplete( ownStatus, aError );
       
  1680         }
       
  1681     else
       
  1682         {
       
  1683         // Request already completed.
       
  1684         // - If this second completion is error, override status.
       
  1685         // - If this second completion is success, don't override - existing
       
  1686         //   result may be error and we can't undo that.
       
  1687         CLOG(( ECodEng, 4, _L("  already completed") ));
       
  1688         if ( aError != KErrNone )
       
  1689             {
       
  1690             iStatus = aError;
       
  1691             }
       
  1692         }
       
  1693     }
       
  1694 
       
  1695 // ---------------------------------------------------------
       
  1696 // CCodEngBase::CapabilityCheckL
       
  1697 // ---------------------------------------------------------
       
  1698 //
       
  1699 void CCodEngBase::CapabilityCheckL()
       
  1700     {
       
  1701     CLOG(( ECodEng, 2, _L("-> CCodEngBase::CapabilityCheckL") ));
       
  1702     __ASSERT_DEBUG( iData->ActiveDownload(),CodPanic( ECodInternal ));
       
  1703     // 1. Data type checking.
       
  1704     TInt typeErr( KErrNone );    
       
  1705 #ifdef __SYNCML_DM_FOTA
       
  1706     TBool fota( EFalse );
       
  1707 #endif /*def __SYNCML_DM_FOTA */
       
  1708     for ( TInt i = 0; i < (*iData)[iData->ActiveDownload()]->Types().MdcaCount() && !iContentTypeCheck; i++ )
       
  1709         {
       
  1710         const TDataType& type( (*iData)[iData->ActiveDownload()]->Types().MdcaPoint( i ) );
       
  1711 #ifdef __TEST_COD_LOG
       
  1712         TPtrC8 mime( type.Des8() );
       
  1713 #endif /* def __TEST_COD_LOG */
       
  1714 
       
  1715         if (
       
  1716             type == TDataType( KOma1XmlRoContentType ) ||
       
  1717             type == TDataType( KOma1WbxmlRoContentType )
       
  1718            )
       
  1719             {
       
  1720             // DRM related types which are not proper files (not saved to FS).
       
  1721             CLOG(( ECodEng, 4, _L8("  <%S> DRM1 rights OK"), &mime ));
       
  1722             iIsDd2 = EFalse;
       
  1723             }
       
  1724         else if ( type == TDataType( KOma1DrmMessageContentType ) )
       
  1725             {
       
  1726             // Accept DRM message. The system supports it but
       
  1727             // DocHandler does not report this.
       
  1728             CLOG(( ECodEng, 4, _L8("  <%S> DRM1 msg OK"), &mime ));
       
  1729             iFsUsed = ETrue;
       
  1730             }
       
  1731 #ifdef __DRM_OMA2
       
  1732         else if (
       
  1733             type == TDataType( KOma2RoContentType ) ||
       
  1734             type == TDataType( KOma2ProtectedRoType ) ||
       
  1735             type == TDataType( KOma2TriggerContentType )
       
  1736            )
       
  1737             {
       
  1738             // DRM related types which are not proper files (not saved to FS).
       
  1739             CLOG(( ECodEng, 4, _L8("  <%S> DRM2 rights OK"), &mime ));
       
  1740             iIsDd2 = EFalse;            
       
  1741             }
       
  1742 #endif /*def __DRM_OMA2*/
       
  1743 #ifdef __SYNCML_DM_FOTA
       
  1744         else if ( type == TDataType( KFotaPackageDataType ) )
       
  1745             {
       
  1746             // Accept FOTA download. Special storage (not saved to FS).
       
  1747             CLOG(( ECodEng, 4, _L8("  <%S> FOTA OK"), &mime ));
       
  1748             fota = ETrue;
       
  1749             }
       
  1750 #endif /*def __SYNCML_DM_FOTA */
       
  1751         else 
       
  1752             {
       
  1753             CLOG(( ECodEng, 4, _L8("  <%S> DocHandler check"), &mime ));
       
  1754             iFsUsed = ETrue;
       
  1755             
       
  1756             if ( !iResumedDownload )
       
  1757                 {
       
  1758                 TRAP( typeErr, iDocHandler->CanOpenL( type ));
       
  1759                 if (typeErr == KMimeNotSupported)
       
  1760                     {
       
  1761                     CAknQueryDialog* dialog = CAknQueryDialog::NewL();
       
  1762                     dialog->PrepareLC(R_COD_UI_CONFIRM_NOTE);
       
  1763                     HBufC* prompt;
       
  1764                     prompt = StringLoader::LoadLC(R_QTN_BROWSER_DOWNLOADS_UNSUPPORTED_CONTENT_QUERY);
       
  1765                     dialog->SetPromptL(*prompt);  
       
  1766                     CleanupStack::PopAndDestroy( prompt );
       
  1767                     if(!dialog->RunLD())
       
  1768                         {
       
  1769                         User::Leave( KHttp902UserCancelled );
       
  1770                         }
       
  1771                     }
       
  1772                 }
       
  1773             }
       
  1774         }
       
  1775 
       
  1776     // 2. Storage space checking. (Depends on data types.)
       
  1777    
       
  1778     TInt size = (*iData)[iData->ActiveDownload()]->Size() - (*iData)[iData->ActiveDownload()]->DownloadedSize();
       
  1779     TInt bytesToWrite = size;
       
  1780     if (bytesToWrite < 0)
       
  1781         bytesToWrite = 0;
       
  1782 
       
  1783     if ( iFsUsed )
       
  1784         {
       
  1785         CLOG(( ECodEng, 2, _L("  FS check (%d)"), size ));
       
  1786 #ifdef RD_MULTIPLE_DRIVE 
       
  1787         TInt err( KErrNone );
       
  1788         iSpaceAvailOk = EFalse;
       
  1789         User::LeaveIfError(
       
  1790                 DriveInfo::GetDefaultDrive( DriveInfo::EDefaultPhoneMemory, iAvailDriveSpace ) );
       
  1791 
       
  1792         HBufC8* drivesDynList = QueryDynDriveListLC();
       
  1793         TPtrC8 drives( *drivesDynList );
       
  1794         
       
  1795         // drive letters are separated by semicolons
       
  1796         for( TInt i = 0; i < drives.Length() && (err || !iSpaceAvailOk); i = i + 2 )
       
  1797             {
       
  1798             if( (err = iFs.CharToDrive( drives[i], iAvailDriveSpace )) == KErrNone )
       
  1799                 {
       
  1800                 // Check if there's enough memory in the phone
       
  1801         	    TRAP( err, iSpaceAvailOk = !SysUtil::DiskSpaceBelowCriticalLevelL(
       
  1802                                                         &iFs,
       
  1803         			                                    bytesToWrite,
       
  1804                                                         iAvailDriveSpace ));
       
  1805                 }
       
  1806             else
       
  1807                 {
       
  1808                 CLOG(( ECodEng, 4, _L("Bad drive letter [%c]"), drives[i] ));
       
  1809                 }            
       
  1810             }
       
  1811         CleanupStack::PopAndDestroy( drivesDynList );
       
  1812 
       
  1813         if( err || !iSpaceAvailOk )
       
  1814             {
       
  1815             User::Leave( KErrCodInsufficientSpace );
       
  1816             }
       
  1817 #else
       
  1818         iPhoneMemoryOk = EFalse;
       
  1819         iMmcOk = EFalse;
       
  1820         // Check C:
       
  1821         iPhoneMemoryOk = !SysUtil::FFSSpaceBelowCriticalLevelL( &iFs, bytesToWrite );
       
  1822         CLOG(( ECodEng, 4, _L("  iPhoneMemoryOk(%d)"), iPhoneMemoryOk ));
       
  1823         RFeatMgr featMgr;
       
  1824         featMgr.OpenL();
       
  1825         CleanupClosePushL<RFeatMgr>( featMgr );
       
  1826         if ( featMgr.FeatureSupported( KFeatureIdMmc ) )
       
  1827             {
       
  1828             // If no MMC is inserted, this will leave (and not set iMmcOk).
       
  1829             TRAP_IGNORE( iMmcOk = !SysUtil::MMCSpaceBelowCriticalLevelL
       
  1830                 ( &iFs, bytesToWrite ); )
       
  1831             }
       
  1832         CleanupStack::PopAndDestroy();  // featMgr
       
  1833         CLOG(( ECodEng, 4, _L("  iMmcOk(%d)"), iMmcOk ));
       
  1834         if( !(iPhoneMemoryOk || iMmcOk) )
       
  1835             {
       
  1836             User::Leave( KErrCodInsufficientSpace );
       
  1837             }
       
  1838 #endif
       
  1839         }
       
  1840 
       
  1841 #ifdef __SYNCML_DM_FOTA
       
  1842     if ( fota )
       
  1843         {
       
  1844         // Transient FOTA session is used to check store space -> waste.
       
  1845         // Pre-allocate FOTA saver to avoid this (??) makes the saver's
       
  1846         // lifespan hard to follow, error-prone. TODO (??)
       
  1847         CLOG(( ECodEng, 2, _L("  FOTA check (%d)"), size ));
       
  1848         RFotaEngineSession fotaEng;
       
  1849         CleanupClosePushL<RFotaEngineSession>( fotaEng );
       
  1850         fotaEng.OpenL();
       
  1851         if ( !fotaEng.IsPackageStoreSizeAvailable( size ) )
       
  1852             {
       
  1853             User::Leave( KErrCodInsufficientSpace );
       
  1854             }
       
  1855         CleanupStack::PopAndDestroy( &fotaEng );
       
  1856         }
       
  1857 #endif /*def __SYNCML_DM_FOTA */
       
  1858 
       
  1859 	//When reached here, it is assured that capability check is done successfully
       
  1860 	//for the active download.
       
  1861 	//Content type check is done for this track
       
  1862 	iContentTypeCheck = ETrue;
       
  1863 	
       
  1864     CLOG(( ECodEng, 2, _L("<- CCodEngBase::CapabilityCheckL") ));
       
  1865     }
       
  1866 
       
  1867 // ---------------------------------------------------------
       
  1868 // CCodEngBase::CreateSaverL
       
  1869 // ---------------------------------------------------------
       
  1870 //
       
  1871 CCodSaver* CCodEngBase::CreateSaverL( const TDesC8& aType )
       
  1872     {
       
  1873     CLOG(( ECodEng, 2, _L8("-> CCodEngBase::CreateSaverL <%S>"), &aType ));
       
  1874 //TODO:    __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
       
  1875     // TODO check attribute match (early reject mismatched or unsupported types)!
       
  1876 
       
  1877     if( aType == KNullDesC8 )
       
  1878     	{
       
  1879     	return NULL;
       
  1880     	}
       
  1881     
       
  1882 // DD1 and DD2 cases
       
  1883     if (( aType.Find( KOma2TriggerContentType ) != KErrNotFound) || ( aType.Find( KDd2DataType ) != KErrNotFound )|| ( aType.Find( KOma1WbxmlRoContentType ) != KErrNotFound ))
       
  1884         {
       
  1885         iSaver = CRoapSaver::NewL( aType, iRoapData, iProgress, KRoapProgressMax, (*iData)[iData->ActiveDownload()]->iTempPath, (*iData)[iData->ActiveDownload()]->iRootPath, KNullDesC());
       
  1886         iSaver->SetObserver( iObserver );
       
  1887         iSaver->SetParams( iParams );
       
  1888         iSaver->SetMaxSize( iData->Size() );
       
  1889         iSaver->OpenStoreL();   // TODO unneeded method, put to construction.
       
  1890         }
       
  1891 #ifdef __SYNCML_DM_FOTA
       
  1892     else if ( aType.Find( KFotaPackageDataType ) != KErrNotFound  )
       
  1893         {
       
  1894         TInt pkgId( KCodDefaultFotaPkgId );
       
  1895         if ( iParams )
       
  1896             {
       
  1897             CodUtil::GetIntParam( pkgId, EGenericParamFotaPkgId, *iParams );
       
  1898             }
       
  1899         iSaver = CFotaSaver::NewL( aType, pkgId );
       
  1900         iSaver->SetObserver( iObserver );
       
  1901         iSaver->SetParams( iParams );
       
  1902         iSaver->SetMaxSize( iData->Size() );
       
  1903         iSaver->OpenStoreL();   // TODO unneeded method, put to construction.
       
  1904         }
       
  1905 #endif /*def __SYNCML_DM_FOTA */
       
  1906     else
       
  1907         {
       
  1908         // TODO the assert below crashes without early reject!
       
  1909         //__ASSERT_DEBUG( iFsUsed, CodPanic( ECodInternal ) );
       
  1910 
       
  1911         TBool contentTypeMisMatch ( ETrue );
       
  1912         for ( TInt i = 0; i < (*iData)[iData->ActiveDownload()]->Types().MdcaCount(); i++ )
       
  1913             {
       
  1914             const TDataType& type( (*iData)[iData->ActiveDownload()]->Types().MdcaPoint( i ) );
       
  1915             if( ( aType.Find (type.Des8()) != KErrNotFound ) || 
       
  1916                             ( (type.Des8().Find(KOma1DrmMessageContentType)!= KErrNotFound) && (aType.Find(KOma1DcfContentType)!= KErrNotFound )  ))             
       
  1917                 {
       
  1918                 contentTypeMisMatch = EFalse;
       
  1919                 break;
       
  1920                 }                
       
  1921             }
       
  1922         if(contentTypeMisMatch)
       
  1923             {
       
  1924             User::Leave(KErrCodAttributeMismatch);
       
  1925             }
       
  1926         
       
  1927         // Do this only if Unique filename check has never been performed earlier for this file.
       
  1928         if (( !(*iData)[iData->ActiveDownload()]->IsUniqueFilenameSet() ))
       
  1929             {
       
  1930             // Append an index to filename in case file with same name already exists
       
  1931             SetUniqueFileNameL();
       
  1932             (*iData)[iData->ActiveDownload()]->UniqueFilenameSet( ETrue );
       
  1933             
       
  1934             CArrayPtrFlat<CHeaderField>* headers = NULL;
       
  1935             if (iLoader)
       
  1936             	headers = iLoader->ResponseHeaders();
       
  1937             
       
  1938             // Store in Sub-Info File
       
  1939             StoreSubInfoFileL( headers, iData->ActiveDownload() );
       
  1940             // Name changed. Inform server.
       
  1941             iObserver->MediaObjectNameChanged();
       
  1942             }
       
  1943         
       
  1944         if (iIsDd2)
       
  1945 		    {
       
  1946             iSaver = CFileSaver::NewL( ((*iData)[iData->ActiveDownload()]->Types().MdcaPoint( 0)), iFs, *iDocHandler, (*iData)[iData->ActiveDownload()]->iTempPath, (*iData)[iData->ActiveDownload()]->iRootPath, (*iData)[iData->ActiveDownload()]->iFullName->Des());
       
  1947 		    }
       
  1948         else
       
  1949 		    {
       
  1950             iSaver = CFileSaver::NewL( aType, iFs, *iDocHandler, (*iData)[iData->ActiveDownload()]->iTempPath, (*iData)[iData->ActiveDownload()]->iRootPath, (*iData)[iData->ActiveDownload()]->iFullName->Des());
       
  1951 		    }
       
  1952         iSaver->SetObserver( iObserver );
       
  1953         iSaver->SetParams( iParams );
       
  1954         iSaver->SetMaxSize( iData->Size() );
       
  1955         iSaver->OpenStoreL();   // TODO unneeded method, put to construction.
       
  1956 		iSaver->ReleaseFileName( (*iData)[iData->ActiveDownload()]->iFileName);
       
  1957 		//send message that PDL is available. The DlMgrUiLib will have a "Play" option available
       
  1958         /*
       
  1959         OMA 2:
       
  1960         If the Media Object of the Product containing the Media Object has a license element, 
       
  1961         the Download Agent MUST NOT make the Media Object(s) available for rendering before 
       
  1962         the License has been successfully installed..
       
  1963         Only the order tag equals to any allows to install the License element first.
       
  1964         */
       
  1965           if ((iIsDd2 && iObserver && iData && (*iData)[iData->ActiveDownload()]->ProgressiveDownload() && !iIsLicense) || 
       
  1966              (iIsDd2 && iObserver && iData && (*iData)[iData->ActiveDownload()]->ProgressiveDownload() &&  iIsLicense && !iData->IsPostOrder()))
       
  1967 		  {
       
  1968           iSaver->ReleaseFileName( (*iData)[iData->ActiveDownload()]->iFileName);
       
  1969           iObserver->PdPlayAvailable();
       
  1970 		  }
       
  1971         }
       
  1972 
       
  1973     CLOG(( ECodEng, 2, _L("<- CCodEngBase::CreateSaverL") ));
       
  1974     return iSaver;
       
  1975     }
       
  1976 
       
  1977 // ---------------------------------------------------------
       
  1978 // CCodEngBase::SetPathsL
       
  1979 // ---------------------------------------------------------
       
  1980 //
       
  1981 void CCodEngBase::SetPathsL()
       
  1982     {
       
  1983     CLOG(( ECodEng, 2, _L("-> CCodEngBase::SetPathsL") ));
       
  1984 #ifdef RD_MULTIPLE_DRIVE 
       
  1985     __ASSERT_DEBUG( iSpaceAvailOk, CodPanic( ECodInternal ) );
       
  1986 #else
       
  1987     __ASSERT_DEBUG( iPhoneMemoryOk || iMmcOk, CodPanic( ECodInternal ) );
       
  1988     __ASSERT_DEBUG( iFsUsed, CodPanic( ECodInternal ) );
       
  1989 #endif
       
  1990     (*iData)[iData->ActiveDownload()]->iTempPath = KNullDesC;
       
  1991     (*iData)[iData->ActiveDownload()]->iRootPath = KNullDesC;
       
  1992 #ifdef RD_MULTIPLE_DRIVE 
       
  1993     if ( iSpaceAvailOk )
       
  1994         {
       
  1995         User::LeaveIfError( PathInfo::GetRootPath( (*iData)[iData->ActiveDownload()]->iRootPath, iAvailDriveSpace ) );
       
  1996         }
       
  1997 #else    
       
  1998     if ( iPhoneMemoryOk && iMmcOk && iObserver ) 
       
  1999         {
       
  2000         iObserver->GetRootPathL( (*iData)[iData->ActiveDownload()]->iRootPath );
       
  2001         if(!(*iData)[iData->ActiveDownload()]->iRootPath.Compare(_L("C:\\")))
       
  2002             {
       
  2003                 (*iData)[iData->ActiveDownload()]->iRootPath = PathInfo::PhoneMemoryRootPath();
       
  2004                 
       
  2005             }
       
  2006         }
       
  2007     else if ( iPhoneMemoryOk )
       
  2008         {
       
  2009         (*iData)[iData->ActiveDownload()]->iRootPath = PathInfo::PhoneMemoryRootPath();
       
  2010         }
       
  2011     else
       
  2012         {
       
  2013         __ASSERT_DEBUG( iMmcOk, CodPanic( ECodInternal ) );
       
  2014         (*iData)[iData->ActiveDownload()]->iRootPath = PathInfo::MemoryCardRootPath();
       
  2015         }
       
  2016 #endif
       
  2017 
       
  2018  	TParsePtrC rootPath( (*iData)[iData->ActiveDownload()]->iRootPath );
       
  2019  	TBuf<KMaxPath> tempBuf;
       
  2020  	// Set temp path to the same drive.
       
  2021     tempBuf.Format( KDownloadFolderFormat, 
       
  2022                     &KCodDefaultTempDir, 
       
  2023                     iAppUId,
       
  2024                     &KTempFilesCodDirName );      
       
  2025 
       
  2026     (*iData)[iData->ActiveDownload()]->iTempPath.Append(rootPath.Drive());
       
  2027     (*iData)[iData->ActiveDownload()]->iTempPath.Append(tempBuf);
       
  2028 
       
  2029     TDriveInfo info;
       
  2030     TDriveUnit unit( rootPath.Drive() );
       
  2031     User::LeaveIfError( iFs.Drive( info, unit ) );
       
  2032     // Create the temp directory earlier in case it's not created yet
       
  2033     iFs.MkDirAll( (*iData)[iData->ActiveDownload()]->iTempPath ); 
       
  2034     if ( info.iDriveAtt & KDriveAttRemovable )
       
  2035         {
       
  2036         iRemovableMedia = ETrue;
       
  2037         }
       
  2038         
       
  2039     CLOG(( ECodEng, 2, _L("<- CCodEngBase::SetPathsL root<%S> temp<%S>"), \
       
  2040         &(*iData)[iData->ActiveDownload()]->iRootPath, &(*iData)[iData->ActiveDownload()]->iTempPath ));
       
  2041     }
       
  2042 
       
  2043 // ---------------------------------------------------------
       
  2044 // CCodEngBase::ResetPaths
       
  2045 // ---------------------------------------------------------
       
  2046 //
       
  2047 void CCodEngBase::ResetPaths()
       
  2048     {
       
  2049     iFsUsed = EFalse;
       
  2050 #ifdef RD_MULTIPLE_DRIVE 
       
  2051     iSpaceAvailOk = EFalse;
       
  2052     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultPhoneMemory, iAvailDriveSpace );
       
  2053 #else
       
  2054     iPhoneMemoryOk = EFalse;
       
  2055     iMmcOk = EFalse;
       
  2056 #endif
       
  2057     //(*iData)[iData->ActiveDownload()]->iTempPath = KNullDesC;
       
  2058     //(*iData)[iData->ActiveDownload()]->iRootPath = KNullDesC;
       
  2059     iRemovableMedia = EFalse;
       
  2060     }
       
  2061 
       
  2062 #ifdef RD_MULTIPLE_DRIVE
       
  2063 //------------------------------------------------------------------------
       
  2064 //CCodEngBase::QueryDynDriveListLC
       
  2065 //------------------------------------------------------------------------
       
  2066 HBufC8* CCodEngBase::QueryDynDriveListLC()
       
  2067     {
       
  2068     TDriveList driveList;
       
  2069     TInt driveCount( 0 );
       
  2070     TChar driveLetter;
       
  2071     TBuf8<KMaxDriveListStrLen> driveLettersDyn;
       
  2072 
       
  2073     // Checking validity of drives in Cenrep List
       
  2074     // drive letters are separated by semicolons
       
  2075     // Destination is FFS in default
       
  2076     TInt drive;
       
  2077     User::LeaveIfError(
       
  2078         DriveInfo::GetDefaultDrive( DriveInfo::EDefaultPhoneMemory, drive ) );
       
  2079 
       
  2080     for( TInt i = 0; i < iDriveLettersCenRep.Length(); i = i + 2 )
       
  2081         {
       
  2082         if( iFs.CharToDrive( iDriveLettersCenRep[i], drive ) == KErrNone )
       
  2083             {
       
  2084             TUint status;
       
  2085             if ( DriveInfo::GetDriveStatus( iFs, drive, status ) == KErrNone )
       
  2086                 {
       
  2087                 if ( ( status & ( DriveInfo::EDriveUserVisible | DriveInfo::EDrivePresent ) ) )
       
  2088                     {
       
  2089                     CLOG(( ECodEng, 0, _L("-> CCodEngBase::QueryDynDriveListLC Drive is present and visible")));
       
  2090                     }
       
  2091                 }
       
  2092             }
       
  2093         }
       
  2094 
       
  2095     // get the list of drives available in real time
       
  2096     if ( DriveInfo::GetUserVisibleDrives( iFs, driveList, driveCount ) == KErrNone )
       
  2097         {
       
  2098         if ( iDriveLettersCenRep.Length() > 0 )
       
  2099             {
       
  2100                 driveLettersDyn.Append( iDriveLettersCenRep );
       
  2101                 if ( driveLettersDyn[driveLettersDyn.Length() - 1] != ';' )
       
  2102                     {
       
  2103                     driveLettersDyn.Append( KDefaultDriveListSep );
       
  2104                     }
       
  2105             }
       
  2106         TInt count( driveList.Length() );
       
  2107         for ( TInt i( 0 ); i < count; ++i )
       
  2108             {
       
  2109             if ( driveList[ i ] )
       
  2110                 {
       
  2111                 User::LeaveIfError( iFs.DriveToChar( i, driveLetter) );
       
  2112                 TInt drivePos = driveLettersDyn.LocateF( driveLetter );
       
  2113                 if ( drivePos == KErrNotFound )
       
  2114                     {
       
  2115                     driveLettersDyn.Append( driveLetter ); 
       
  2116                     driveLettersDyn.Append( KDefaultDriveListSep ); 
       
  2117                     }
       
  2118                 }
       
  2119             }
       
  2120         CLOG(( ECodEng, 2, _L("<- CCodEngBase::QueryDynDriveListLC Pref. drive list dynamic: [%S]"), \
       
  2121                 &driveLettersDyn));
       
  2122         }
       
  2123 
       
  2124     HBufC8* driveLetters = HBufC8::NewLC( KMaxDriveListStrLen );
       
  2125     driveLetters->Des().Copy( driveLettersDyn );
       
  2126     return driveLetters;
       
  2127     }
       
  2128 
       
  2129 //------------------------------------------------------------------------
       
  2130 //CCodEngBase::QueryDriveList
       
  2131 //------------------------------------------------------------------------
       
  2132 void CCodEngBase::QueryDriveListL()
       
  2133     {
       
  2134     CRepository* repository = CRepository::NewLC( KCRUidBrowser );
       
  2135     
       
  2136     if( repository->Get(KBrowserDrivePrefListForDownloadedContent, iDriveLettersCenRep) != KErrNone )
       
  2137         {
       
  2138         CLOG(( ECodEng, 0, _L("-> CCodEngBase::QueryDriveListL Drive list not found")));
       
  2139         iDriveLettersCenRep.Copy( KDefaultDriveList );
       
  2140         }
       
  2141     CLOG(( ECodEng, 2, _L("<- CCodEngBase::QueryDriveListL Pref. drive list: [%S]"), \
       
  2142         &iDriveLettersCenRep));    
       
  2143     
       
  2144     CleanupStack::PopAndDestroy( repository );
       
  2145     }
       
  2146 
       
  2147 #endif
       
  2148 
       
  2149 //------------------------------------------------------------------------
       
  2150 //CCodEngBase::DownloadID
       
  2151 //------------------------------------------------------------------------
       
  2152 TUint32 CCodEngBase::DownloadID()
       
  2153 	{
       
  2154 	return iDownloadId;
       
  2155 	}
       
  2156 
       
  2157 //------------------------------------------------------------------------
       
  2158 //CCodEngBase::SetPausable
       
  2159 //------------------------------------------------------------------------
       
  2160 
       
  2161 void CCodEngBase::SetPausable(TBool aPausable)
       
  2162     {
       
  2163     (*iData)[iData->ActiveDownload()]->iPausable = aPausable;
       
  2164     if( iData->Count() > 1 && aPausable )
       
  2165     	{
       
  2166     	iObserver->UpdatePausable(aPausable);	
       
  2167     	}
       
  2168     else if(iData->Count()  ==  1)
       
  2169         {
       
  2170         iObserver->UpdatePausable(aPausable);
       
  2171         }	    	
       
  2172     }
       
  2173 
       
  2174 //------------------------------------------------------------------------
       
  2175 //CCodEngBase::SetResumePDAvailable
       
  2176 //------------------------------------------------------------------------
       
  2177 
       
  2178 void CCodEngBase::SetResumePDAvailable()
       
  2179 	{
       
  2180 	if(iData && iData->ActiveDownload() 
       
  2181 		     && iData->Count() 
       
  2182 			 && (*iData)[iData->ActiveDownload()]->ProgressiveDownload())
       
  2183 		{
       
  2184 		iObserver->DownloadResumedPdAvailable();	
       
  2185 		}
       
  2186 	}
       
  2187         
       
  2188 //------------------------------------------------------------------------
       
  2189 //CCodEngBase::StoreFilePathsL
       
  2190 //------------------------------------------------------------------------
       
  2191 void CCodEngBase::StoreFilePathsL(TPtr8& aBuf)
       
  2192 	{
       
  2193     HBufC* buf1 = (*iData)[iData->ActiveDownload()]->iTempPath.AllocLC();
       
  2194 	AppendBufL(aBuf,buf1);
       
  2195 	
       
  2196 	HBufC* buf2 = (*iData)[iData->ActiveDownload()]->iRootPath.AllocLC();
       
  2197 	AppendBufL(aBuf,buf2);
       
  2198 	
       
  2199 	CleanupStack::PopAndDestroy(2,buf1);
       
  2200 	AppendBufL(aBuf,(*iData)[iData->ActiveDownload()]->iFullName);
       
  2201 		
       
  2202 	}
       
  2203 
       
  2204 //------------------------------------------------------------------------
       
  2205 //CCodEngBase::LoadFilePathsL
       
  2206 //------------------------------------------------------------------------
       
  2207 void CCodEngBase::LoadFilePathsL(RFile& aInFile)
       
  2208 	{
       
  2209 	HBufC* buf1 = NULL;
       
  2210 	HBufC* buf2 = NULL;	
       
  2211 	ReadHBufCL(aInFile,buf1);
       
  2212 	(*iData)[iData->ActiveDownload()]->iTempPath = *buf1;
       
  2213 	
       
  2214 	ReadHBufCL(aInFile,buf2);
       
  2215 	
       
  2216 	(*iData)[iData->ActiveDownload()]->iRootPath = *buf2;
       
  2217 	
       
  2218 	ReadHBufCL(aInFile,(*iData)[iData->ActiveDownload()]->iFullName);
       
  2219 	delete buf1;
       
  2220 	delete buf2;
       
  2221 	}
       
  2222 
       
  2223 //------------------------------------------------------------------------
       
  2224 //CCodEngBase::Start()
       
  2225 //------------------------------------------------------------------------
       
  2226 // 
       
  2227 EXPORT_C void CCodEngBase::Start( const CAiwGenericParamList* aParams, TRequestStatus* aStatus ) 
       
  2228 	{
       
  2229 	iParentStatus = aStatus;
       
  2230 	*iParentStatus = KRequestPending;
       
  2231 	iParams = aParams;
       
  2232     // Get params from GenericParams.
       
  2233     if ( iParams )
       
  2234         {
       
  2235         CodUtil::GetUint32Param( iPreferredIap, EGenericParamAccessPoint, *iParams );
       
  2236         }
       
  2237     
       
  2238 	Continue( EStartConnect );
       
  2239 	}
       
  2240 	
       
  2241 //------------------------------------------------------------------------
       
  2242 //CCodEngBase::ChangeMediaObjectL()
       
  2243 //------------------------------------------------------------------------
       
  2244 // 
       
  2245 void CCodEngBase::ChangeMediaObjectL()
       
  2246 	{
       
  2247 	__ASSERT_DEBUG( iState == EMediaChange, CodPanic( ECodInternal ) );
       
  2248 	
       
  2249 	TInt mediaObjectCount = iData->Count();	
       
  2250     if( mediaObjectCount && iData->ActiveDownload() )
       
  2251     	{
       
  2252     	(*iData)[iData->ActiveDownload()]->iStatusCode = iStatusCode;
       
  2253     	(*iData)[iData->ActiveDownload()]->iResult = iResult;
       
  2254      	iObserver->Done( iStatusCode, iResult );
       
  2255     
       
  2256 		if( iStatusCode == KHttp900Success )
       
  2257 	    	{
       
  2258 	    	(*iData)[iData->ActiveDownload()]->iState = ESucceeded;
       
  2259         	StoreSubInfoFileL(NULL, iData->ActiveDownload() );
       
  2260 	    	}
       
  2261 
       
  2262     	UpdateTrackInfoL();
       
  2263     
       
  2264 	    if( iData->ActiveDownload() != mediaObjectCount &&( (*iData)[iData->ActiveDownload()]->iResult != KErrCancel 
       
  2265 	                                                    &&  (*iData)[iData->ActiveDownload()]->iResult != KErrAbort
       
  2266 	                                                    &&  (*iData)[iData->ActiveDownload()]->iResult != KErrCodWapConnectionDropped
       
  2267 	                                                    &&  (*iData)[iData->ActiveDownload()]->iResult != KErrCodHttpDownloadPaused
       
  2268 	                                                    &&  (*iData)[iData->ActiveDownload()]->iResult != KErrCodInvalidDescriptor))
       
  2269     		{
       
  2270       		if( iSaver )
       
  2271           		{
       
  2272           		iSaver->Cleanup( !(*iData)[iData->ActiveDownload()]->iPausable );
       
  2273           		}	    		
       
  2274 			delete iSaver;  // Cleans up unless Release()-d.
       
  2275 		    iSaver = NULL;	
       
  2276 		    delete iLoader;
       
  2277 		    iLoader = NULL;
       
  2278 		    delete iConn;
       
  2279 		    iConn = NULL;
       
  2280 		    delete iCodBuf;
       
  2281 		    iCodBuf = NULL;
       
  2282 
       
  2283     		TInt count = iData->ActiveDownload();
       
  2284 		  	do
       
  2285 		      {
       
  2286 		      count++;
       
  2287 		      }
       
  2288     			while( count <= iData->Count() && !( (*iData)[count]->State() == EQueued 
       
  2289 	            		|| (*iData)[count]->State() == EInProgress )
       
  2290 	            		);
       
  2291 	    
       
  2292 		    if( count <= iData->Count())
       
  2293 		        {
       
  2294 		    	iData->SetActiveDownload(count);
       
  2295 				Continue( EStartConnect );	    		
       
  2296 				return;
       
  2297 		        }
       
  2298    			}
       
  2299       	}     
       
  2300     Continue ( EStartProductNotify );     
       
  2301 	}
       
  2302 
       
  2303 //------------------------------------------------------------------------
       
  2304 //CCodEngBase::Pausable
       
  2305 //------------------------------------------------------------------------
       
  2306 EXPORT_C TBool CCodEngBase::Pausable()
       
  2307     {
       
  2308     return (*iData)[iData->ActiveDownload()]->iPausable;	
       
  2309     }
       
  2310 
       
  2311 // ---------------------------------------------------------
       
  2312 // CCodEngBase::StoreMainInfoFileL()
       
  2313 // ---------------------------------------------------------  
       
  2314 //       
       
  2315 void CCodEngBase::StoreMainInfoFileL()	
       
  2316     {
       
  2317     if ( iCodDlInfoPath == KNullDesC )
       
  2318         {
       
  2319         return;
       
  2320         }
       
  2321     TInt bufSz = KDownloadInfoIncrSize;
       
  2322     HBufC8* newInfo = HBufC8::NewLC( bufSz );
       
  2323     TPtr8 newInfoPtr = newInfo->Des();
       
  2324     
       
  2325     // Append the DD attributes 
       
  2326 	iData->AppendStorageInfoL(newInfoPtr);
       
  2327 
       
  2328     RFile outFile;
       
  2329     CleanupClosePushL<RFile>( outFile );
       
  2330     
       
  2331     User::LeaveIfError( outFile.Replace( iFs, 
       
  2332                                          iCodDlInfoPath, 
       
  2333                                          EFileShareExclusive | 
       
  2334                                          EFileStream | 
       
  2335                                          EFileWrite ) );
       
  2336 
       
  2337     outFile.Write( newInfoPtr );
       
  2338     User::LeaveIfError( outFile.Flush() );
       
  2339     
       
  2340     CleanupStack::PopAndDestroy(2);
       
  2341 
       
  2342     }
       
  2343 
       
  2344 // ---------------------------------------------------------
       
  2345 // CCodEngBase::StoreSubInfoFileL()
       
  2346 // ---------------------------------------------------------        
       
  2347 // 
       
  2348 void CCodEngBase::StoreSubInfoFileL( const CArrayPtrFlat<CHeaderField>* aHeaders, TInt aMediaIndex )	
       
  2349     {
       
  2350     if ( iCodDlInfoPath == KNullDesC )
       
  2351         {
       
  2352         return;
       
  2353         }
       
  2354     RFile outFile;
       
  2355     CleanupClosePushL<RFile>( outFile );
       
  2356 
       
  2357 
       
  2358     TInt bufSz = KDownloadInfoIncrSize;
       
  2359     HBufC8* newInfo = HBufC8::NewLC( bufSz );
       
  2360     TPtr8 newInfoPtr = newInfo->Des();
       
  2361     
       
  2362     TFileName infoPath;
       
  2363     infoPath.Format( _L("%S_%d"), &iCodDlInfoPath, aMediaIndex );
       
  2364 
       
  2365     newInfoPtr.Zero();
       
  2366     
       
  2367     // Load the DD attributes and other required information to the buffer
       
  2368 	(*iData)[aMediaIndex]->StoreMediaInfoL( newInfoPtr, aHeaders );
       
  2369 
       
  2370     User::LeaveIfError( outFile.Replace( iFs, 
       
  2371                                          infoPath, 
       
  2372                                          EFileShareExclusive | 
       
  2373                                          EFileStream | 
       
  2374                                          EFileWrite ) );
       
  2375 
       
  2376     outFile.Write( newInfoPtr );
       
  2377     User::LeaveIfError( outFile.Flush() );
       
  2378 
       
  2379     CleanupStack::PopAndDestroy(2);
       
  2380     }
       
  2381 
       
  2382 // ---------------------------------------------------------
       
  2383 // CCodEngBase::StoreInfoFilesL()
       
  2384 // ---------------------------------------------------------        
       
  2385 // 
       
  2386 void CCodEngBase::StoreInfoFilesL()	
       
  2387     {
       
  2388     StoreMainInfoFileL();
       
  2389     
       
  2390     for(TInt i = 1; i <= iData->Count(); ++i)
       
  2391         {
       
  2392         StoreSubInfoFileL( NULL, i );
       
  2393         }
       
  2394     }
       
  2395 // ---------------------------------------------------------
       
  2396 // CCodEngBase::LoadMainInfoFileL()
       
  2397 // ---------------------------------------------------------        
       
  2398 // 
       
  2399 void CCodEngBase::LoadMainInfoFileL()	
       
  2400     {
       
  2401     	
       
  2402     RFile inFile;
       
  2403     CleanupClosePushL<RFile>( inFile );
       
  2404     TInt err = inFile.Open(iFs, 
       
  2405                            CodDlInfoFile(), 
       
  2406                            EFileShareReadersOnly | 
       
  2407                            EFileRead ) ;	
       
  2408 
       
  2409     // Possible erros KErrNotFound , KErrPathNotFound , KErrBadName
       
  2410 	if( err  )
       
  2411 		{
       
  2412 		CleanupStack::PopAndDestroy();
       
  2413 		return;
       
  2414 		}
       
  2415 		
       
  2416 	iData->LoadStorageInfoL( inFile );
       
  2417 	CleanupStack::PopAndDestroy(); // inFile
       
  2418 
       
  2419     }
       
  2420 
       
  2421 // ---------------------------------------------------------
       
  2422 // CCodEngBase::LoadSubInfoFileL()
       
  2423 // ---------------------------------------------------------            
       
  2424 // 
       
  2425 void CCodEngBase::LoadSubInfoFileL( TInt aMediaIndex, CArrayPtrFlat<CHeaderField>* aHeaders )	
       
  2426     {
       
  2427    	
       
  2428     RFile inFile;
       
  2429     CleanupClosePushL<RFile>( inFile );
       
  2430 
       
  2431     TFileName infoPath;
       
  2432     infoPath.Format( _L("%S_%d"), &iCodDlInfoPath, aMediaIndex );
       
  2433 
       
  2434     
       
  2435     TInt err = inFile.Open(iFs, 
       
  2436                            infoPath, 
       
  2437                            EFileShareReadersOnly | 
       
  2438                            EFileRead ) ;	
       
  2439 
       
  2440     // Possible erros KErrNotFound , KErrPathNotFound , KErrBadName
       
  2441 	if( err  )
       
  2442 		{
       
  2443 		CleanupStack::PopAndDestroy();
       
  2444 		return;
       
  2445 		}
       
  2446 		
       
  2447 	(*iData)[aMediaIndex]->LoadMediaInfoL( inFile, iFs, aHeaders );
       
  2448 	CleanupStack::PopAndDestroy(); // inFile
       
  2449     }
       
  2450 
       
  2451 // ---------------------------------------------------------
       
  2452 // CCodEngBase::LoadInfoFilesL()
       
  2453 // ---------------------------------------------------------        
       
  2454 // 
       
  2455 void CCodEngBase::LoadInfoFilesL()	
       
  2456     {
       
  2457     LoadMainInfoFileL();
       
  2458     
       
  2459     TBool activeDownloadSet = EFalse;
       
  2460     
       
  2461     for(TInt i = 1; i <= iData->Count(); ++i)
       
  2462         {
       
  2463         LoadSubInfoFileL( i, NULL );
       
  2464         if( ((*iData)[i]->State() == EInProgress  || (*iData)[i]->State() == EQueued ) && !activeDownloadSet )
       
  2465             {
       
  2466             iData->SetActiveDownload ( i );
       
  2467             activeDownloadSet = ETrue;
       
  2468             }            
       
  2469         }
       
  2470     if( iData->ActiveDownload() == 0 )
       
  2471         {
       
  2472         iData->SetActiveDownload(iData->Count());
       
  2473         }
       
  2474     }    
       
  2475     
       
  2476 // ---------------------------------------------------------
       
  2477 // CCodEngBase::StartProductNotifyL
       
  2478 // ---------------------------------------------------------
       
  2479 //    
       
  2480 void CCodEngBase::StartProductNotifyL()
       
  2481     {
       
  2482     
       
  2483     CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartProductNotifyL iStatus(%d)"), \
       
  2484         iStatus.Int() ));
       
  2485     __ASSERT_DEBUG( iState == EStartProductNotify, CodPanic( ECodInternal ) );    
       
  2486     if ( iData->InstallNotify().Length() )
       
  2487         {
       
  2488         CLOG(( ECodEng, 4, _L("CCodEngBase::StartProductNotifyL: init request") ));
       
  2489         if ( !iProgress )
       
  2490             {
       
  2491             // Setup notify-only progress.
       
  2492             iProgress = new (ELeave) TCodProgress( iObserver );
       
  2493             iProgress->Setup( 0, KCodNotifyTraffic );    
       
  2494             }
       
  2495         iProgress->StartPhaseL( TCodProgress::ENotify );
       
  2496         TBool notifyObserver = EFalse;
       
  2497         // When notifying after fetch, we already have a loader (and the
       
  2498         // observer has already been notified about load).
       
  2499         // When notifying without fetch, we don't have a loader yet (and the
       
  2500         // observer has not been notified about load yet).
       
  2501         if ( !iConn )
       
  2502             {
       
  2503             iConn = CConnection::NewL();
       
  2504             }
       
  2505         // For notify, attach only (do no create new connection).
       
  2506         iConn->AttachL( iPreferredIap );
       
  2507         if( !iLoader )
       
  2508             {
       
  2509             iLoader = CHttpLoader::NewL( *iConn, NULL, iProgress ,this );
       
  2510             notifyObserver = ETrue;
       
  2511             }
       
  2512         TInt statusCode;
       
  2513         
       
  2514         if(!iData->Count())
       
  2515             {
       
  2516             statusCode = KHttp906InvalidDescriptor; 
       
  2517             }
       
  2518         else
       
  2519             {
       
  2520             statusCode = KHttp981DownloadCompletion; 
       
  2521             }
       
  2522             
       
  2523         for( TInt i = 1;i <= iData->Count(); ++i )
       
  2524             {
       
  2525             if( (*iData)[i]->iStatusCode != KHttp900Success )
       
  2526                 {
       
  2527                 statusCode = KHttp970MixedStatus;
       
  2528                 break;
       
  2529                 }
       
  2530             }
       
  2531         HBufC8* url = CodUtil::AbsoluteUrlLC
       
  2532             ( iData->SourceUri(), iData->InstallNotify() );
       
  2533         iLoader->NotifyL( *url, StatusText( statusCode ), &iStatus );
       
  2534         CleanupStack::PopAndDestroy( url );
       
  2535         iState = EProductNotify;
       
  2536         SetActive();
       
  2537         if ( iObserver && notifyObserver )
       
  2538             {
       
  2539             if ( iStatusCode == KHttp902UserCancelled ||
       
  2540                  iStatusCode == KHttp921UserAborted )
       
  2541                 {
       
  2542                 CLOG(( ECodEng, 3, \
       
  2543                     _L("-> CCodEngBase::StartNotifyL notify StartCancelL") ));
       
  2544                 iObserver->StartCancelL();
       
  2545                 iNotificationStatus = ECancel;
       
  2546                 }
       
  2547             else
       
  2548                 {
       
  2549                 CLOG(( ECodEng, 3, \
       
  2550                     _L("-> CCodEngBase::StartNotifyL notify StartLoadL(%d)"), \
       
  2551                     iStatusCode ));
       
  2552                 iObserver->StartLoadL( iStatusCode );
       
  2553                 iNotificationStatus = ELoad;
       
  2554                 }
       
  2555             }
       
  2556         }
       
  2557     else
       
  2558         {
       
  2559         // No install notify attribute, regarded as successful notification.
       
  2560         CLOG(( ECodEng, 4, _L("CCodEngBase::StartNotifyL: nothing to do") ));
       
  2561         Continue( EProductNotify );
       
  2562         }
       
  2563     CLOG(( ECodEng, 2, _L("<- CCodEngBase::StartNotifyL") ));    
       
  2564     }
       
  2565     
       
  2566 // ---------------------------------------------------------
       
  2567 // CCodEngBase::EndProductNotifyL
       
  2568 // ---------------------------------------------------------    
       
  2569 void CCodEngBase::EndProductNotifyL()
       
  2570     {
       
  2571         CLOG(( ECodEng, 2, _L("-> CCodEngBase::EndNotifyL iStatus(%d)"), \
       
  2572         iStatus.Int() ));
       
  2573     __ASSERT_DEBUG( iState == EProductNotify, CodPanic( ECodInternal ) );
       
  2574 
       
  2575     delete iLoader;
       
  2576     iLoader = NULL;
       
  2577     delete iConn;
       
  2578     iConn = NULL;
       
  2579 
       
  2580     User::LeaveIfError( iStatus.Int() );    // Handle errors in RunError().
       
  2581 
       
  2582     // Do not leave after this point! Notify was successful, we must keep
       
  2583     // downloaded content now.
       
  2584     
       
  2585     if ( iProgress )
       
  2586         {
       
  2587         TRAP_IGNORE( iProgress->DoneL() );
       
  2588         delete iProgress;
       
  2589         iProgress = NULL;
       
  2590         }
       
  2591     /*
       
  2592     if( iSaver && (*iData)[iData->ActiveDownload()]->iResult == KErrNone )
       
  2593         {
       
  2594 //TODO: check if in case of PD we should release. It is already done.
       
  2595         iSaver->ReleaseContent( (*iData)[iData->ActiveDownload()]->iFileName, iHandler );
       
  2596         iType = iSaver->DataType();
       
  2597         }
       
  2598     */
       
  2599     Done();
       
  2600     }
       
  2601 
       
  2602 //------------------------------------------------------------------------
       
  2603 //CCodEngBase::UpdatedDownloadDataL
       
  2604 //------------------------------------------------------------------------
       
  2605 EXPORT_C HBufC8* CCodEngBase::UpdatedDownloadDataL()
       
  2606     {
       
  2607     if (!iData)
       
  2608         return NULL;
       
  2609     
       
  2610     CDownloadDataClient* dlData = CDownloadDataClient::NewLC();
       
  2611     ConvertCodDataToDownloadDataL( dlData );
       
  2612     HBufC8* des8 = dlData->MarshalDataL();
       
  2613     CleanupStack::PopAndDestroy(dlData);
       
  2614     
       
  2615     return des8;
       
  2616     }
       
  2617 // ---------------------------------------------------------
       
  2618 // CCodEngBase::UpdateDownloadedSize
       
  2619 // ---------------------------------------------------------       
       
  2620 void CCodEngBase::UpdateDownloadedSize( TInt aSize )
       
  2621     {
       
  2622     (*iData)[iData->ActiveDownload()]->SetDownloadedSize( (*iData)[iData->ActiveDownload()]->DownloadedSize() + aSize );    
       
  2623     }
       
  2624 // ---------------------------------------------------------
       
  2625 // CCodEngBase::ActiveDownload
       
  2626 // ---------------------------------------------------------          
       
  2627 EXPORT_C TInt CCodEngBase::ActiveDownload()
       
  2628     {
       
  2629     return iData->ActiveDownload();
       
  2630     }
       
  2631 
       
  2632 //------------------------------------------------------------------------
       
  2633 //CCodEngBase::UpdatedTrackDataL
       
  2634 //------------------------------------------------------------------------
       
  2635 EXPORT_C HBufC8* CCodEngBase::UpdatedTrackDataL(TInt& aValue)
       
  2636     {
       
  2637     if (!iData)
       
  2638         return NULL;
       
  2639     
       
  2640     aValue = iData->ActiveDownload();
       
  2641     
       
  2642     CMediaDataClient* mediaData = CMediaDataClient::NewL();
       
  2643 	CleanupStack::PushL(mediaData);
       
  2644 	ConvertMOToMediaDataL(mediaData, aValue);
       
  2645     HBufC8* des8 = mediaData->MarshalDataL();
       
  2646     CleanupStack::PopAndDestroy(); //mediaData
       
  2647 
       
  2648     return des8;
       
  2649     }
       
  2650 //------------------------------------------------------------------------
       
  2651 //CCodEngBase::ConvertCODDataToDownloadDataL
       
  2652 //------------------------------------------------------------------------    
       
  2653 void CCodEngBase::ConvertCodDataToDownloadDataL( CDownloadDataClient*& aDlData )
       
  2654     {
       
  2655     if (aDlData)
       
  2656         {
       
  2657         aDlData->SetNameL( iData->Name() );
       
  2658         aDlData->SetSize( iData->Size() );
       
  2659         aDlData->SetIconL( iData->Icon() );
       
  2660         aDlData->SetUpdatedDDURI( iData->UpdatedDDUriL() );
       
  2661         
       
  2662         for (TInt mObj = 1; mObj <= iData->Count(); ++mObj)
       
  2663             {
       
  2664             CMediaDataClient* mediaData = CMediaDataClient::NewL();
       
  2665             CleanupStack::PushL(mediaData);
       
  2666             
       
  2667             ConvertMOToMediaDataL(mediaData, mObj);
       
  2668             aDlData->AppendMediaData(mediaData);
       
  2669             
       
  2670             CleanupStack::Pop(); //mediaData
       
  2671             }
       
  2672         }
       
  2673     }
       
  2674 
       
  2675 //------------------------------------------------------------------------
       
  2676 //CCodEngBase::ConvertMOToMediaDataL
       
  2677 //------------------------------------------------------------------------    
       
  2678 void CCodEngBase::ConvertMOToMediaDataL( CMediaDataClient*& aMOData, TInt aMOIndex )
       
  2679     {
       
  2680     CMediaObjectData* objMedia = (*iData)[aMOIndex];
       
  2681     
       
  2682     aMOData->SetNameL( objMedia->Name() );
       
  2683     aMOData->SetUrlL( objMedia->Url() );
       
  2684     aMOData->SetSize( objMedia->Size() );
       
  2685     aMOData->SetIconL( objMedia->Icon() );
       
  2686     aMOData->SetSourceUriL( objMedia->SourceUri() );
       
  2687     aMOData->SetProgressiveDownload( objMedia->ProgressiveDownload() );
       
  2688     aMOData->SetState( objMedia->State() );
       
  2689     aMOData->SetResult( objMedia->iResult );
       
  2690     aMOData->SetDownloadedSize( objMedia->DownloadedSize() );
       
  2691     aMOData->SetPausable( objMedia->Pausable() );
       
  2692     if(objMedia->iFullName)
       
  2693     	{
       
  2694     	aMOData->SetDestFilenameL( objMedia->FullName() );
       
  2695     	aMOData->SetTempFilenameL( objMedia->FullName() );
       
  2696     	}  
       
  2697     
       
  2698     for (TInt type = 0; type < objMedia->TypesCount(); ++type)
       
  2699         aMOData->AddTypeL( objMedia->Types().MdcaPoint(type) );
       
  2700     }
       
  2701 
       
  2702 //------------------------------------------------------------------------
       
  2703 //CCodEngBase::UpdateMediaInfoL
       
  2704 //------------------------------------------------------------------------    
       
  2705 void CCodEngBase::UpdateMediaInfoL()
       
  2706     {
       
  2707     if (iObserver)
       
  2708         {
       
  2709         iObserver->UpdateMediaInfoL();
       
  2710         }
       
  2711     }
       
  2712 // ---------------------------------------------------------
       
  2713 // CCodEngBase::GetProductStatusCode
       
  2714 // ---------------------------------------------------------       
       
  2715 EXPORT_C TCodDownloadProgress::TState CCodEngBase::GetProductStatusCode() const
       
  2716     {
       
  2717     TCodDownloadProgress::TState statusCode = TCodDownloadProgress::EFailedPermanent;        
       
  2718     TInt allSucceeded = 0;
       
  2719     TInt currentActiveDownload = iData->ActiveDownload();
       
  2720     
       
  2721     for( TInt i = 1 ; i <= iData->Count() ; ++i )
       
  2722         {
       
  2723         TInt mediaObjectStatusCode = (*iData)[i]->iStatusCode;
       
  2724         
       
  2725         // If the current track failed for some reason, set this as the
       
  2726         // active download. Do this only for the first failed track.
       
  2727         if ((mediaObjectStatusCode != KHttp900Success) &&
       
  2728             (mediaObjectStatusCode != KHttp956LicenseSuccess))
       
  2729             {
       
  2730             if( currentActiveDownload > i )
       
  2731                 {
       
  2732                 //This is done so that next time when resume happens
       
  2733                 //it happens from first failed download
       
  2734                 iData->SetActiveDownload ( i );
       
  2735                 currentActiveDownload = i;
       
  2736                 
       
  2737                 //Inform server about the Active download
       
  2738                 iObserver->SetActiveDownload();
       
  2739                 iObserver->MediaObjectNameChanged();
       
  2740                 }
       
  2741             }
       
  2742 
       
  2743         // Check for error and status code
       
  2744         switch( mediaObjectStatusCode )
       
  2745             {
       
  2746             case KHttp900Success:
       
  2747             case KHttp956LicenseSuccess:
       
  2748                 {
       
  2749                 allSucceeded++;
       
  2750                 statusCode = TCodDownloadProgress::ESucceeded;
       
  2751                 break;
       
  2752                 }
       
  2753 
       
  2754             case KHttp901InsufficientMemory:
       
  2755                 {
       
  2756                 statusCode = TCodDownloadProgress::EFailedTemporary;
       
  2757                 break;
       
  2758                 }
       
  2759             case KHttp902UserCancelled:
       
  2760             case KHttp921UserAborted:
       
  2761             case KHttp957LicenseFailed:
       
  2762                 {
       
  2763                 break;
       
  2764                 }
       
  2765             
       
  2766             case KHttp905AttributeMismatch:
       
  2767             case KHttp906InvalidDescriptor:
       
  2768             case KHttp907InvalidType:
       
  2769             case KHttp922DeviceAborted:
       
  2770             case KHttp923NonAcceptableContent:
       
  2771             case KHttp924LoaderError:
       
  2772             case KHttp951InvalidDdVersion:
       
  2773             case KHttp952DeviceAborted:
       
  2774             case KHttp953NonAcceptableContent:
       
  2775             case KHttp909RequestedRangeNotSatisfiable:
       
  2776                 {
       
  2777                 // Permanent errors: retry is useless.
       
  2778                 if( (*iData)[i]->iPausable ) 
       
  2779                     {
       
  2780                     //for pausable permanent errors
       
  2781                     //Are actually Temporary errors
       
  2782                     return TCodDownloadProgress::EFailedTemporary;
       
  2783                     }
       
  2784                 break;
       
  2785                 }
       
  2786             case KHttp954LoaderError:
       
  2787             case KHttp903LossOfService:
       
  2788             case KHttp910NoMemory:
       
  2789             	{
       
  2790             	if( (*iData)[i]->iPausable )
       
  2791             		{
       
  2792             		return TCodDownloadProgress::EPaused;
       
  2793             		}
       
  2794             	break;
       
  2795             	}
       
  2796             	
       
  2797 
       
  2798             case KHttp955PreconditionFailed:
       
  2799                 {
       
  2800                 return TCodDownloadProgress::EInit;
       
  2801                 }
       
  2802 
       
  2803             default:
       
  2804                 {
       
  2805                 // Unexpected status.
       
  2806                 //__ASSERT_DEBUG( EFalse, CodUiPanic( ECodUiInternal ) );
       
  2807                 statusCode = TCodDownloadProgress::EFailedPermanent;
       
  2808                 break;
       
  2809                 }
       
  2810 
       
  2811             }
       
  2812         }
       
  2813         
       
  2814     if( iData->Count() && allSucceeded == iData->Count())
       
  2815         {
       
  2816         return TCodDownloadProgress::ESucceeded;
       
  2817         }            
       
  2818     if( statusCode == TCodDownloadProgress::EFailedPermanent && !allSucceeded)    
       
  2819         {
       
  2820         return statusCode;
       
  2821         }
       
  2822 
       
  2823     return TCodDownloadProgress::EFailedTemporary;    
       
  2824     }
       
  2825     
       
  2826 //------------------------------------------------------------------------
       
  2827 //CCodEngBase::UpdateTrackInfoL
       
  2828 //------------------------------------------------------------------------    
       
  2829 void CCodEngBase::UpdateTrackInfoL()
       
  2830     {
       
  2831     if (iObserver)
       
  2832         {
       
  2833         iObserver->UpdateTrackInfoL();
       
  2834         }
       
  2835     }
       
  2836 
       
  2837 //------------------------------------------------------------------------
       
  2838 //CCodEngBase::SetUrlL
       
  2839 //------------------------------------------------------------------------
       
  2840 void CCodEngBase::SetUrlL(const TDesC& aUrl)
       
  2841 	{
       
  2842 	TInt currentActiveDownload = iData->ActiveDownload();
       
  2843 	(*iData)[currentActiveDownload]->SetUrlL( aUrl );
       
  2844 	}
       
  2845 	
       
  2846 	
       
  2847 //------------------------------------------------------------------------
       
  2848 //CCodEngBase::ContentTypeChanged
       
  2849 //------------------------------------------------------------------------    
       
  2850 void CCodEngBase::ContentTypeChanged()
       
  2851     {
       
  2852     if (iObserver)
       
  2853         {
       
  2854         iObserver->ContentTypeChanged();
       
  2855         }
       
  2856     }