hti/HtiFramework/src/HtiFramework.cpp
branchRCL_3
changeset 59 8ad140f3dd41
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This file contains the implementations of the
       
    15 *               CHtiFramework class.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "HtiFramework.h"
       
    22 #include "HtiLogging.h"
       
    23 #include <badesca.h>
       
    24 #include <e32std.h>
       
    25 #include <f32file.h>
       
    26 #include <HtiCfg.h>
       
    27 #include <HtiStartupWaitInterface.h>
       
    28 
       
    29 // CONSTANTS
       
    30 _LIT( KHtiFrameworkMatchPattern, "HtiFramework*" );
       
    31 _LIT( KHtiMainThreadName,        "HtiMain" );
       
    32 _LIT( KHtiWatchDogExeName,       "HtiWatchDog.exe" );
       
    33 _LIT( KHtiWatchDogMatchPattern,  "HtiWatchDog*" );
       
    34 _LIT( KHtiAdminStartParameter,   "admin" );
       
    35 _LIT( KEComServerMatchPattern,   "EComServer*" );
       
    36 _LIT( KHtiStartupWaitDllName,    "HtiStartupWait.dll" );
       
    37 
       
    38 // config file parameters
       
    39 _LIT( KCfgFilePath,         "\\");
       
    40 _LIT( KHtiCfgFileName,      "hti.cfg" );
       
    41 _LIT8( KCommPlugin,         "CommPlugin" );
       
    42 _LIT8( KMaxMsgSize,         "MaxMsgSize" );
       
    43 _LIT8( KMaxQueueSize,       "MaxQueueSize" );
       
    44 _LIT8( KMaxHeapSize,        "MaxHeapSize" );
       
    45 _LIT8( KPriority,           "Priority" );
       
    46 _LIT8( KShowConsole,        "ShowConsole" );
       
    47 _LIT8( KMaxWaitTime,        "MaxWaitTime" );
       
    48 _LIT8( KStartUpDelay,       "StartUpDelay" );
       
    49 _LIT8( KEnableHtiWatchDog,  "EnableHtiWatchDog" );
       
    50 _LIT8( KEnableHtiAutoStart, "EnableHtiAutoStart" );
       
    51 _LIT8( KShowErrorDialogs,   "ShowErrorDialogs" );
       
    52 _LIT8( KReconnectDelay,     "ReconnectDelay");
       
    53 
       
    54 const static TInt KDefaultMaxWaitTime  = 90; // seconds
       
    55 const static TInt KDefaultStartUpDelay = 5;  // seconds
       
    56 const static TInt KHtiDefaultPriority = 3;
       
    57 const static TInt KHtiWatchDogEnabledDefault = 0;
       
    58 const static TInt KHtiConsoleEnabledDefault = 0;
       
    59 const static TInt KHtiAutoStartEnabledDefault = 0;
       
    60 const static TInt KHtiShowErrorDialogsDefault = 1;
       
    61 const static TInt KHtiReconnectDelay = 0;
       
    62 
       
    63 // MACROS
       
    64 
       
    65 // LOCAL CONSTANTS AND MACROS
       
    66 
       
    67 // MODULE DATA STRUCTURES
       
    68 
       
    69 // LOCAL FUNCTION PROTOTYPES
       
    70 
       
    71 // FORWARD DECLARATIONS
       
    72 
       
    73 // ============================ MEMBER FUNCTIONS ===============================
       
    74 
       
    75 // -----------------------------------------------------------------------------
       
    76 // CHtiFramework::CHtiFramework
       
    77 // Constructor
       
    78 // -----------------------------------------------------------------------------
       
    79 CHtiFramework::CHtiFramework():
       
    80     iCfg( NULL ),
       
    81     iDispatcher( NULL ),
       
    82     iOriginalHeap( NULL )
       
    83     {
       
    84     }
       
    85 
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CHtiFramework::ConstructL
       
    89 // Second phase constructor
       
    90 // -----------------------------------------------------------------------------
       
    91 void CHtiFramework::ConstructL()
       
    92     {
       
    93     HTI_LOG_FUNC_IN("CHtiFramework::ConstructL");
       
    94 
       
    95     if ( IsHtiRunning() )
       
    96         {
       
    97         HTI_LOG_TEXT( "HTI already running - not starting second instance" );
       
    98         User::Leave( KErrAlreadyExists );
       
    99         }
       
   100 
       
   101     TInt priority = KHtiDefaultPriority;
       
   102     TInt enableHtiWatchDog = KHtiWatchDogEnabledDefault;
       
   103     TInt showConsole = KHtiConsoleEnabledDefault;
       
   104     TInt enableHtiAutoStart = KHtiAutoStartEnabledDefault;
       
   105     TInt showErrorDialogs = KHtiShowErrorDialogsDefault;
       
   106     TInt reconnectDelay = KHtiReconnectDelay;
       
   107 
       
   108     TRAPD( err, iCfg = CHtiCfg::NewL() );
       
   109     if ( err == KErrNone )
       
   110         {
       
   111         HTI_LOG_TEXT( "CHtiCfg constructed" );
       
   112         TRAP( err, iCfg->LoadCfgL( KCfgFilePath, KHtiCfgFileName ) );
       
   113         if ( err == KErrNone )
       
   114             {
       
   115             HTI_LOG_TEXT( "Cfg file loaded" );
       
   116 
       
   117             TBuf8<64> commPlugin( KNullDesC8 );
       
   118             TRAPD( paramErr, commPlugin = iCfg->GetParameterL( KCommPlugin ) );
       
   119             if ( paramErr != KErrNone )
       
   120                 {
       
   121                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   122                 HTI_LOG_DES( KCommPlugin );
       
   123                 }
       
   124 
       
   125             TInt maxMsgSize = 0;
       
   126             TRAP( paramErr, maxMsgSize = iCfg->GetParameterIntL( KMaxMsgSize ) );
       
   127             if ( paramErr != KErrNone )
       
   128                 {
       
   129                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   130                 HTI_LOG_DES( KMaxMsgSize );
       
   131                 }
       
   132 
       
   133             TInt maxQueueSize = 0;
       
   134             TRAP( paramErr, maxQueueSize = iCfg->GetParameterIntL( KMaxQueueSize ) );
       
   135             if ( paramErr != KErrNone )
       
   136                 {
       
   137                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   138                 HTI_LOG_DES( KMaxQueueSize );
       
   139                 }
       
   140 
       
   141             TInt maxHeapSize = 0;
       
   142             TRAP( paramErr, maxHeapSize = iCfg->GetParameterIntL( KMaxHeapSize ) );
       
   143             if ( paramErr != KErrNone )
       
   144                 {
       
   145                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   146                 HTI_LOG_DES( KMaxHeapSize );
       
   147                 }
       
   148             else
       
   149                 {
       
   150                 //create new heap and switch heaps
       
   151                 RHeap* newHeap = UserHeap::ChunkHeap( NULL, //local
       
   152                                                       KMinHeapSize, //min size
       
   153                                                       maxHeapSize //max size
       
   154                                                      );
       
   155                 if ( newHeap )
       
   156                     {
       
   157                     HTI_LOG_TEXT( "SwitchHeap" );
       
   158                     iOriginalHeap = User::SwitchHeap( newHeap );
       
   159                     HTI_LOG_ALLOC_HEAP_MEM();
       
   160                     }
       
   161                 else
       
   162                     {
       
   163                     HTI_LOG_TEXT( "Failed create new heap" );
       
   164                     User::Leave( KErrNoMemory );
       
   165                     }
       
   166                 }
       
   167 
       
   168             TRAP( paramErr, priority = iCfg->GetParameterIntL( KPriority ) );
       
   169             if ( paramErr != KErrNone )
       
   170                 {
       
   171                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   172                 HTI_LOG_DES( KPriority );
       
   173                 }
       
   174 
       
   175             TRAP( paramErr, showConsole = iCfg->GetParameterIntL( KShowConsole ) );
       
   176             if ( paramErr != KErrNone )
       
   177                 {
       
   178                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   179                 HTI_LOG_DES( KShowConsole );
       
   180                 }
       
   181 
       
   182             TInt maxWaitTime = KDefaultMaxWaitTime;
       
   183             TRAP( paramErr, maxWaitTime = iCfg->GetParameterIntL( KMaxWaitTime ) );
       
   184             if ( paramErr != KErrNone )
       
   185                 {
       
   186                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   187                 HTI_LOG_DES( KMaxWaitTime );
       
   188                 }
       
   189 
       
   190             TInt startUpDelay = KDefaultStartUpDelay;
       
   191             TRAP( paramErr, startUpDelay = iCfg->GetParameterIntL( KStartUpDelay ) );
       
   192             if ( paramErr != KErrNone )
       
   193                 {
       
   194                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   195                 HTI_LOG_DES( KStartUpDelay );
       
   196                 }
       
   197 
       
   198             TRAP( paramErr, enableHtiWatchDog = iCfg->GetParameterIntL( KEnableHtiWatchDog ) );
       
   199             if ( paramErr != KErrNone )
       
   200                 {
       
   201                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   202                 HTI_LOG_DES( KEnableHtiWatchDog );
       
   203                 }
       
   204 
       
   205             TRAP( paramErr, enableHtiAutoStart = iCfg->GetParameterIntL( KEnableHtiAutoStart ) );
       
   206             if ( paramErr != KErrNone )
       
   207                 {
       
   208                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   209                 HTI_LOG_DES( KEnableHtiAutoStart );
       
   210                 }
       
   211 
       
   212             TRAP( paramErr, showErrorDialogs = iCfg->GetParameterIntL( KShowErrorDialogs ) );
       
   213             if ( paramErr != KErrNone )
       
   214                 {
       
   215                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   216                 HTI_LOG_DES( KShowErrorDialogs );
       
   217                 }
       
   218             
       
   219             TRAP( paramErr, reconnectDelay = iCfg->GetParameterIntL( KReconnectDelay ) );
       
   220             if ( paramErr != KErrNone )
       
   221                 {
       
   222                 HTI_LOG_TEXT( "The following parameter not defined in cfg, using default value:" );
       
   223                 HTI_LOG_DES( KReconnectDelay );
       
   224                 }
       
   225             
       
   226             if ( !IsStartAcceptedL( enableHtiAutoStart ) )
       
   227                 {
       
   228                 User::Leave( KErrAbort );
       
   229                 }
       
   230 
       
   231             WaitNormalState( maxWaitTime, startUpDelay );
       
   232             iDispatcher = CHtiDispatcher::NewL( commPlugin, maxMsgSize,
       
   233                     maxQueueSize, reconnectDelay, showConsole != 0, showErrorDialogs != 0 );
       
   234             }
       
   235         }
       
   236 
       
   237 
       
   238     // cfg file was not found or it could not be opened
       
   239     if ( err )
       
   240         {
       
   241         HTI_LOG_TEXT( "Error loading cfg file, use default values" );
       
   242 
       
   243         if ( !IsStartAcceptedL( enableHtiAutoStart ) )
       
   244             {
       
   245             User::Leave( KErrAbort );
       
   246             }
       
   247 
       
   248         WaitNormalState( KDefaultMaxWaitTime, KDefaultStartUpDelay );
       
   249 
       
   250         //create with default values
       
   251         iDispatcher = CHtiDispatcher::NewL(
       
   252             KNullDesC8, 0, 0, 0, showConsole != 0, showErrorDialogs != 0 );
       
   253         }
       
   254 
       
   255     HTI_LOG_FORMAT( "Priority setting = %d", priority );
       
   256     // Set HTI priority
       
   257     switch ( priority )
       
   258         {
       
   259         case 1:
       
   260             RProcess().SetPriority( EPriorityBackground ); // 250
       
   261             break;
       
   262         case 2:
       
   263             RProcess().SetPriority( EPriorityForeground ); // 350
       
   264             break;
       
   265         // case 3: goes to default
       
   266         case 4:
       
   267             RThread().SetPriority( EPriorityAbsoluteHigh ); // 500
       
   268             break;
       
   269         default:
       
   270             RProcess().SetPriority( EPriorityHigh );        // 450
       
   271             break;
       
   272         }
       
   273 
       
   274     // start hti watchdog, if it is enabled in config file
       
   275     if ( enableHtiWatchDog != 0 ) StartHtiWatchDogL();
       
   276 
       
   277     HTI_LOG_FORMAT( "Process priority %d", RProcess().Priority() );
       
   278     HTI_LOG_FORMAT( "Thread priority %d", RThread().Priority() );
       
   279     HTI_LOG_FUNC_OUT("CHtiFramework::ConstructL");
       
   280     }
       
   281 
       
   282 
       
   283 // -----------------------------------------------------------------------------
       
   284 // CHtiFramework::~CHtiFramework
       
   285 // Destructor.
       
   286 // -----------------------------------------------------------------------------
       
   287 CHtiFramework::~CHtiFramework()
       
   288     {
       
   289     HTI_LOG_FUNC_IN("~CHTIServer");
       
   290     delete iDispatcher;
       
   291 
       
   292     HTI_LOG_ALLOC_HEAP_MEM();
       
   293     //switch before deleting iCfg
       
   294     //'cause iCfg was allocated in the original heap
       
   295     if ( iOriginalHeap )
       
   296         {
       
   297         User::SwitchHeap( iOriginalHeap );
       
   298         }
       
   299 
       
   300     delete iCfg;
       
   301     HTI_LOG_FUNC_OUT("~CHTIServer");
       
   302     }
       
   303 
       
   304 
       
   305 // -----------------------------------------------------------------------------
       
   306 // CHtiFramework::NewL
       
   307 // Two-phased constructor.
       
   308 // -----------------------------------------------------------------------------
       
   309 CHtiFramework* CHtiFramework::NewL()
       
   310     {
       
   311     CHtiFramework* obj = new ( ELeave ) CHtiFramework;
       
   312     CleanupStack::PushL( obj );
       
   313     obj->ConstructL();
       
   314     CleanupStack::Pop();
       
   315     return obj;
       
   316     }
       
   317 
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 // CHtiFramework::StartL
       
   321 // The method that gets the show going.
       
   322 // -----------------------------------------------------------------------------
       
   323 TInt CHtiFramework::StartL()
       
   324     {
       
   325     HTI_LOG_FUNC_IN( "CHtiFramework::StartL" );
       
   326 
       
   327     CConsoleBase* console = iDispatcher->GetConsole();
       
   328     if ( console )
       
   329         {
       
   330         console->Printf( _L( "HTI up and running.\n" ) );
       
   331         }
       
   332 
       
   333     // start scheduler
       
   334     CActiveScheduler::Start();
       
   335 
       
   336     HTI_LOG_FUNC_OUT( "CHtiFramework::StartL" );
       
   337     return KErrNone;
       
   338 
       
   339     }
       
   340 
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 // CHtiFramework::StartHtiWatchDogL
       
   344 // Launches the HTI Watchdog process if necessary.
       
   345 // -----------------------------------------------------------------------------
       
   346 void CHtiFramework::StartHtiWatchDogL()
       
   347     {
       
   348     HTI_LOG_FUNC_IN( "CHtiFramework::StartHtiWatchDogL" );
       
   349 
       
   350     TFullName processName;
       
   351     TFindProcess finder( KHtiWatchDogMatchPattern );
       
   352     TInt err = finder.Next( processName );
       
   353     if ( err == KErrNone )
       
   354         {
       
   355         // ok, already running
       
   356         HTI_LOG_TEXT( "HtiWatchDog already running" );
       
   357         }
       
   358     else
       
   359         {
       
   360         // start watchdog
       
   361         HTI_LOG_TEXT( "Starting HtiWatchDog..." );
       
   362         RProcess watchDogProcess;
       
   363         err = watchDogProcess.Create( KHtiWatchDogExeName, KNullDesC );
       
   364         if ( err == KErrNone )
       
   365             {
       
   366             watchDogProcess.Resume();
       
   367             watchDogProcess.Close();
       
   368             HTI_LOG_TEXT( "HtiWatchDog up and running" );
       
   369             }
       
   370         else
       
   371             {
       
   372             HTI_LOG_FORMAT( "Could not start HtiWatchDog, err: %d", err );
       
   373             User::Leave( err );
       
   374             }
       
   375         }
       
   376     HTI_LOG_FUNC_OUT( "CHtiFramework::StartHtiWatchDogL" );
       
   377     }
       
   378 
       
   379 
       
   380 // -----------------------------------------------------------------------------
       
   381 // CHtiFramework::WaitNormalState
       
   382 // Delays HTI startup until device reaches normal state.
       
   383 // -----------------------------------------------------------------------------
       
   384 void CHtiFramework::WaitNormalState( TInt aMaxWaitTime, TInt aStartUpDelay )
       
   385     {
       
   386     HTI_LOG_FUNC_IN("CHtiFramework::WaitNormalState");
       
   387     // First make sure that EComServer is running before continuing
       
   388     TFullName processName;
       
   389     TFindProcess finder( KEComServerMatchPattern );
       
   390     while ( finder.Next( processName ) != KErrNone )
       
   391         {
       
   392         HTI_LOG_TEXT( "HTI waiting for EComServer startup" );
       
   393         finder.Find( KEComServerMatchPattern );
       
   394         User::After( 1000000 ); // wait 1 second
       
   395         }
       
   396     HTI_LOG_TEXT( "EComServer process found - HTI startup continuing" );
       
   397 
       
   398     if ( aMaxWaitTime > 0 )
       
   399         {
       
   400         TInt err = KErrNone;
       
   401         RFs fs;
       
   402         err = fs.Connect();
       
   403         if ( err == KErrNone )
       
   404             {
       
   405             RLibrary library;
       
   406             err = library.Load( KHtiStartupWaitDllName );
       
   407             HTI_LOG_FORMAT( "StartupWait library load returned %d", err );
       
   408             if ( err == KErrNone &&
       
   409                  library.Type()[1] == KHtiStartupWaitInterfaceUid )
       
   410                 {
       
   411                 HTI_LOG_TEXT( "StartupWait DLL found" );
       
   412                 TLibraryFunction entry = library.Lookup( 1 );
       
   413                 if ( entry != NULL )
       
   414                     {
       
   415                     MHtiStartupWaitInterface* startupWait =
       
   416                         ( MHtiStartupWaitInterface* ) entry();
       
   417                     err = startupWait->WaitForStartup( aMaxWaitTime );
       
   418                     HTI_LOG_FORMAT( "StartupWait returned %d", err );
       
   419                     delete startupWait;
       
   420                     startupWait = NULL;
       
   421                     }
       
   422                 }
       
   423             library.Close();
       
   424             }
       
   425         }
       
   426 
       
   427     HTI_LOG_FORMAT( "HTI Starting after %d seconds", aStartUpDelay );
       
   428     User::After( aStartUpDelay * 1000 * 1000 );
       
   429 
       
   430     HTI_LOG_FUNC_OUT( "CHtiFramework::WaitNormalState" );
       
   431     }
       
   432 
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // CHtiFramework::IsHtiRunning
       
   436 // Checks whether HTI Framework process is already running.
       
   437 // -----------------------------------------------------------------------------
       
   438 TBool CHtiFramework::IsHtiRunning()
       
   439     {
       
   440     HTI_LOG_FUNC_IN( "CHtiFramework::IsHtiRunning" );
       
   441     TInt htiInstanceCount = 0;
       
   442     TBool isRunning = EFalse;
       
   443     TFullName processName;
       
   444     TFindProcess finder( KHtiFrameworkMatchPattern );
       
   445     TInt err = finder.Next( processName );
       
   446     while ( err == KErrNone && processName.Length() > 0 )
       
   447         {
       
   448         HTI_LOG_FORMAT( "Found process %S", &processName );
       
   449         RProcess process;
       
   450         err = process.Open( finder );
       
   451         if ( err == KErrNone )
       
   452             {
       
   453             if ( process.ExitType() == EExitPending )
       
   454                 {
       
   455                 HTI_LOG_TEXT( "Process is running" );
       
   456                 htiInstanceCount++;
       
   457                 }
       
   458             process.Close();
       
   459             }
       
   460         err = finder.Next( processName );
       
   461         }
       
   462     if ( htiInstanceCount > 1 )
       
   463         {
       
   464         isRunning = ETrue;
       
   465         }
       
   466     HTI_LOG_FUNC_OUT( "CHtiFramework::IsHtiRunning" );
       
   467     return isRunning;
       
   468     }
       
   469 
       
   470 
       
   471 // -----------------------------------------------------------------------------
       
   472 // CHtiFramework::IsStartAccepted
       
   473 // Checks whether HTI Framework should start or not. If automatic startup is
       
   474 // disabled HTI should start only when started by HtiAdmin.
       
   475 // -----------------------------------------------------------------------------
       
   476 TBool CHtiFramework::IsStartAcceptedL( TBool aIsAutoStartEnabled )
       
   477     {
       
   478     HTI_LOG_FUNC_IN( "CHtiFramework::IsStartAccepted" );
       
   479     TBool isStartAccepted = EFalse;
       
   480 
       
   481     if ( aIsAutoStartEnabled )
       
   482         {
       
   483         // If auto start is enabled, no additional checks needed. OK to start.
       
   484         isStartAccepted = ETrue;
       
   485         }
       
   486 
       
   487     else
       
   488         {
       
   489         // If we have "admin" parameter given from command line, start is
       
   490         // requested by HtiAdmin or HtiWatchDog and we are OK to start -
       
   491         // otherwise this is an auto start and we deny it.
       
   492         TInt cmdLen = User::CommandLineLength();
       
   493         HBufC* cmdLine = HBufC::NewL( cmdLen );
       
   494         TPtr ptrCmdLine = cmdLine->Des();
       
   495         User::CommandLine( ptrCmdLine );
       
   496         TLex parser( *cmdLine );
       
   497         parser.SkipCharacters();
       
   498         if ( parser.MarkedToken().Compare( KHtiAdminStartParameter ) == 0  )
       
   499             {
       
   500             isStartAccepted = ETrue;
       
   501             }
       
   502         delete cmdLine;
       
   503         cmdLine = NULL;
       
   504         }
       
   505 
       
   506     HTI_LOG_FORMAT( "HTI start accepted = %d", isStartAccepted );
       
   507     HTI_LOG_FUNC_OUT( "CHtiFramework::IsStartAccepted" );
       
   508     return isStartAccepted;
       
   509     }
       
   510 
       
   511 
       
   512 // ============================ LOCAL FUNCTIONS ===============================
       
   513 
       
   514 LOCAL_C TInt StartL()
       
   515     {
       
   516     User::__DbgMarkStart( RHeap::EUser );
       
   517 
       
   518     User::RenameThread( KHtiMainThreadName );
       
   519 
       
   520     TInt error;
       
   521     CHtiFramework* server = NULL;
       
   522     TRAP( error, server = CHtiFramework::NewL() );
       
   523 
       
   524     if ( error == KErrNone )
       
   525         {
       
   526         CleanupStack::PushL( server );
       
   527         TRAP( error, server->StartL() );
       
   528 
       
   529         if ( error )
       
   530             {
       
   531             HTI_LOG_FORMAT( "Leave happened in StartL(): %d", error );
       
   532             }
       
   533 
       
   534         CleanupStack::PopAndDestroy();
       
   535         }
       
   536     else
       
   537         {
       
   538         HTI_LOG_FORMAT( "Leave when constructing: %d", error );
       
   539         }
       
   540 
       
   541     User::__DbgMarkEnd( RHeap::EUser, 0 );
       
   542     HTI_LOG_TEXT( "NO memory leaks: past __UHEAP_MARKEND" );
       
   543     return error;
       
   544     }
       
   545 
       
   546 
       
   547 GLDEF_C TInt E32Main()
       
   548     {
       
   549     __UHEAP_MARK;
       
   550     HTI_LOG_ALLOC_HEAP_MEM();
       
   551 
       
   552     _LIT( KHTIServer, "CHtiFramework" );
       
   553     CTrapCleanup* cleanup = CTrapCleanup::New();
       
   554     CActiveScheduler *scheduler = new ( ELeave ) CActiveScheduler;
       
   555     CActiveScheduler::Install( scheduler );
       
   556 
       
   557     TRAPD( error, StartL() );
       
   558 
       
   559     delete scheduler;
       
   560     delete cleanup;
       
   561     __UHEAP_MARKEND;
       
   562     HTI_LOG_ALLOC_HEAP_MEM();
       
   563 
       
   564     __ASSERT_ALWAYS( !error, User::Panic( KHTIServer, error ) );
       
   565     return KErrNone;
       
   566     }