browserutilities/feedsengine/FeedsServer/Api/src/FeedsInterface.cpp
changeset 0 dd21522fd290
child 25 0ed94ceaa377
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of 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:  The client side connection to the FeedsSever.
       
    15  *
       
    16 */
       
    17 
       
    18  
       
    19 #include "FeedsInterface.h"
       
    20 #include "FeedsMap.h"
       
    21 #include "Transaction.h"
       
    22 #include "FeedAttributes.h"
       
    23 #include "FolderAttributes.h"
       
    24 #include "Logger.h"
       
    25 #include <e32math.h>
       
    26 
       
    27 // -----------------------------------------------------------------------------
       
    28 // RFeedsInterface::Constructor
       
    29 // 
       
    30 // Default constructor should never leave.
       
    31 // -----------------------------------------------------------------------------
       
    32 //
       
    33 EXPORT_C RFeedsInterface::RFeedsInterface(MFeedsApiObserver& aObserver,
       
    34         TInt aFolderListId) :
       
    35     iObserver(aObserver), iRootFolder(NULL), iCurrentFeed(NULL), iFolderListId(aFolderListId), iIsConnected(EFalse)
       
    36     {
       
    37 
       
    38     }
       
    39 
       
    40 // -----------------------------------------------------------------------------
       
    41 // RFeedsInterface::Connect
       
    42 // 
       
    43 // Connects to Feed server
       
    44 // -----------------------------------------------------------------------------
       
    45 //
       
    46 EXPORT_C TInt RFeedsInterface::Connect()
       
    47 	{
       
    48     TInt retry = 2;
       
    49 
       
    50     TInt err;
       
    51 
       
    52     for (;;)
       
    53         {
       
    54         // Attempt to create a session with the server.
       
    55         err = CreateSession (KFeedsServerName, Version (), 25);
       
    56 
       
    57         // Get the settings.
       
    58         if ( err == KErrNone)
       
    59         	{
       
    60         	iIsConnected = ETrue;
       
    61         	return KErrNone;
       
    62         	}
       
    63 
       
    64         // Return general errors.
       
    65         if ( (err != KErrNotFound) && (err != KErrServerTerminated))
       
    66         	{
       
    67         	return err;
       
    68         	}
       
    69 
       
    70         // No more retries left.
       
    71         if ( --retry == 0)
       
    72         	{
       
    73         	return err;
       
    74         	}
       
    75 
       
    76         // If need be start the server.
       
    77         err = StartServer ();
       
    78 
       
    79         // Return if the server failed to start.
       
    80         if ( (err != KErrNone) && (err != KErrAlreadyExists))
       
    81         	{
       
    82         	return err;
       
    83         	}
       
    84         }
       
    85     }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // RFeedsInterface::Close
       
    89 // 
       
    90 // Closes connection with server
       
    91 // -----------------------------------------------------------------------------
       
    92 //
       
    93 EXPORT_C void RFeedsInterface::Close()
       
    94     {
       
    95     SendReceive (EFeedsServerDisconnectManualUpdateConnection);
       
    96     SendReceive (EFeedsServerCloseFeedSession);
       
    97     SendReceive (EFeedsServerCompleteWatchSettings);
       
    98     SendReceive (EFeedsServerCompleteWatchFolderList);
       
    99     SendReceive (EFeedsServerCloseFolderSession);
       
   100 
       
   101     RSessionBase::Close ();
       
   102 
       
   103     delete iRootFolder;
       
   104     iRootFolder = NULL;
       
   105     delete iCurrentFeed;
       
   106     iCurrentFeed = NULL;
       
   107     iActiveTransaction.ResetAndDestroy ();
       
   108     }
       
   109 
       
   110 // -----------------------------------------------------------------------------
       
   111 // RFeedsInterface::Version
       
   112 // 
       
   113 // Returns current version of API
       
   114 // -----------------------------------------------------------------------------
       
   115 //
       
   116 
       
   117 EXPORT_C TVersion RFeedsInterface::Version() const
       
   118     {
       
   119     return (TVersion(KFeedsServerMajorVersionNumber, KFeedsServerMinorVersionNumber,
       
   120             KFeedsServerBuildVersionNumber));
       
   121     }
       
   122 
       
   123 // -----------------------------------------------------------------------------
       
   124 // RFeedsInterface::SendAsyncCommand
       
   125 // 
       
   126 // calls SendReceive on current session
       
   127 // -----------------------------------------------------------------------------
       
   128 //
       
   129 
       
   130 void RFeedsInterface::SendAsyncCommand(TInt aFunction, const TIpcArgs& aArgs,
       
   131         TRequestStatus& aStatus) const
       
   132         {
       
   133         SendReceive (aFunction, aArgs, aStatus);
       
   134         }
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // RFeedsInterface::RequestHandlerCompleted
       
   138 // 
       
   139 // Called by transaction when request completes.
       
   140 // -----------------------------------------------------------------------------
       
   141 //
       
   142 
       
   143 void RFeedsInterface::RequestHandlerCompleted(CTransaction& aTransaction,
       
   144         TInt aStatus)
       
   145     {
       
   146     TInt pos = KErrNotFound;
       
   147     
       
   148     for (int i = 0; i < iActiveTransaction.Count (); i++)
       
   149         {
       
   150         if ( aTransaction.GetId ()== iActiveTransaction[i]->GetId ())
       
   151             {
       
   152             pos = i;
       
   153             break;
       
   154             }
       
   155         }
       
   156         
       
   157     if ( aStatus != KErrNone && pos != KErrNotFound)
       
   158         {
       
   159         iObserver.RequestCompleted (iActiveTransaction[pos], aStatus == KErrNone ? EFeedsRequestCompleted
       
   160                                     : EFeedsRequestFailed);
       
   161         iActiveTransaction[pos]->AutoDelete();
       
   162         iActiveTransaction.Remove (pos);
       
   163         return;
       
   164         }
       
   165     
       
   166     if ( pos != KErrNotFound)
       
   167         {
       
   168         switch (iActiveTransaction[pos]->Type ())
       
   169         	{
       
   170             case CTransaction::EFetchRootFolderItem:
       
   171                 if ( iActiveTransaction[pos]->iTranStatus == KErrNone)
       
   172                     {
       
   173                     if ( iRootFolder != NULL)
       
   174                         {
       
   175                         delete iRootFolder;
       
   176                         iRootFolder = NULL;
       
   177                         }
       
   178                     iRootFolder = iActiveTransaction[pos]->OrphanFeedsEntity ();
       
   179                     // Start watching for changes.
       
   180                     TRAP_IGNORE(WatchFolderListL ());
       
   181                     }
       
   182                 break;
       
   183             case CTransaction::EFetchFeed:
       
   184                 if ( iActiveTransaction[pos]->iTranStatus == KErrNone)
       
   185                     {
       
   186                     if ( iCurrentFeed != NULL)
       
   187                         {
       
   188                         delete iCurrentFeed;
       
   189                         }
       
   190                     iCurrentFeed = iActiveTransaction[pos]->OrphanFeedsEntity ();
       
   191                     UpdateFeed(iRootFolder, iCurrentFeed);
       
   192                     }
       
   193             	break;
       
   194             case CTransaction::EFetchSettings:
       
   195                    iActiveTransaction[pos]->GetSetting(iSetting);
       
   196                 break;
       
   197             case CTransaction::EWatchForChanges:
       
   198                 if ( iActiveTransaction[pos]->iTranStatus == KErrNone)
       
   199                     {
       
   200                     TRAP_IGNORE(GetRootFolderL());
       
   201                     iActiveTransaction[pos]->AutoDelete();
       
   202                     iActiveTransaction.Remove (pos);
       
   203                     return;
       
   204                     }
       
   205                 break;
       
   206             // no need to notify observer now, server will notify us later
       
   207             // assuming FetchRootFolder or WatchFolderList has been called before
       
   208             case CTransaction::EAddFolderItem:
       
   209             case CTransaction::EDeleteFolderItem:
       
   210             case CTransaction::EChangeFolderItem:
       
   211             case CTransaction::EMoveFolderItem:
       
   212             case CTransaction::EMoveFolderItemTo:
       
   213             case CTransaction::EUpdateFolderItem:
       
   214                 iActiveTransaction[pos]->AutoDelete();
       
   215                 iActiveTransaction.Remove (pos);
       
   216                 return;
       
   217             
       
   218             case CTransaction::EImportOPML:
       
   219             case CTransaction::EExportOPML:
       
   220                 break;
       
   221 
       
   222             // feed related
       
   223             case CTransaction::EUpdateItemStatus:
       
   224                 
       
   225             // general client related
       
   226             case CTransaction::EChangeSettings:
       
   227                 break;
       
   228                 
       
   229             case CTransaction::EWatchForSettingChanges:
       
   230                 if ( iActiveTransaction[pos]->iTranStatus == KErrNone)
       
   231                     {
       
   232                     TRAP_IGNORE( 
       
   233                         {
       
   234                         CTransaction* trans = GetTransactionL();
       
   235                         CleanupStack::PushL(trans);
       
   236                         trans->FetchServerSettingsL();
       
   237                         iActiveTransaction.AppendL(trans);
       
   238                         CleanupStack::Pop(trans);
       
   239                         });
       
   240                     iActiveTransaction[pos]->AutoDelete();
       
   241                     iActiveTransaction.Remove (pos);
       
   242                     return;
       
   243                     }
       
   244                 break;
       
   245                 
       
   246             case CTransaction::ECancelAll:
       
   247             case CTransaction::EDisconnectManualUpdateConnection:
       
   248                 return;
       
   249 
       
   250         	}
       
   251         iObserver.RequestCompleted (iActiveTransaction[pos],
       
   252                     aStatus == KErrNone ? EFeedsRequestCompleted
       
   253                                     : EFeedsRequestFailed);
       
   254         iActiveTransaction[pos]->AutoDelete();
       
   255         iActiveTransaction.Remove (pos);
       
   256         }
       
   257     }
       
   258 
       
   259 // -----------------------------------------------------------------------------
       
   260 // RFeedsInterface::UpdateFeed
       
   261 // 
       
   262 // Updates timestamp/unreadcount in correponding on in rootfolder.
       
   263 // -----------------------------------------------------------------------------
       
   264 //
       
   265 
       
   266 TBool RFeedsInterface::UpdateFeed(CFeedsEntity* aRootFolder, CFeedsEntity* aFeed)
       
   267 	{
       
   268     if ( aRootFolder == NULL || aFeed == NULL)
       
   269          return EFalse;
       
   270     if ( aRootFolder->GetType ()== EFeed && aFeed->iFeedId == aRootFolder->iFeedId)
       
   271         {
       
   272         TTime time;
       
   273         time.HomeTime ();
       
   274         aFeed->GetTimeValue (EFeedAttributeTimestamp, time);
       
   275         aRootFolder->iAttrProp->SetTimeAttribute (EFeedAttributeTimestamp, time);
       
   276         TInt unreadCount = 0;
       
   277         TInt status;
       
   278         for (TInt i=0; i<aFeed->GetChildren().Count ();i++)
       
   279             {
       
   280             CFeedsEntity* item = aFeed->GetChildren()[i];
       
   281             item->GetIntegerValue (EItemAttributeStatus, status);
       
   282             if ( status != EItemStatusRead)
       
   283                 {
       
   284                 unreadCount++;
       
   285                 }
       
   286             }
       
   287         aRootFolder->iAttrProp->SetIntegerAttribute (
       
   288             EFolderAttributeUnreadCount, unreadCount);
       
   289         return ETrue;
       
   290         }
       
   291     if ( aRootFolder->GetType ()== EFolder)
       
   292         {
       
   293         for (TInt i =0; i<aRootFolder->GetChildren().Count ();i++)
       
   294             {
       
   295             if ( UpdateFeed (aRootFolder->GetChildren()[i], aFeed))
       
   296                 {
       
   297                 return ETrue;
       
   298                 }
       
   299             }
       
   300         }
       
   301     return EFalse;
       
   302 	}
       
   303 
       
   304 // -----------------------------------------------------------------------------
       
   305 // RFeedsInterface::CancelAllCommandsL
       
   306 // 
       
   307 // Cancel commands
       
   308 // -----------------------------------------------------------------------------
       
   309 //
       
   310 void RFeedsInterface::CancelAllCommandsL()
       
   311     {
       
   312     CTransaction* trans = GetTransactionL ();
       
   313     CleanupStack::PushL (trans);
       
   314 
       
   315     trans->CancelAllL();
       
   316     iActiveTransaction.AppendL (trans);
       
   317     CleanupStack::Pop (trans);
       
   318     }
       
   319 
       
   320 // -----------------------------------------------------------------------------
       
   321 // RFeedsInterface::GetRootFolder
       
   322 // 
       
   323 // Fetches root folder
       
   324 // -----------------------------------------------------------------------------
       
   325 //
       
   326 EXPORT_C TInt RFeedsInterface::GetRootFolderL()
       
   327     {
       
   328     CTransaction* trans = GetTransactionL ();
       
   329     CleanupStack::PushL (trans);
       
   330 
       
   331     trans->FetchFolderItemL (EFalse);
       
   332     iActiveTransaction.AppendL (trans);
       
   333     CleanupStack::Pop (trans);
       
   334     return trans->GetId();
       
   335     }
       
   336 // -----------------------------------------------------------------------------
       
   337 // RFeedsInterface::Add
       
   338 // 
       
   339 // Adds new feed/folder into list
       
   340 // -----------------------------------------------------------------------------
       
   341 //
       
   342 
       
   343 EXPORT_C void RFeedsInterface::AddL(TFeedsEntityType aType, const CFeedsMap& aArgs,
       
   344         const CFeedsEntity& aParent)
       
   345     {
       
   346     TPtrC title;
       
   347     TPtrC url;
       
   348     TInt freq;
       
   349     aArgs.GetStringAttribute(EFeedAttributeTitle,title);
       
   350     aArgs.GetStringAttribute(EFeedAttributeLink,url);
       
   351     if (aArgs.GetIntegerAttribute(EFeedAttributeAutoUpdateFreq,freq) == KErrNotFound)
       
   352         {
       
   353         freq = 0;
       
   354         }
       
   355 
       
   356     CTransaction* trans = GetTransactionL ();
       
   357     CleanupStack::PushL (trans);
       
   358 
       
   359     trans->AddFolderItemL (title, url, aType==EFolder, aParent, freq);
       
   360     iActiveTransaction.AppendL (trans);
       
   361     CleanupStack::Pop (trans);
       
   362     }
       
   363 
       
   364 // -----------------------------------------------------------------------------
       
   365 // RFeedsInterface::SetAttributeL
       
   366 // 
       
   367 // Changes various feed/folder/item attribute on server side.
       
   368 // -----------------------------------------------------------------------------
       
   369 //
       
   370 
       
   371 EXPORT_C TInt RFeedsInterface::SetAttributeL(const CFeedsEntity& aFeedEntity,
       
   372         const CFeedsMap& aNewValues)
       
   373     {
       
   374     TPtrC title;
       
   375     TPtrC url;
       
   376     TInt freq = 0;
       
   377     TFeedItemStatus readStatus;
       
   378     TInt unreadCount = 0;
       
   379     CFeedsEntity* parent = NULL;
       
   380 
       
   381     switch (aFeedEntity.GetType())
       
   382         {
       
   383         case EFeed:
       
   384             if( aNewValues.IsExist( EFeedAttributeTitle) )
       
   385                 {
       
   386                 aNewValues.GetStringAttribute ( EFeedAttributeTitle, title);                       
       
   387                 }
       
   388                 else
       
   389                 {
       
   390                 aFeedEntity.iAttrProp->GetStringAttribute( EFeedAttributeTitle, title);
       
   391                 }
       
   392             if( aNewValues.IsExist ( EFeedAttributeLink) )     
       
   393                 {
       
   394                 aNewValues.GetStringAttribute ( EFeedAttributeLink, url);    
       
   395                 }
       
   396             else
       
   397                 {
       
   398                 aFeedEntity.iAttrProp->GetStringAttribute( EFeedAttributeLink, url);    
       
   399                 }    
       
   400             if( aNewValues.IsExist( EFeedAttributeAutoUpdateFreq))
       
   401                 {
       
   402                 aNewValues.GetIntegerAttribute( EFeedAttributeAutoUpdateFreq, freq);    
       
   403                 }
       
   404             else
       
   405                 {
       
   406                 if ( KErrNotFound == aFeedEntity.iAttrProp->GetIntegerAttribute( EFeedAttributeAutoUpdateFreq, freq))
       
   407                     {
       
   408                     freq = 0;
       
   409                     }
       
   410                 }
       
   411             break;	
       
   412 
       
   413         case EFolder:
       
   414             if ( aNewValues.IsExist (EFeedAttributeTitle))
       
   415                 {
       
   416                 aNewValues.GetStringAttribute (EFeedAttributeTitle, title);
       
   417                 }
       
   418             else
       
   419                 {
       
   420                 return KErrArgument;
       
   421                 }
       
   422             break;
       
   423 
       
   424         case EFeedsItem:
       
   425 
       
   426             if ( aNewValues.IsExist (EItemAttributeStatus))
       
   427                 {
       
   428                 TInt status;
       
   429                 aNewValues.GetIntegerAttribute (EItemAttributeStatus, status);
       
   430                 readStatus = (TFeedItemStatus)status;
       
   431                 }
       
   432             else
       
   433                 {
       
   434                 return KErrArgument;
       
   435                 }
       
   436             break;
       
   437 
       
   438         case EFeedsEnclosure:
       
   439             //return KErrArgument;
       
   440             break;
       
   441         }
       
   442     CTransaction* trans = GetTransactionL ();
       
   443     CleanupStack::PushL (trans);
       
   444 
       
   445     switch (aFeedEntity.GetType ())
       
   446         {
       
   447         case EFeed:
       
   448             trans->ChangeFolderItemL (aFeedEntity, title, url, freq);
       
   449             break;
       
   450 
       
   451         case EFolder:
       
   452             trans->ChangeFolderItemL (aFeedEntity, title, url, freq);
       
   453             break;
       
   454 
       
   455         case EFeedsItem:
       
   456             {
       
   457             parent = SearchFeed (aFeedEntity.GetParent()->iFeedId, iRootFolder);
       
   458             RArray<TInt> itemIds;
       
   459             RArray<TFeedItemStatus> status;
       
   460             TInt oldStatus;
       
   461             if ( aFeedEntity.iAttrProp->GetIntegerAttribute (
       
   462                     EItemAttributeStatus, oldStatus)== KErrNotFound)
       
   463                 {
       
   464                 oldStatus = (TInt)EItemStatusUndefined;
       
   465                 }
       
   466 
       
   467             if ( parent != NULL && parent->iAttrProp->GetIntegerAttribute (
       
   468                     EFolderAttributeUnreadCount, unreadCount)!= KErrNotFound)
       
   469                 {
       
   470                 }
       
   471 
       
   472             if ( oldStatus != (TInt) readStatus)
       
   473                 {
       
   474                 if ( (oldStatus == EItemStatusNew || oldStatus == EItemStatusUnread) && readStatus == EItemStatusRead)
       
   475                     {
       
   476                     unreadCount--;
       
   477                     }
       
   478                 else
       
   479                 	if ( oldStatus == EItemStatusRead && (readStatus == EItemStatusNew || readStatus == EItemStatusUnread))
       
   480                         {
       
   481                         unreadCount++;
       
   482                         }
       
   483                 }
       
   484             itemIds.Append (aFeedEntity.GetId ());
       
   485             status.Append (readStatus);
       
   486 
       
   487             trans->UpdateItemStatusL (aFeedEntity.GetParent()->iFeedId, itemIds, status, unreadCount);
       
   488 
       
   489             }
       
   490             break;
       
   491 
       
   492         case EFeedsEnclosure:
       
   493         	break;
       
   494         }
       
   495     iActiveTransaction.AppendL (trans);
       
   496     if ( aFeedEntity.GetType ()== EFeedsItem)
       
   497         {
       
   498         aFeedEntity.iAttrProp->SetIntegerAttribute (EItemAttributeStatus,
       
   499                 readStatus);
       
   500         if ( parent != NULL)
       
   501             parent->iAttrProp->SetIntegerAttribute (
       
   502                 EFolderAttributeUnreadCount, unreadCount);
       
   503         }
       
   504 
       
   505     CleanupStack::Pop (trans);
       
   506     return KErrNone;
       
   507     }
       
   508 
       
   509 // -----------------------------------------------------------------------------
       
   510 // RFeedsInterface::SearchFeed
       
   511 // 
       
   512 // Searches feed with given id ,in list.
       
   513 // -----------------------------------------------------------------------------
       
   514 //
       
   515 EXPORT_C CFeedsEntity* RFeedsInterface::SearchFeed(TInt aFeedId, CFeedsEntity* aSearch)
       
   516     {
       
   517 
       
   518     if ((aSearch->GetType ()== EFeed) && (aSearch->iFeedId == aFeedId))
       
   519         {
       
   520         return aSearch;
       
   521         }
       
   522     if ( aSearch->GetType ()== EFolder)
       
   523         {
       
   524         const RPointerArray<CFeedsEntity>& children = aSearch->GetChildren();
       
   525         TInt count = children.Count();
       
   526         CFeedsEntity* child = NULL;
       
   527         CFeedsEntity *foundFeed = NULL;
       
   528         for (TInt i=0; i<count;i++)
       
   529             {
       
   530             child = children[i];
       
   531             foundFeed = SearchFeed (aFeedId, child);
       
   532             if(foundFeed)
       
   533                 {
       
   534                 return foundFeed;
       
   535                 }		
       
   536             }
       
   537         }
       
   538     return NULL;
       
   539     }
       
   540 
       
   541 // -----------------------------------------------------------------------------
       
   542 // RFeedsInterface::Delete
       
   543 // 
       
   544 // Delete feeds/folder
       
   545 // -----------------------------------------------------------------------------
       
   546 //
       
   547 
       
   548 EXPORT_C void RFeedsInterface::DeleteL(const RPointerArray<const CFeedsEntity> aFeedsEntities)
       
   549     {
       
   550     CTransaction* trans = GetTransactionL();
       
   551     CleanupStack::PushL(trans);
       
   552 
       
   553     trans->DeleteFolderItemL(aFeedsEntities);
       
   554     iActiveTransaction.AppendL(trans);
       
   555     CleanupStack::Pop(trans);
       
   556     }
       
   557 
       
   558 // -----------------------------------------------------------------------------
       
   559 // RFeedsInterface::DebugPrintTablesL
       
   560 //
       
   561 // Print tables of database.
       
   562 // -----------------------------------------------------------------------------
       
   563 //
       
   564 EXPORT_C void RFeedsInterface::DebugPrintTablesL()
       
   565     {
       
   566     CTransaction* trans = GetTransactionL();
       
   567     CleanupStack::PushL(trans);
       
   568 
       
   569     trans->DebugPrintTables();
       
   570     iActiveTransaction.AppendL(trans);
       
   571     CleanupStack::Pop(trans);
       
   572     }
       
   573 	
       
   574 // -----------------------------------------------------------------------------
       
   575 // RFeedsInterface::DisconnectManualUpdateConnectionL
       
   576 //
       
   577 // Disconnect connection provided by client for manual update.
       
   578 // -----------------------------------------------------------------------------
       
   579 //
       
   580 EXPORT_C void RFeedsInterface::DisconnectManualUpdateConnectionL()
       
   581     {
       
   582     CTransaction* trans = GetTransactionL();
       
   583     CleanupStack::PushL(trans);
       
   584 
       
   585     trans->DisconnectManualUpdateConnection();
       
   586     iActiveTransaction.AppendL(trans);
       
   587     CleanupStack::Pop(trans);
       
   588     }
       
   589 	
       
   590 	
       
   591 // -----------------------------------------------------------------------------
       
   592 // RFeedsInterface::Fetch
       
   593 // 
       
   594 // Fetch feed from server (May involve updation of feed)
       
   595 // -----------------------------------------------------------------------------
       
   596 //
       
   597 
       
   598 EXPORT_C TInt RFeedsInterface::FetchL(const CFeedsEntity& aEntity, TBool aForceUpdate, TBool aNoCache)
       
   599     {
       
   600     CTransaction* trans = GetTransactionL();
       
   601     CleanupStack::PushL(trans);
       
   602 
       
   603     trans->FetchFeedL(aEntity.iFeedId, aForceUpdate, aNoCache);
       
   604     iActiveTransaction.AppendL(trans);
       
   605     CleanupStack::Pop(trans);
       
   606     return trans->GetId();
       
   607     }
       
   608 
       
   609 // -----------------------------------------------------------------------------
       
   610 // RFeedsInterface::Fetch
       
   611 // 
       
   612 // Fetch feed from server (May involve updation of feed)
       
   613 // -----------------------------------------------------------------------------
       
   614 //
       
   615 
       
   616 EXPORT_C TInt RFeedsInterface::FetchL(const TDesC& aUrl, TBool aForceUpdate, TBool aNoCache)
       
   617     {
       
   618     CTransaction* trans = GetTransactionL();
       
   619     CleanupStack::PushL(trans);
       
   620 
       
   621     trans->FetchFeedL(aUrl, aForceUpdate, aNoCache);
       
   622     iActiveTransaction.AppendL(trans);
       
   623     CleanupStack::Pop(trans);
       
   624     return trans->GetId();
       
   625     }
       
   626 	
       
   627 // -----------------------------------------------------------------------------
       
   628 // RFeedsInterface::Update
       
   629 // 
       
   630 // Update feeds/Folder
       
   631 // -----------------------------------------------------------------------------
       
   632 //
       
   633 
       
   634 EXPORT_C TInt RFeedsInterface::UpdateL(const RPointerArray<const CFeedsEntity>& aFeedsArray)
       
   635     {
       
   636     CTransaction* trans = GetTransactionL();
       
   637     CleanupStack::PushL(trans);
       
   638     if(aFeedsArray.Count() == 1 && aFeedsArray[0]->GetId() == 0)
       
   639         {
       
   640         trans->UpdateFolderItemsL();
       
   641         }
       
   642     else
       
   643         {
       
   644         trans->UpdateFolderItemsL(aFeedsArray );
       
   645         }
       
   646 
       
   647     iActiveTransaction.AppendL(trans);
       
   648     CleanupStack::Pop(trans);
       
   649     return trans->GetId();
       
   650     }
       
   651 
       
   652 
       
   653 // -----------------------------------------------------------------------------
       
   654 // RFeedsInterface::GetSettings
       
   655 // 
       
   656 // Fetches Settings from server
       
   657 // -----------------------------------------------------------------------------
       
   658 //
       
   659 EXPORT_C TInt RFeedsInterface::GetSettingsL(TFeedsServerSetting& aFeedsSetting, TBool aAsync/*=ETrue*/)
       
   660     {
       
   661 
       
   662     CTransaction* trans = GetTransactionL();
       
   663     CleanupStack::PushL(trans);
       
   664     if(aAsync)
       
   665         {
       
   666         trans->FetchServerSettingsL();
       
   667         iActiveTransaction.AppendL(trans);
       
   668         }
       
   669     else
       
   670         {
       
   671         trans->FetchServerSettingsSyncL();
       
   672         iSetting = trans->Settings();
       
   673         trans->AutoDelete();
       
   674         aFeedsSetting = iSetting;
       
   675         }
       
   676     CleanupStack::Pop(trans);
       
   677     return KErrNone;
       
   678     }
       
   679 	
       
   680 // -----------------------------------------------------------------------------
       
   681 // RFeedsInterface::SetSettings
       
   682 // 
       
   683 // Changes settings
       
   684 // -----------------------------------------------------------------------------
       
   685 //
       
   686 
       
   687 EXPORT_C void RFeedsInterface::SetSettingsL(const TFeedsServerSetting& aFeedsSetting)
       
   688     {
       
   689     CTransaction* trans = GetTransactionL();
       
   690     CleanupStack::PushL(trans);
       
   691 
       
   692     trans->ChangeServerSettingsL( aFeedsSetting );
       
   693     iActiveTransaction.AppendL(trans);
       
   694     CleanupStack::Pop(trans);
       
   695     }
       
   696 
       
   697 // -----------------------------------------------------------------------------
       
   698 // RFeedsInterface::WatchSettings
       
   699 // 
       
   700 // Sets up a notifier to execute when the settings change.
       
   701 // -----------------------------------------------------------------------------
       
   702 //
       
   703 EXPORT_C void RFeedsInterface::WatchSettingsL()
       
   704     {
       
   705     CTransaction* trans = GetTransactionL();
       
   706     CleanupStack::PushL(trans);
       
   707 
       
   708     trans->WatchSettingsL();
       
   709     iActiveTransaction.AppendL(trans);
       
   710     CleanupStack::Pop(trans);
       
   711     }
       
   712 
       
   713 // -----------------------------------------------------------------------------
       
   714 // RFeedsInterface::ExportFolders
       
   715 // 
       
   716 // Exports list of folders in form of OPML file
       
   717 // -----------------------------------------------------------------------------
       
   718 //
       
   719 
       
   720 EXPORT_C void RFeedsInterface::ExportFoldersL(const RPointerArray<const CFeedsEntity>& aFeedsArray,const TDesC& aFileName)
       
   721     {
       
   722     CTransaction* trans = GetTransactionL();
       
   723     CleanupStack::PushL(trans);
       
   724 
       
   725     trans->ExportFolderItemL( aFeedsArray,aFileName);
       
   726     iActiveTransaction.AppendL(trans);
       
   727     CleanupStack::Pop(trans);
       
   728     }
       
   729     
       
   730 // -----------------------------------------------------------------------------
       
   731 // RFeedsInterface::ImportOPML
       
   732 // 
       
   733 // Imports OPML
       
   734 // -----------------------------------------------------------------------------
       
   735 //
       
   736 EXPORT_C void RFeedsInterface::ImportOPMLL(const TDesC& aFileName)
       
   737     {
       
   738     CTransaction* trans = GetTransactionL();
       
   739     CleanupStack::PushL(trans);
       
   740 
       
   741     trans->ImportOPMLL( aFileName ,EFalse);
       
   742     iActiveTransaction.AppendL(trans);
       
   743     CleanupStack::Pop(trans);
       
   744     }
       
   745 
       
   746 // -----------------------------------------------------------------------------
       
   747 // RFeedsInterface::CancelAll
       
   748 // 
       
   749 // Cancels all pending requests
       
   750 // -----------------------------------------------------------------------------
       
   751 //
       
   752 EXPORT_C void RFeedsInterface::CancelAllL()
       
   753     {
       
   754     CTransaction* trans = GetTransactionL();
       
   755     CleanupStack::PushL(trans);
       
   756 
       
   757     trans->CancelAllL();
       
   758     iActiveTransaction.AppendL(trans);
       
   759     CleanupStack::Pop(trans);
       
   760     }
       
   761 
       
   762 // -----------------------------------------------------------------------------
       
   763 // RFeedsInterface::Move
       
   764 // 
       
   765 // Move folder/feed to specific index.
       
   766 // -----------------------------------------------------------------------------
       
   767 //
       
   768 EXPORT_C void RFeedsInterface::MoveL(const RPointerArray<const CFeedsEntity>& aFolderItems,TInt aIndex)
       
   769     {
       
   770     CTransaction* trans = GetTransactionL();
       
   771     CleanupStack::PushL(trans);
       
   772 
       
   773     trans->MoveFolderItemsL( aFolderItems,aIndex);
       
   774     iActiveTransaction.AppendL(trans);
       
   775     CleanupStack::Pop(trans);
       
   776     }
       
   777 
       
   778 // -----------------------------------------------------------------------------
       
   779 // RFeedsInterface::MoveToFolder
       
   780 // 
       
   781 // Move feeds/folders to diff folder.
       
   782 // -----------------------------------------------------------------------------
       
   783 //
       
   784 EXPORT_C void RFeedsInterface::MoveToFolderL(const RPointerArray<const CFeedsEntity>& aSourceFolders,const CFeedsEntity& aDestinationFolder)
       
   785     {
       
   786     CTransaction* trans = GetTransactionL();
       
   787     CleanupStack::PushL(trans);
       
   788 
       
   789     trans->MoveFolderItemsToL( aSourceFolders,aDestinationFolder);
       
   790     iActiveTransaction.AppendL(trans);
       
   791     CleanupStack::Pop(trans);
       
   792     }
       
   793 
       
   794 // -----------------------------------------------------------------------------
       
   795 // RFeedsInterface::WatchFolderListL
       
   796 // 
       
   797 // Sets up notifier for changes happen on server side.
       
   798 // -----------------------------------------------------------------------------
       
   799 //
       
   800 EXPORT_C void RFeedsInterface::WatchFolderListL()
       
   801     {
       
   802     for (int i=0; i<iActiveTransaction.Count ();i++)
       
   803         {
       
   804         if ( iActiveTransaction[i]->Type ()== CTransaction::EWatchForChanges)
       
   805             {
       
   806             return;
       
   807             }
       
   808         }
       
   809 
       
   810     CTransaction* trans = GetTransactionL();
       
   811     CleanupStack::PushL (trans);
       
   812 
       
   813     trans->WatchFolderListL ();
       
   814     iActiveTransaction.AppendL (trans);
       
   815     CleanupStack::Pop (trans);
       
   816     }
       
   817 
       
   818 // -----------------------------------------------------------------------------
       
   819 // RFeedsInterface::GetTransactionL
       
   820 // 
       
   821 // Factory function to return transaction with unique ID
       
   822 // -----------------------------------------------------------------------------
       
   823 //
       
   824 CTransaction* RFeedsInterface::GetTransactionL()
       
   825     {
       
   826     TBool found = EFalse;
       
   827     TInt transId;
       
   828     do
       
   829         {
       
   830         found = EFalse;
       
   831         transId = Math::Random ();
       
   832         for (int i=0; i<iActiveTransaction.Count ();i++)
       
   833             {
       
   834             if ( iActiveTransaction[i]->GetId ()== transId)
       
   835                 {
       
   836                 found = ETrue;
       
   837                 break;
       
   838                 }
       
   839             }
       
   840         }
       
   841     while (found);
       
   842     CTransaction* trans = CTransaction::NewL (*this, transId, iFolderListId);
       
   843     trans->SetFeedInterface (this);
       
   844     return trans;
       
   845     }
       
   846 
       
   847 // -----------------------------------------------------------------------------
       
   848 // RFeedsInterface::StartServer
       
   849 // 
       
   850 // Create the server thread/process
       
   851 // -----------------------------------------------------------------------------
       
   852 //
       
   853 TInt RFeedsInterface::StartServer()
       
   854     {
       
   855     RProcess server;
       
   856 
       
   857     // EPOC is easy, just create a new server process. Simultaneous
       
   858     // launching of two such processes is detected when the second one
       
   859     // attempts to create the server object, failing with KErrAlreadyExists.
       
   860     TInt r = server.Create (KFeedsServerName, KNullDesC);
       
   861     if ( r != KErrNone)
       
   862         {
       
   863         return r;
       
   864         }
       
   865 
       
   866     TRequestStatus stat;
       
   867     server.Rendezvous (stat);
       
   868 
       
   869     // An unrecoverable error occurred.
       
   870     if ( stat != KRequestPending)
       
   871         {
       
   872         server.Kill (0);
       
   873         }
       
   874 
       
   875     // Logon OK, start the server.
       
   876     else
       
   877         {
       
   878         server.Resume ();
       
   879         }
       
   880 
       
   881     // Wait for start or death.
       
   882     User::WaitForRequest (stat);
       
   883 
       
   884     // The 'exit reason' can't be used if the server panicked as this
       
   885     // is the panic 'reason' and may be '0' which cannot be distinguished
       
   886     // from KErrNone
       
   887     r = (server.ExitType() == EExitPanic) ? KErrGeneral : stat.Int ();
       
   888 
       
   889     // Close the server.
       
   890     server.Close ();
       
   891 
       
   892     return r;
       
   893     }
       
   894 
       
   895 // -----------------------------------------------------------------------------
       
   896 // RFeedsInterface::RootFolder
       
   897 // 
       
   898 // Returns RootFolder
       
   899 // -----------------------------------------------------------------------------
       
   900 //
       
   901 
       
   902 EXPORT_C CFeedsEntity* RFeedsInterface::RootFolder()
       
   903     {
       
   904     return iRootFolder;
       
   905     }
       
   906 // -----------------------------------------------------------------------------
       
   907 // RFeedsInterface::Feed
       
   908 // 
       
   909 // Return currently fetched feed
       
   910 // -----------------------------------------------------------------------------
       
   911 //
       
   912 
       
   913 EXPORT_C CFeedsEntity* RFeedsInterface::Feed()
       
   914     {
       
   915     return iCurrentFeed;
       
   916     }
       
   917 
       
   918 // -----------------------------------------------------------------------------
       
   919 // RFeedsInterface::UpdateFeedItemStatusL
       
   920 // Updates the feed item's status
       
   921 // -----------------------------------------------------------------------------
       
   922 //	
       
   923 EXPORT_C void RFeedsInterface::UpdateFeedItemStatusL(const RArray<TInt>& aItemIds,
       
   924         const RArray<TFeedItemStatus>& aItemStatus, TInt aUnreadCount)
       
   925     {
       
   926     CTransaction* trans = GetTransactionL();
       
   927     CleanupStack::PushL(trans);
       
   928 
       
   929     trans->UpdateItemStatusL( iCurrentFeed->iFeedId, aItemIds, aItemStatus, aUnreadCount);
       
   930     iActiveTransaction.AppendL(trans);
       
   931     CleanupStack::Pop(trans);
       
   932 
       
   933     }
       
   934 
       
   935 
       
   936 // -----------------------------------------------------------------------------
       
   937 // RFeedsInterface::NetworkConnectionNeededL()
       
   938 // -----------------------------------------------------------------------------
       
   939 //
       
   940 void RFeedsInterface::NetworkConnectionNeededL( TInt* aConnectionPtr,
       
   941         TInt& aSockSvrHandle, TBool& aNewConn, TApBearerType& aBearerType)
       
   942     {
       
   943     iObserver.NetworkConnectionNeededL ( aConnectionPtr, aSockSvrHandle,
       
   944             aNewConn, aBearerType);
       
   945     }
       
   946 	
       
   947 
       
   948 // -----------------------------------------------------------------------------
       
   949 // RFeedsInterface::SendReceiveSync
       
   950 // 
       
   951 // calls synchronous SendReceive on current session
       
   952 // -----------------------------------------------------------------------------
       
   953 //
       
   954 
       
   955 TInt RFeedsInterface::SendReceiveSync(TInt aFunction, const TIpcArgs& aArgs) const
       
   956     {
       
   957     return (SendReceive(aFunction, aArgs));
       
   958     }
       
   959 
       
   960 // -----------------------------------------------------------------------------
       
   961 // RFeedsInterface::Settings
       
   962 // 
       
   963 // return current settings.
       
   964 // -----------------------------------------------------------------------------
       
   965 //
       
   966 EXPORT_C TFeedsServerSetting RFeedsInterface::Settings()
       
   967     {
       
   968     return iSetting;
       
   969     }