vtengines/vtmediatorplugin/src/cvtmediatorplugin.cpp
changeset 0 ed9695c8bcbe
child 3 b1602a5ab0a3
equal deleted inserted replaced
-1:000000000000 0:ed9695c8bcbe
       
     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 "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:  Video Telephony mediator plugin header
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32def.h>
       
    21 #include <w32std.h>
       
    22 #include <apacmdln.h>
       
    23 #include <apaflrec.h>
       
    24 #include <apgcli.h>
       
    25 #include <mediatordomainuids.h>
       
    26 #include <eikdll.h>
       
    27 #include <apgcli.h>
       
    28 #include <apgwgnam.h>
       
    29 #include <apgtask.h>
       
    30 #include <mediatorcommandstotelephonyapi.h>
       
    31 #include <videotelcontrolmediatorapi.h>
       
    32 #include <videoteltophonecommandsapi.h>
       
    33 #include "cvtmediatorplugin.h"
       
    34 
       
    35 
       
    36 // CONSTANTS
       
    37 #ifdef _DEBUG
       
    38 #define TRACE(x) RDebug::Print( _L(x) );
       
    39 #define TRACE2(x,y) RDebug::Print( _L(x),y );
       
    40 #else
       
    41 #define TRACE(x)
       
    42 #define TRACE2(x,y)
       
    43 #endif
       
    44                        
       
    45 // This array's values are used in algorithm defining if video telephone
       
    46 // application should be started. Previous state value is substracted from new 
       
    47 // state value and if result is greater than zero, app is started.
       
    48 // This tackles transitions where a state is for some reason skipped,
       
    49 // e.g. idle -> connected (dialling/ringing/answering states were not detected).
       
    50 // Negative value indicates call clearing.
       
    51 static const TInt KVtCallStateActionArray[] = {
       
    52     0, //ECallStateUnknown
       
    53     0, //ECallStateIdle
       
    54     1, // ECallStateDialling
       
    55     0, // ECallStateEmergencyDialling (not valid video call state)
       
    56     1, // ECallStateRinging
       
    57     1, // ECallStateConnecting
       
    58     1, // ECallStateConnected
       
    59     0, // ECallStateHangingUp
       
    60     0, // ECallStateHeld (not valid video call state)
       
    61     1, // ECallStateAnswering
       
    62     0, // ECallStateRejecting
       
    63     0  // ECallStateDisconnecting
       
    64     };
       
    65 
       
    66 static const TInt KVtAppNotReady = 5000;
       
    67 
       
    68 static const TInt KVtEngMdtrCmdTimeout = 500000;
       
    69 
       
    70 static const TInt KVtInitCallId = -1000;
       
    71 
       
    72 // array granularity is 2 (use dataport, release dataport commands)
       
    73 static const TInt KVtMdtrCmdArrayGranularity = 2;
       
    74 
       
    75 const TUid KVtCmVideoTelUiUid = { 0x101F8681 };
       
    76 
       
    77 static const TInt KRamNeededForVideoCalls = 4000000;
       
    78 
       
    79 // VT application path 
       
    80 _LIT( KVtCmVideoTelUiPath, "\\sys\\bin\\videotelui.exe" );
       
    81 
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // CMediatorTestPlugin::CMediatorTestPlugin
       
    85 // First phase construction.
       
    86 // -----------------------------------------------------------------------------
       
    87 CVtMediatorPlugin::CVtMediatorPlugin() : CMediatorPluginBase(),
       
    88     iCommandList( KVtMdtrCmdArrayGranularity ),
       
    89     iState( EWaitingAppLaunch ),
       
    90     iActiveVideoCallState( ECallStateUnknown ),
       
    91     iWaitingVideoCallState( ECallStateUnknown )
       
    92     
       
    93 	{
       
    94 	ClearData(iActiveVideoCallInfo, iActiveVideoCallState);
       
    95 	ClearData(iWaitingVideoCallInfo, iWaitingVideoCallState);
       
    96 	}
       
    97 	
       
    98 CMediatorPluginBase* CVtMediatorPlugin::NewL()
       
    99     {
       
   100     TRACE("CVtMediatorPlugin::NewL<")
       
   101     CVtMediatorPlugin* self = new (ELeave) CVtMediatorPlugin;
       
   102     TRACE("CVtMediatorPlugin::NewL>")
       
   103     return self;
       
   104     }
       
   105 
       
   106 // -----------------------------------------------------------------------------
       
   107 // Destructor.
       
   108 // -----------------------------------------------------------------------------
       
   109 CVtMediatorPlugin::~CVtMediatorPlugin()
       
   110 	{
       
   111 	TRACE("CVtMediatorPlugin::~CVtMediatorPlugin<")
       
   112     
       
   113 	if ( iMediatorNotifications )
       
   114 	    {
       
   115 	    iMediatorNotifications->UnregisterNotificationObserver();
       
   116 	    delete iMediatorNotifications;
       
   117 	    }
       
   118 
       
   119 	// ignore error
       
   120 	if ( iEventConsumer )
       
   121 	    {
       
   122 	    iEventConsumer->UnsubscribeEvent(
       
   123 	            KMediatorTelephonyDomain,
       
   124 	            KCatEventsFromTelephony,
       
   125 	            EPhoneEventCallData );     
       
   126 	    delete iEventConsumer;
       
   127 	    }
       
   128         
       
   129     // ignore error     
       
   130 	if ( iEventProvider )
       
   131 	    {
       
   132 	    iEventProvider->UnregisterEvent(
       
   133 	            KMediatorVideoTelephonyDomain,
       
   134 	            KCatVideotelInternalEvents,
       
   135 	            EVtMediatorEventVideoCallInformation );   
       
   136 	    delete iEventProvider;
       
   137 	    }
       
   138         
       
   139     // ignore error
       
   140 	if ( iCommandResponder )
       
   141 	    {
       
   142 	    iCommandResponder->UnregisterCommand(
       
   143 	                KMediatorVideoTelephonyDomain,
       
   144 	                KCatPhoneToVideotelCommands,
       
   145 	                iCommandList );
       
   146 	    iCommandList.Close();
       
   147 	    delete iCommandResponder;
       
   148 	    }
       
   149 	
       
   150 	delete iCommandInitiator;
       
   151     
       
   152            
       
   153     if( iAppDeathActive )
       
   154         {
       
   155         delete iAppDeathActive;
       
   156         iAppThread.Close();
       
   157         iWsSession.Close();
       
   158         
       
   159         }
       
   160 
       
   161     TRACE("CVtMediatorPlugin::~CVtMediatorPlugin>")
       
   162 	}
       
   163 
       
   164 // -----------------------------------------------------------------------------
       
   165 // StartL.
       
   166 // -----------------------------------------------------------------------------
       
   167 void CVtMediatorPlugin::StartL()
       
   168 	{
       
   169     TRACE("CVtMediatorPlugin.StartL<")
       
   170     
       
   171     // for monitoring VT app starting
       
   172     iMediatorNotifications = CMediatorNotifications::NewL();
       
   173     iMediatorNotifications->RegisterNotificationObserver( this );
       
   174     
       
   175     // consumer for call data events
       
   176     iEventConsumer = CMediatorEventConsumer::NewL( this );
       
   177     
       
   178     iCommandInitiator = CMediatorCommandInitiator::NewL( this );
       
   179     
       
   180     
       
   181     RegisterVtInternalEventL();
       
   182     
       
   183     RegisterDataportCommandL();       
       
   184           
       
   185     TRACE("CVtMediatorPlugin.StartL>")
       
   186 	}
       
   187 
       
   188 // -----------------------------------------------------------------------------
       
   189 // MediatorEventL.
       
   190 // -----------------------------------------------------------------------------
       
   191 void CVtMediatorPlugin::MediatorEventL( TUid /*aDomain*/,
       
   192                              TUid aCategory,
       
   193                              TInt aEventId,
       
   194                              const TDesC8& aData )
       
   195     {
       
   196     TRACE("CVtMediatorPlugin.MediatorEventL<")
       
   197     if ( aCategory == KCatEventsFromTelephony &&
       
   198          aEventId == EPhoneEventCallData )
       
   199         {
       
   200         TTelephonyCallDataParamPackage pckg;
       
   201         pckg.Copy( aData );
       
   202         const TTelephonyCallDataParam telCallData = pckg();        
       
   203         HandleCallStateChangeL( telCallData );        
       
   204         }
       
   205     TRACE("CVtMediatorPlugin.MediatorEventL>")
       
   206     }
       
   207 // -----------------------------------------------------------------------------
       
   208 // CVtMediatorPlugin::MediatorEventsAddedL
       
   209 //
       
   210 // subscribes to CLI event when it is registered
       
   211 // -----------------------------------------------------------------------------
       
   212 //
       
   213 void CVtMediatorPlugin::MediatorEventsAddedL( TUid aDomain/*aDomain*/,
       
   214                                    TUid aCategory,
       
   215                                    const REventList& aEvents )
       
   216     {
       
   217     TRACE("CVtMediatorPlugin.MediatorEventsAddedL<")
       
   218     
       
   219     if ( aCategory == KCatEventsFromTelephony )
       
   220         {
       
   221         ChangeCallDataEventSubscriptionL( aEvents, ETrue );
       
   222         }    
       
   223     TRACE("CVtMediatorPlugin.MediatorEventsAddedL>")
       
   224     }
       
   225 
       
   226 // -----------------------------------------------------------------------------
       
   227 // ?classname::?member_function
       
   228 //
       
   229 // (other items were commented in a header).
       
   230 // -----------------------------------------------------------------------------
       
   231 //
       
   232 void CVtMediatorPlugin::MediatorCommandsAddedL( TUid /*aDomain*/,
       
   233                                      TUid aCategory,
       
   234                                      const RCommandList& /*aCommands*/ )
       
   235     {
       
   236     TRACE("CVtMediatorPlugin.MediatorCommandsAddedL<")
       
   237     if ( aCategory == KCatPhoneToVideotelCommands )
       
   238         {
       
   239         HandleVtCommandRegistrationL();
       
   240         }
       
   241     TRACE("CVtMediatorPlugin.MediatorCommandsAddedL>")
       
   242     }
       
   243 
       
   244 // -----------------------------------------------------------------------------
       
   245 // ?classname::?member_function
       
   246 //
       
   247 // (other items were commented in a header).
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 void CVtMediatorPlugin::MediatorCategoryRemovedL( TUid /*aDomain*/,
       
   251     TUid /*aCategory*/ )
       
   252     {
       
   253     }
       
   254 
       
   255 // -----------------------------------------------------------------------------
       
   256 // ?classname::?member_function
       
   257 //
       
   258 // (other items were commented in a header).
       
   259 // -----------------------------------------------------------------------------
       
   260 //
       
   261 void CVtMediatorPlugin::MediatorEventsRemovedL( TUid /*aDomain*/,
       
   262                                      TUid aCategory,
       
   263                                      const REventList& aEvents )
       
   264     {
       
   265     TRACE("CVtMediatorPlugin.MediatorEventsRemovedL<")
       
   266     if ( aCategory == KCatEventsFromTelephony )
       
   267         {
       
   268         ChangeCallDataEventSubscriptionL( aEvents, EFalse );
       
   269         }    
       
   270     TRACE("CVtMediatorPlugin.MediatorEventsRemovedL>")
       
   271     }
       
   272 
       
   273 // -----------------------------------------------------------------------------
       
   274 // ?classname::?member_function
       
   275 //
       
   276 // (other items were commented in a header).
       
   277 // -----------------------------------------------------------------------------
       
   278 //
       
   279 void CVtMediatorPlugin::MediatorCommandsRemovedL( TUid /*aDomain*/,
       
   280                                        TUid aCategory,
       
   281                                        const RCommandList& /*aCommands*/ )
       
   282     {
       
   283     TRACE("CVtMediatorPlugin.MediatorCommandsRemovedL<")  
       
   284     if ( aCategory == KCatPhoneToVideotelCommands )
       
   285         {
       
   286         // VT has unregistered commands, meaning it is shutting down
       
   287         HandleVtCommandUnregistrationL();
       
   288         }
       
   289     TRACE("CVtMediatorPlugin.MediatorCommandsRemovedL>")
       
   290     }
       
   291 
       
   292 // -----------------------------------------------------------------------------
       
   293 // CVtMediatorPlugin::MediatorCommandL
       
   294 //
       
   295 // 
       
   296 // -----------------------------------------------------------------------------
       
   297 //
       
   298 void CVtMediatorPlugin::MediatorCommandL( TUid aDomain,
       
   299                                  TUid aCategory, 
       
   300                                  TInt aCommandId,
       
   301                                  TVersion /*aVersion*/, 
       
   302                                  const TDesC8& aData )
       
   303     {
       
   304     TRACE("CVtMediatorPlugin.MediatorCommandL<") 
       
   305     if ( aCategory == KCatPhoneToVideotelCommands )
       
   306         {
       
   307         if ( aCommandId == EVtCmdUseDataport )
       
   308             {
       
   309 #ifdef _DEBUG           
       
   310             // error in responding is ignored but printed on debug build
       
   311             const TInt err =
       
   312 #endif            
       
   313             iCommandResponder->IssueResponse( 
       
   314                 aDomain, aCategory, aCommandId, KErrNone, KNullDesC8() );
       
   315             TRACE2("CVtMediatorPlugin.MediatorCommandL EVtCmdUseDataport err=%d", err )
       
   316             HandleDataportCommandL( aData );
       
   317             }
       
   318         else if ( aCommandId == EVtCmdReleaseDataport )
       
   319             {
       
   320             if ( EReady == iState )
       
   321                 {
       
   322                 const TVersion version( 
       
   323                         KVideotelMdtrCommandsVersionMajor,
       
   324                         KVideotelMdtrCommandsVersionMinor,
       
   325                         KVideotelMdtrCommandsVersionBuild );
       
   326 
       
   327 #ifdef _DEBUG           
       
   328             // error in responding is ignored but printed on debug build
       
   329             const TInt err =
       
   330 #endif                          
       
   331                 iCommandInitiator->IssueCommand(
       
   332                         KMediatorVideoTelephonyDomain,
       
   333                         KCatVideotelInternalCommands,
       
   334                         EVtMediatorReleaseDataport,
       
   335                         version,
       
   336                         KNullDesC8() );
       
   337             TRACE2("CVtMediatorPlugin.MediatorCommandL EVtCmdReleaseDataport, send to VT err=%d", err )
       
   338                 
       
   339                 }
       
   340             else
       
   341                 {
       
   342 #ifdef _DEBUG           
       
   343                 // error in responding is ignored but printed on debug build
       
   344                 const TInt err =
       
   345 #endif            
       
   346                 iCommandResponder->IssueResponse( 
       
   347                         aDomain, 
       
   348                         aCategory, 
       
   349                         aCommandId, 
       
   350                         KErrNone, 
       
   351                         KNullDesC8() );
       
   352                 TRACE2("CVtMediatorPlugin.MediatorCommandL EVtCmdReleaseDataport, just Resp err=%d", err ) 
       
   353                 }
       
   354            
       
   355             }
       
   356         }
       
   357     TRACE("CVtMediatorPlugin.MediatorCommandL>")
       
   358     }
       
   359 
       
   360 // -----------------------------------------------------------------------------
       
   361 // CVtMediatorPlugin::CommandResponseL
       
   362 //
       
   363 // 
       
   364 // -----------------------------------------------------------------------------
       
   365 //
       
   366 void CVtMediatorPlugin::CommandResponseL( TUid aDomain, TUid aCategory, 
       
   367     TInt aCommandId, TInt /*aStatus*/, const TDesC8& /*aData*/ )
       
   368     {
       
   369     TRACE("CVtMediatorPlugin.CommandResponseL<")
       
   370     if( ( aDomain == KMediatorVideoTelephonyDomain ) &&
       
   371         ( aCategory == KCatVideotelInternalCommands ) )
       
   372         {
       
   373         TInt res =
       
   374         iCommandResponder->IssueResponse( 
       
   375                 KMediatorVideoTelephonyDomain,
       
   376                 KCatPhoneToVideotelCommands,
       
   377                 EVtCmdReleaseDataport, 
       
   378                 KErrNone, 
       
   379                 KNullDesC8() );         
       
   380          TRACE2("CVtMediatorPlugin.CommandResponseL, IssueResponse res: %d", res )  
       
   381          User::LeaveIfError( res );      
       
   382         }
       
   383     TRACE("CVtMediatorPlugin.CommandResponseL>")
       
   384     }
       
   385 
       
   386 // -----------------------------------------------------------------------------
       
   387 // CVtMediatorPlugin::CancelMediatorCommand
       
   388 //
       
   389 // no-op
       
   390 // -----------------------------------------------------------------------------
       
   391 //
       
   392 void CVtMediatorPlugin::CancelMediatorCommand( TUid /*aDomain*/,
       
   393                                       TUid /*aCategory*/, 
       
   394                                       TInt /*aCommandId*/ )
       
   395     {
       
   396     }
       
   397 // -----------------------------------------------------------------------------
       
   398 // CVtMediatorPlugin::ChangeCallDataEventSubscriptionL
       
   399 //
       
   400 // Takes care of 'call data' event subscription.
       
   401 // -----------------------------------------------------------------------------
       
   402 //
       
   403 void CVtMediatorPlugin::ChangeCallDataEventSubscriptionL(
       
   404     const REventList& aEvents,
       
   405     const TBool aEventRegistered )
       
   406     {
       
   407     TRACE("CVtMediatorPlugin.ChangeCLIEventSubscription<")
       
   408    
       
   409     TInt res( KErrNone );
       
   410     TInt eventCount = aEvents.Count();
       
   411     while ( eventCount-- )
       
   412         {
       
   413         const TEvent& aEvent = aEvents[ eventCount ];
       
   414         if ( aEvent.iEventId == EPhoneEventCallData )
       
   415             {
       
   416             if ( aEventRegistered )
       
   417                 {
       
   418                 // Phone has registered Call data event => subscribe it                
       
   419                 const TVersion version(
       
   420                     KTelephonyEventsVersionMajor,
       
   421                     KTelephonyEventsVersionMinor,
       
   422                     KTelephonyEventsVersionBuild );
       
   423                 res = iEventConsumer->SubscribeEvent(
       
   424                     KMediatorTelephonyDomain,
       
   425                     KCatEventsFromTelephony,
       
   426                     EPhoneEventCallData, version );
       
   427                 }
       
   428             else
       
   429                 {
       
   430                 // Phone has unregistered Call data event => unsubscribe it
       
   431                 res = iEventConsumer->UnsubscribeEvent(
       
   432                     KMediatorTelephonyDomain,
       
   433                     KCatEventsFromTelephony,
       
   434                     EPhoneEventCallData );
       
   435                 }
       
   436             TRACE2("   (un)subscribe result=%d", res )
       
   437             eventCount = 0; // break loop
       
   438             }
       
   439         }
       
   440     
       
   441     TRACE2("CVtMediatorPlugin.ChangeCLIEventSubscription result=%d>", res )
       
   442     User::LeaveIfError( res );
       
   443     }
       
   444     
       
   445 // -----------------------------------------------------------------------------
       
   446 // CVtMediatorPlugin::HandleVtCommandRegistrationL
       
   447 //
       
   448 // 
       
   449 // -----------------------------------------------------------------------------
       
   450 //
       
   451 void CVtMediatorPlugin::HandleVtCommandRegistrationL()
       
   452     {
       
   453     TRACE("CVtMediatorPlugin.HandleVtCommandRegistrationL<" )
       
   454     if ( iState == EWaitingEventRegistration )
       
   455         {
       
   456         // VT app registered commands => it can also receive events
       
   457         // NOTE: it is expected that VT application first subscribes
       
   458         // to internal events and only after that registers commands to
       
   459         // avoid timing problems.
       
   460         iState = EReady;
       
   461         delete iCallBack;
       
   462         iCallBack = NULL;
       
   463         TCallBack cb( &EventRaiserCallback, this );
       
   464         iCallBack = new ( ELeave ) CAsyncCallBack( cb, 
       
   465             CActive::EPriorityStandard );        
       
   466         TRACE("CVtMediatorPlugin enque async callback" )
       
   467         iCallBack->CallBack();        
       
   468         }
       
   469     TRACE("CVtMediatorPlugin.HandleVtCommandRegistrationL>" )
       
   470     }
       
   471 
       
   472 TInt CVtMediatorPlugin::EventRaiserCallback( TAny* aAny )
       
   473     {
       
   474     TRACE("CVtMediatorPlugin.EventRaiserCallback<" )
       
   475     CVtMediatorPlugin* plugin = reinterpret_cast<CVtMediatorPlugin*>( aAny );
       
   476     delete plugin->iCallBack;
       
   477     plugin->iCallBack = NULL;
       
   478     TRAP_IGNORE( plugin->RaiseVtEventL() );
       
   479     TRACE("CVtMediatorPlugin.EventRaiserCallback>" )
       
   480     return KErrNone;
       
   481     }
       
   482 
       
   483 // -----------------------------------------------------------------------------
       
   484 // CVtMediatorPlugin::
       
   485 //
       
   486 // 
       
   487 // -----------------------------------------------------------------------------
       
   488 //
       
   489 void CVtMediatorPlugin::HandleVtCommandUnregistrationL()
       
   490     {
       
   491     // unregistration means that VT app is shutting down.    
       
   492     TRACE("CVtMediatorPlugin.HandleVtCommandUnregistrationL<" )
       
   493     ClearData(iActiveVideoCallInfo, iActiveVideoCallState);
       
   494     //ClearData(iWaitingVideoCallInfo);
       
   495     TRACE("CVtMediatorPlugin.HandleVtCommandUnregistrationL>" )
       
   496     }
       
   497 
       
   498 
       
   499 // -----------------------------------------------------------------------------
       
   500 // CVtMediatorPlugin::
       
   501 //
       
   502 // 
       
   503 // -----------------------------------------------------------------------------
       
   504 //
       
   505 void CVtMediatorPlugin::LaunchVtAppL()
       
   506     {
       
   507         
       
   508     TRACE("CVtMediatorPlugin.LaunchVtAppL<" )
       
   509     
       
   510     if ( !IsEnoughMemory() )
       
   511         {
       
   512         const TVersion KTelephonyCmdVersion(
       
   513                 KTelephonyCommandsVersionMajor,
       
   514                 KTelephonyCommandsVersionMinor,
       
   515                 KTelephonyCommandsVersionBuild );
       
   516         const TInt res =
       
   517         iCommandInitiator->IssueCommand(
       
   518                 KMediatorTelephonyDomain,
       
   519                 KCatVideoTelToPhoneCommands,
       
   520                 EVtCmdLowMemory,
       
   521                 KTelephonyCmdVersion,
       
   522                 KNullDesC8() );
       
   523         ClearData(iActiveVideoCallInfo, iActiveVideoCallState);
       
   524         ClearData(iWaitingVideoCallInfo, iWaitingVideoCallState);
       
   525         TRACE("CVtMediatorPlugin.LaunchVtAppL, Insufficient Memory" )
       
   526         return;
       
   527         }
       
   528 
       
   529     iAppDeathActive = new ( ELeave ) CAppDeathActive( *this, iAppThread );
       
   530        
       
   531     User::LeaveIfError( iWsSession.Connect() );
       
   532 
       
   533     TInt wgId = 0;
       
   534     TBool found = EFalse;
       
   535 
       
   536     // Check if there is already application running. Then we do not 
       
   537     // start new one - rather we just monitor the existing one.
       
   538     while ( ( wgId != KErrNotFound ) && !found )
       
   539         {
       
   540         CApaWindowGroupName::FindByAppUid( 
       
   541             KVtCmVideoTelUiUid, 
       
   542             iWsSession, 
       
   543             wgId );
       
   544 
       
   545         TApaTask task( iWsSession );
       
   546         task.SetWgId( wgId );
       
   547         if ( task.Exists() )
       
   548             {
       
   549             if ( iAppThread.Open( task.ThreadId() ) == KErrNone )
       
   550                 {
       
   551                 TExitType exitType = iAppThread.ExitType();
       
   552                 found = ( exitType == EExitPending );
       
   553 
       
   554                 if ( found )
       
   555                     {
       
   556                     iAppThreadId = task.ThreadId();
       
   557                     }
       
   558                 }
       
   559             }
       
   560             
       
   561         if ( !found )
       
   562             {
       
   563             iAppThread.Close();
       
   564              }
       
   565         }
       
   566 
       
   567     // If application was not found, then launch new application.
       
   568     if ( !found )
       
   569         {
       
   570         TThreadId threadId;
       
   571 #ifndef SYMBIAN_SUPPORT_UI_FRAMEWORKS_V1
       
   572         CApaCommandLine* cmd = CApaCommandLine::NewLC();
       
   573         cmd->SetExecutableNameL( KVtCmVideoTelUiPath );
       
   574 #else // !SYMBIAN_SUPPORT_UI_FRAMEWORKS_V1
       
   575         CApaCommandLine* cmd = CApaCommandLine::NewLC( KVtCmVideoTelUiPath );
       
   576 #endif // SYMBIAN_SUPPORT_UI_FRAMEWORKS_V1
       
   577         cmd->SetCommandL( EApaCommandBackground );
       
   578             
       
   579         RApaLsSession session;
       
   580         User::LeaveIfError( session.Connect() );
       
   581         CleanupClosePushL( session );
       
   582             
       
   583         TInt err = session.StartApp( *cmd, threadId );
       
   584         if ( err > KErrNone )
       
   585             {
       
   586             err = KErrGeneral;
       
   587             }
       
   588         User::LeaveIfError( err );
       
   589         CleanupStack::PopAndDestroy( 2, cmd ); // CleanupClosePushL, cmd
       
   590         User::LeaveIfError( iAppThread.Open( threadId ) );
       
   591         iAppThreadId = threadId;
       
   592         }
       
   593 
       
   594     // Start active objects.
       
   595     iState = EWaitingEventRegistration;
       
   596     iAppDeathActive->Start();
       
   597     TRACE("CVtMediatorPlugin.LaunchVtAppL>" )
       
   598     }
       
   599 
       
   600 
       
   601 // -----------------------------------------------------------------------------
       
   602 // CVtMediatorPlugin::
       
   603 //
       
   604 // 
       
   605 // -----------------------------------------------------------------------------
       
   606 //
       
   607 void CVtMediatorPlugin::SaveCallData( const TTelephonyCallDataParam& aData, TVtVideoTelephonyCallInformation& iVtCallInfo )
       
   608     {
       
   609     TRACE("CVtMediatorPlugin.SaveCallData<" )
       
   610     iVtCallInfo.iDisplayText = aData.iCLIText.Left(
       
   611         TVtVideoTelephonyCallInformation::TDisplayTextMaxLength );
       
   612         
       
   613     TRACE2("CVtMediatorPlugin.SaveCallData iDisplayText=%S",
       
   614         &iVtCallInfo.iDisplayText );
       
   615                 
       
   616     iVtCallInfo.iCallId = aData.iCallId;
       
   617     
       
   618     if ( KNullDesC() != aData.iRemotePhoneNumber )
       
   619         {
       
   620         iVtCallInfo.iVoiceCallPossible = ETrue;
       
   621         }
       
   622     iVtCallInfo.iEventDataValidity |= 
       
   623         TVtVideoTelephonyCallInformation::EDisplayTextValid;
       
   624     TRACE2("CVtMediatorPlugin.SaveCallData data saved=%d>",
       
   625         aData.iCallType == ECallTypeVideo )
       
   626     }
       
   627 
       
   628                      
       
   629 // -----------------------------------------------------------------------------
       
   630 // CVtMediatorPlugin::
       
   631 //
       
   632 // 
       
   633 // -----------------------------------------------------------------------------
       
   634 //
       
   635 void CVtMediatorPlugin::HandleDataportCommandL( const TDesC8& aData )
       
   636     {
       
   637     TRACE("CVtMediatorPlugin.HandleDataportCommandL<" ) 
       
   638     TDataPortPackage pckg;
       
   639     pckg.Copy( aData );
       
   640     iActiveVideoCallInfo.iDataport = pckg();
       
   641     iActiveVideoCallInfo.iEventDataValidity |= 
       
   642         TVtVideoTelephonyCallInformation::EDataportValid;     
       
   643     RaiseVtEventL();
       
   644     TRACE("CVtMediatorPlugin.HandleDataportCommandL>" )
       
   645     }
       
   646 
       
   647                          
       
   648 // -----------------------------------------------------------------------------
       
   649 // CVtMediatorPlugin::ClearData
       
   650 //
       
   651 // 
       
   652 // -----------------------------------------------------------------------------
       
   653 //
       
   654 void CVtMediatorPlugin::ClearData(TVtVideoTelephonyCallInformation& aVtCallInfo, TCallState& aCallState)
       
   655     {
       
   656     TRACE("CVtMediatorPlugin.ClearData<" )
       
   657     if ( aVtCallInfo.iCallId == iActiveVideoCallInfo.iCallId )
       
   658         {
       
   659         iState = EWaitingAppLaunch;
       
   660         }
       
   661     aVtCallInfo.iEventDataValidity = 0;
       
   662     aVtCallInfo.iDataport.Zero();
       
   663     aVtCallInfo.iVoiceCallPossible = EFalse;
       
   664     //for video call, it should be 9/10
       
   665     //for other call, it will be from -1 to 8
       
   666     aVtCallInfo.iCallId = KVtInitCallId;
       
   667     aVtCallInfo.iDisplayText.Zero();
       
   668     aCallState = ECallStateIdle;
       
   669     TRACE("CVtMediatorPlugin.ClearData>" )
       
   670     }
       
   671 
       
   672 // -----------------------------------------------------------------------------
       
   673 // CVtMediatorPlugin::RegisterVtInternalEventL
       
   674 //
       
   675 // 
       
   676 // -----------------------------------------------------------------------------
       
   677 //
       
   678 void CVtMediatorPlugin::RegisterVtInternalEventL()
       
   679     {
       
   680     TRACE("CVtMediatorPlugin.RegisterVtInternalEventL<" )
       
   681     iEventProvider = CMediatorEventProvider::NewL();
       
   682     
       
   683     TVersion version(
       
   684         KVideotelMdtrEventVersionMajor,
       
   685         KVideotelMdtrEventVersionMinor,
       
   686         KVideotelMdtrEventVersionBuild );
       
   687 
       
   688     TCapabilitySet capSet;
       
   689     capSet.SetEmpty();
       
   690     capSet.AddCapability( ECapabilityReadDeviceData );
       
   691             
       
   692     const TInt err = iEventProvider->RegisterEvent(
       
   693         KMediatorVideoTelephonyDomain,
       
   694         KCatVideotelInternalEvents,
       
   695         EVtMediatorEventVideoCallInformation,
       
   696         version,
       
   697         capSet );
       
   698           
       
   699    
       
   700     TRACE2("CVtMediatorPlugin.RegisterVtInternalEventL err=%d>", err )
       
   701     User::LeaveIfError( err );
       
   702     }
       
   703 
       
   704 // -----------------------------------------------------------------------------
       
   705 // CVtMediatorPlugin::RegisterDataportCommandL
       
   706 //
       
   707 // 
       
   708 // -----------------------------------------------------------------------------
       
   709 //
       
   710 void CVtMediatorPlugin::RegisterDataportCommandL()
       
   711     {
       
   712     TRACE("CVtMediatorPlugin.RegisterDataportCommandL<" )
       
   713     iCommandResponder = CMediatorCommandResponder::NewL( this );
       
   714     
       
   715     TCapabilitySet capSet;
       
   716     capSet.SetEmpty();
       
   717     capSet.AddCapability( ECapabilityWriteDeviceData );
       
   718     MediatorService::TCommand command;
       
   719     
       
   720     command.iCaps = capSet;
       
   721     command.iVersion = TVersion( 
       
   722             KPhoneToVideotelCmdVersionMajor, 
       
   723             KPhoneToVideotelCmdVersionMinor,
       
   724             KPhoneToVideotelCmdVersionBuild );
       
   725     command.iTimeout = KVtEngMdtrCmdTimeout;
       
   726         
       
   727     // enable microphone command
       
   728     command.iCommandId = EVtCmdUseDataport;
       
   729     iCommandList.Append( command );
       
   730         
       
   731     // Releasedataport command
       
   732     capSet.SetEmpty();
       
   733     capSet.AddCapability( ECapabilityPowerMgmt );
       
   734     command.iCommandId = EVtCmdReleaseDataport;
       
   735     iCommandList.Append( command );
       
   736     
       
   737     const TInt err = iCommandResponder->RegisterCommand( 
       
   738         KMediatorVideoTelephonyDomain,
       
   739         KCatPhoneToVideotelCommands,
       
   740         iCommandList );    
       
   741     
       
   742     TRACE2("CVtMediatorPlugin.RegisterDataportCommandL err=%d>", err )
       
   743     User::LeaveIfError( err );
       
   744     }
       
   745 
       
   746 // -----------------------------------------------------------------------------
       
   747 // CVtMediatorPlugin::RaiseVtEventL
       
   748 //
       
   749 // Raises VT call info event if in suitable state, i.e. VT app has subscribed 
       
   750 // the event.
       
   751 // -----------------------------------------------------------------------------
       
   752 //
       
   753 void CVtMediatorPlugin::RaiseVtEventL()
       
   754     {
       
   755     TRACE("CVtMediatorPlugin.RaiseVtEventL<" )
       
   756     TInt result = KVtAppNotReady;  // does not cause leave
       
   757     TRACE2("CVtMediatorPlugin.RaiseVtEventL iState=%d>", 
       
   758             iState )
       
   759     TRACE2("CVtMediatorPlugin.RaiseVtEventL iActiveVideoCallState=%d>", 
       
   760             iActiveVideoCallState )            
       
   761     if ( iState == EReady && // application subscribed to the event
       
   762     
       
   763         // don't send event if video call is not starting/ongoing
       
   764          ( iActiveVideoCallState >= ECallStateDialling &&
       
   765          iActiveVideoCallState <= ECallStateConnected ) )
       
   766         {
       
   767         const TVersion version(
       
   768             KVideotelMdtrEventVersionMajor,
       
   769             KVideotelMdtrEventVersionMinor,
       
   770             KVideotelMdtrEventVersionBuild );            
       
   771             
       
   772         const TVtMediatorInfoPackage pckg( iActiveVideoCallInfo );
       
   773         result = iEventProvider->RaiseEvent(
       
   774             KMediatorVideoTelephonyDomain,
       
   775             KCatVideotelInternalEvents,
       
   776             EVtMediatorEventVideoCallInformation,
       
   777             version,
       
   778             pckg
       
   779             );
       
   780         }
       
   781     TRACE2("CVtMediatorPlugin.RaiseVtEventL result=%d>", result )
       
   782     User::LeaveIfError( result );
       
   783     }
       
   784 
       
   785 // -----------------------------------------------------------------------------
       
   786 // CVtMediatorPlugin::HandleCallStateChangeL
       
   787 //
       
   788 // Compares previous and new video call states and resolves based on result
       
   789 // if Video telephone applicaton should be launched.
       
   790 // -----------------------------------------------------------------------------
       
   791 //
       
   792 void CVtMediatorPlugin::HandleCallStateChangeL(
       
   793     const TTelephonyCallDataParam& aData )
       
   794     {
       
   795     TRACE("CVtMediatorPlugin.HandleCallStateChangeL<" )    
       
   796     
       
   797     TRACE2("CVtMediatorPlugin.HandleCallStateChangeL calltype=%d>", 
       
   798             aData.iCallType )
       
   799     TRACE2("CVtMediatorPlugin.HandleCallStateChangeL saved Activecallid=%d>", 
       
   800             iActiveVideoCallInfo.iCallId )
       
   801     TRACE2("CVtMediatorPlugin.HandleCallStateChangeL saved Waitingcallid=%d>", 
       
   802             iWaitingVideoCallInfo.iCallId )
       
   803     TRACE2("CVtMediatorPlugin.HandleCallStateChangeL callid=%d>", 
       
   804             aData.iCallId )   
       
   805     TRACE2("CVtMediatorPlugin.HandleCallStateChangeL ActiveCallOldState=%d>", 
       
   806             iActiveVideoCallState )
       
   807     TRACE2("CVtMediatorPlugin.HandleCallStateChangeL WaitingCallOldState=%d>", 
       
   808             iWaitingVideoCallState )
       
   809     TRACE2("CVtMediatorPlugin.HandleCallStateChangeL NewState=%d>",
       
   810             aData.iCallState )
       
   811             
       
   812     //if the call is waitingcall, just save/clear
       
   813     if ( aData.iCallType == ECallTypeVideo ||       
       
   814         // check also call id because in call clearing states call type may
       
   815         // be unspecified but call id is saved in call setup and we can
       
   816         // compare to it.
       
   817          iActiveVideoCallInfo.iCallId == aData.iCallId  ||
       
   818          iWaitingVideoCallInfo.iCallId == aData.iCallId )
       
   819         {
       
   820         TBool isWaitingCall = ETrue;
       
   821         
       
   822         /**
       
   823          * firstly we should check the callid to identify if it is a waitingcal/activecall
       
   824          * imagine the usecase that long press endkey to shutdown both calls.
       
   825          * after that checking iState
       
   826          */
       
   827         if ( iWaitingVideoCallInfo.iCallId == aData.iCallId )
       
   828             {
       
   829             isWaitingCall =  ETrue;
       
   830             }
       
   831         else if ( iActiveVideoCallInfo.iCallId == aData.iCallId )
       
   832             {
       
   833             isWaitingCall = EFalse;
       
   834             }
       
   835         //no vt app launched, this happens while vt first launching or end key to shutdown both calls
       
   836         else if ( iState == EWaitingAppLaunch )
       
   837             {
       
   838             isWaitingCall =  EFalse;
       
   839             }
       
   840         
       
   841         TRACE2("CVtMediatorPlugin.HandleCallStateChangeL isWaitingCall=%d>",
       
   842                 isWaitingCall)
       
   843         
       
   844         TCallState& callState = isWaitingCall?iWaitingVideoCallState:iActiveVideoCallState;
       
   845         TVtVideoTelephonyCallInformation& vtCallInfo = isWaitingCall?iWaitingVideoCallInfo:iActiveVideoCallInfo;
       
   846             
       
   847         TBool launchNeeded = KVtCallStateActionArray[ aData.iCallState ] -
       
   848                     KVtCallStateActionArray[callState] > 0;
       
   849         if ( isWaitingCall )
       
   850             {
       
   851             launchNeeded = EFalse;
       
   852             }
       
   853         callState = aData.iCallState;
       
   854             
       
   855         switch ( callState )
       
   856             {
       
   857             case ECallStateDialling:
       
   858             case ECallStateRinging:
       
   859             case ECallStateConnecting:
       
   860             case ECallStateConnected:
       
   861                 SaveCallData( aData,  vtCallInfo);
       
   862                 break;
       
   863             default:
       
   864                 // data becomes invalid in other states (=call clearing/idle)
       
   865                 ClearData(vtCallInfo, callState);
       
   866                 break;
       
   867             }
       
   868         if ( launchNeeded )
       
   869             {
       
   870             LaunchVtAppL();
       
   871             }
       
   872         if ( !isWaitingCall )
       
   873             {
       
   874             RaiseVtEventL();
       
   875             }
       
   876         }
       
   877         
       
   878     TRACE("CVtMediatorPlugin.HandleCallStateChangeL>" )
       
   879     }
       
   880 
       
   881 // -----------------------------------------------------------------------------
       
   882 // CVtMediatorPlugin::IsEnoughMemory
       
   883 //
       
   884 // Check if there is enough memory to launch
       
   885 // -----------------------------------------------------------------------------
       
   886 //
       
   887 TBool CVtMediatorPlugin::IsEnoughMemory()
       
   888     {
       
   889     TRACE("CVtMediatorPlugin::IsEnoughMemory<" )    
       
   890     // Fetch amount of free memory.
       
   891     TMemoryInfoV1Buf memory;
       
   892     UserHal::MemoryInfo( memory );
       
   893     TInt freeRam = (TInt)( memory().iFreeRamInBytes );
       
   894     TRACE2("CVtMediatorPlugin::IsEnoughMemory: freeRam = %d", freeRam )
       
   895     
       
   896     TBool enoughRam = ETrue;
       
   897 
       
   898     if ( freeRam < KRamNeededForVideoCalls )
       
   899         {
       
   900         FreeRam();
       
   901         freeRam = (TInt)( memory().iFreeRamInBytes );
       
   902         TRACE2("CVtMediatorPlugin::IsEnoughMemory: after free, freeRam = %d", freeRam )
       
   903         if ( freeRam < KRamNeededForVideoCalls )
       
   904             {
       
   905             enoughRam = EFalse;
       
   906             TRACE ("CVtMediatorPlugin::IsEnoughMemory : Not enough RAM")
       
   907                 
       
   908             }
       
   909         }
       
   910     TRACE("CVtMediatorPlugin::IsEnoughMemory>" )    
       
   911     return enoughRam;
       
   912     }  
       
   913 // -----------------------------------------------------------------------------
       
   914 // CVtMediatorPlugin::FreeRam
       
   915 // Try to free memory to match the memory usage of VT
       
   916 // -----------------------------------------------------------------------------
       
   917 //
       
   918 void CVtMediatorPlugin::FreeRam()
       
   919     {
       
   920     TRACE("CVtMediatorPlugin.FreeRam()<")
       
   921     User::CompressAllHeaps();
       
   922     TRACE("CVtMediatorPlugin.FreeRam()>")
       
   923     }
       
   924 
       
   925 // -----------------------------------------------------------------------------
       
   926 // CVtMediatorPlugin::StopDeathActiveL
       
   927 // -----------------------------------------------------------------------------
       
   928 //
       
   929 void CVtMediatorPlugin::StopDeathActiveL()
       
   930     {
       
   931     TRACE("CVtMediatorPlugin.StopDeathActive<")
       
   932     delete iAppDeathActive;
       
   933     iAppThread.Close();
       
   934     iWsSession.Close();
       
   935     //if there is a waiting call, check if we need to launch it
       
   936     TRACE2("CVtMediatorPlugin.StopDeathActive WaitintCallID=%d>",
       
   937             iWaitingVideoCallInfo.iCallId)
       
   938     if ( iWaitingVideoCallInfo.iCallId != KVtInitCallId )
       
   939         {
       
   940         iActiveVideoCallInfo = iWaitingVideoCallInfo;
       
   941         iActiveVideoCallState = iWaitingVideoCallState;
       
   942         ClearData(iWaitingVideoCallInfo, iWaitingVideoCallState);
       
   943         
       
   944         if ( iActiveVideoCallState == ECallStateDialling ||
       
   945                 iActiveVideoCallState ==  ECallStateRinging ||
       
   946                 iActiveVideoCallState == ECallStateConnecting ||
       
   947                 iActiveVideoCallState == ECallStateConnected ||
       
   948                 iActiveVideoCallState == ECallStateAnswering )
       
   949                 {
       
   950                 LaunchVtAppL();
       
   951                 RaiseVtEventL();
       
   952                 }
       
   953         }
       
   954     TRACE("CVtMediatorPlugin.StopDeathActive>")
       
   955     }
       
   956 // -----------------------------------------------------------------------------
       
   957 // CVtMediatorPlugin::CAppDeathActive::CAppDeathActive
       
   958 // -----------------------------------------------------------------------------
       
   959 //
       
   960 CVtMediatorPlugin::CAppDeathActive::CAppDeathActive( 
       
   961         CVtMediatorPlugin& aMediatorPlugin,
       
   962         RThread& aAppThread
       
   963     )
       
   964     : CActive( CActive::EPriorityStandard ),
       
   965       iMediatorPlugin( aMediatorPlugin ),
       
   966       iAppThread( aAppThread )
       
   967       
       
   968     {
       
   969     CActiveScheduler::Add( this );
       
   970     }
       
   971 
       
   972 // -----------------------------------------------------------------------------
       
   973 // CVtMediatorPlugin::CAppDeathActive::~CAppDeathActive
       
   974 // -----------------------------------------------------------------------------
       
   975 //
       
   976 CVtMediatorPlugin::CAppDeathActive::~CAppDeathActive()
       
   977     {
       
   978     TRACE("CVtMediatorPlugin.~CAppDeathActive")
       
   979     Cancel();
       
   980     }
       
   981 
       
   982 // -----------------------------------------------------------------------------
       
   983 // CVtMediatorPlugin::CAppDeathActive::Start
       
   984 // -----------------------------------------------------------------------------
       
   985 //
       
   986 void CVtMediatorPlugin::CAppDeathActive::Start()
       
   987     {
       
   988     TRACE("CVtMediatorPlugin.Start<")
       
   989     Cancel();
       
   990     iAppThread.Logon( iStatus );
       
   991     SetActive();
       
   992     TRACE("CVtMediatorPlugin.Start>")
       
   993     }
       
   994 
       
   995 // -----------------------------------------------------------------------------
       
   996 // CVtMediatorPlugin::CAppDeathActive::RunL
       
   997 // -----------------------------------------------------------------------------
       
   998 //
       
   999 void CVtMediatorPlugin::CAppDeathActive::RunL()
       
  1000     {
       
  1001     //do something here
       
  1002     TRACE("CVtMediatorPlugin.RunL<")
       
  1003     iMediatorPlugin.StopDeathActiveL();
       
  1004     TRACE("CVtMediatorPlugin.RunL>")
       
  1005       
       
  1006     }
       
  1007         
       
  1008 // -----------------------------------------------------------------------------
       
  1009 // CVtMediatorPlugin::CAppDeathActive::DoCancel
       
  1010 // -----------------------------------------------------------------------------
       
  1011 //
       
  1012 void CVtMediatorPlugin::CAppDeathActive::DoCancel()
       
  1013     {
       
  1014     iAppThread.LogonCancel( iStatus );
       
  1015     }
       
  1016         
       
  1017 // -----------------------------------------------------------------------------
       
  1018 // CVtMediatorPlugin::CAppDeathActive::RunError
       
  1019 // -----------------------------------------------------------------------------
       
  1020 //
       
  1021 TInt CVtMediatorPlugin::CAppDeathActive::RunError( TInt /*aError*/ )
       
  1022     {
       
  1023     return KErrNone;
       
  1024     }