--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vtengines/vtmediatorplugin/src/cvtmediatorplugin.cpp Wed Jun 23 18:14:26 2010 +0300
@@ -0,0 +1,1025 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Video Telephony mediator plugin header
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32def.h>
+#include <w32std.h>
+#include <apacmdln.h>
+#include <apaflrec.h>
+#include <apgcli.h>
+#include <MediatorDomainUIDs.h>
+#include <eikdll.h>
+#include <apgcli.h>
+#include <apgwgnam.h>
+#include <apgtask.h>
+#include <mediatorcommandstotelephonyapi.h>
+#include <videotelcontrolmediatorapi.h>
+#include <videoteltophonecommandsapi.h>
+#include "cvtmediatorplugin.h"
+
+
+// CONSTANTS
+#ifdef _DEBUG
+#define TRACE(x) RDebug::Print( _L(x) );
+#define TRACE2(x,y) RDebug::Print( _L(x),y );
+#else
+#define TRACE(x)
+#define TRACE2(x,y)
+#endif
+
+// This array's values are used in algorithm defining if video telephone
+// application should be started. Previous state value is substracted from new
+// state value and if result is greater than zero, app is started.
+// This tackles transitions where a state is for some reason skipped,
+// e.g. idle -> connected (dialling/ringing/answering states were not detected).
+// Negative value indicates call clearing.
+static const TInt KVtCallStateActionArray[] = {
+ 0, //ECallStateUnknown
+ 0, //ECallStateIdle
+ 1, // ECallStateDialling
+ 0, // ECallStateEmergencyDialling (not valid video call state)
+ 1, // ECallStateRinging
+ 1, // ECallStateConnecting
+ 1, // ECallStateConnected
+ 0, // ECallStateHangingUp
+ 0, // ECallStateHeld (not valid video call state)
+ 1, // ECallStateAnswering
+ 0, // ECallStateRejecting
+ 0 // ECallStateDisconnecting
+ };
+
+static const TInt KVtAppNotReady = 5000;
+
+static const TInt KVtEngMdtrCmdTimeout = 500000;
+
+static const TInt KVtInitCallId = -1000;
+
+// array granularity is 2 (use dataport, release dataport commands)
+static const TInt KVtMdtrCmdArrayGranularity = 2;
+
+const TUid KVtCmVideoTelUiUid = { 0x101F8681 };
+
+static const TInt KRamNeededForVideoCalls = 4000000;
+
+// VT application path
+_LIT( KVtCmVideoTelUiPath, "\\sys\\bin\\videotelui.exe" );
+
+
+// -----------------------------------------------------------------------------
+// CMediatorTestPlugin::CMediatorTestPlugin
+// First phase construction.
+// -----------------------------------------------------------------------------
+CVtMediatorPlugin::CVtMediatorPlugin() : CMediatorPluginBase(),
+ iCommandList( KVtMdtrCmdArrayGranularity ),
+ iState( EWaitingAppLaunch ),
+ iActiveVideoCallState( ECallStateUnknown ),
+ iWaitingVideoCallState( ECallStateUnknown )
+
+ {
+ ClearData(iActiveVideoCallInfo, iActiveVideoCallState);
+ ClearData(iWaitingVideoCallInfo, iWaitingVideoCallState);
+ }
+
+CMediatorPluginBase* CVtMediatorPlugin::NewL()
+ {
+ TRACE("CVtMediatorPlugin::NewL<")
+ CVtMediatorPlugin* self = new (ELeave) CVtMediatorPlugin;
+ TRACE("CVtMediatorPlugin::NewL>")
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+CVtMediatorPlugin::~CVtMediatorPlugin()
+ {
+ TRACE("CVtMediatorPlugin::~CVtMediatorPlugin<")
+
+ if ( iMediatorNotifications )
+ {
+ iMediatorNotifications->UnregisterNotificationObserver();
+ delete iMediatorNotifications;
+ }
+
+ // ignore error
+ if ( iEventConsumer )
+ {
+ iEventConsumer->UnsubscribeEvent(
+ KMediatorTelephonyDomain,
+ KCatEventsFromTelephony,
+ EPhoneEventCallData );
+ delete iEventConsumer;
+ }
+
+ // ignore error
+ if ( iEventProvider )
+ {
+ iEventProvider->UnregisterEvent(
+ KMediatorVideoTelephonyDomain,
+ KCatVideotelInternalEvents,
+ EVtMediatorEventVideoCallInformation );
+ delete iEventProvider;
+ }
+
+ // ignore error
+ if ( iCommandResponder )
+ {
+ iCommandResponder->UnregisterCommand(
+ KMediatorVideoTelephonyDomain,
+ KCatPhoneToVideotelCommands,
+ iCommandList );
+ iCommandList.Close();
+ delete iCommandResponder;
+ }
+
+ delete iCommandInitiator;
+
+
+ if( iAppDeathActive )
+ {
+ delete iAppDeathActive;
+ iAppThread.Close();
+ }
+
+ TRACE("CVtMediatorPlugin::~CVtMediatorPlugin>")
+ }
+
+// -----------------------------------------------------------------------------
+// StartL.
+// -----------------------------------------------------------------------------
+void CVtMediatorPlugin::StartL()
+ {
+ TRACE("CVtMediatorPlugin.StartL<")
+
+ // for monitoring VT app starting
+ iMediatorNotifications = CMediatorNotifications::NewL();
+ iMediatorNotifications->RegisterNotificationObserver( this );
+
+ // consumer for call data events
+ iEventConsumer = CMediatorEventConsumer::NewL( this );
+
+ iCommandInitiator = CMediatorCommandInitiator::NewL( this );
+
+
+ RegisterVtInternalEventL();
+
+ RegisterDataportCommandL();
+
+ TRACE("CVtMediatorPlugin.StartL>")
+ }
+
+// -----------------------------------------------------------------------------
+// MediatorEventL.
+// -----------------------------------------------------------------------------
+void CVtMediatorPlugin::MediatorEventL( TUid /*aDomain*/,
+ TUid aCategory,
+ TInt aEventId,
+ const TDesC8& aData )
+ {
+ TRACE("CVtMediatorPlugin.MediatorEventL<")
+ if ( aCategory == KCatEventsFromTelephony &&
+ aEventId == EPhoneEventCallData )
+ {
+ TTelephonyCallDataParamPackage pckg;
+ pckg.Copy( aData );
+ const TTelephonyCallDataParam telCallData = pckg();
+ HandleCallStateChangeL( telCallData );
+ }
+ TRACE("CVtMediatorPlugin.MediatorEventL>")
+ }
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::MediatorEventsAddedL
+//
+// subscribes to CLI event when it is registered
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::MediatorEventsAddedL( TUid aDomain/*aDomain*/,
+ TUid aCategory,
+ const REventList& aEvents )
+ {
+ TRACE("CVtMediatorPlugin.MediatorEventsAddedL<")
+
+ if ( aCategory == KCatEventsFromTelephony )
+ {
+ ChangeCallDataEventSubscriptionL( aEvents, ETrue );
+ }
+ TRACE("CVtMediatorPlugin.MediatorEventsAddedL>")
+ }
+
+// -----------------------------------------------------------------------------
+// ?classname::?member_function
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::MediatorCommandsAddedL( TUid /*aDomain*/,
+ TUid aCategory,
+ const RCommandList& /*aCommands*/ )
+ {
+ TRACE("CVtMediatorPlugin.MediatorCommandsAddedL<")
+ if ( aCategory == KCatPhoneToVideotelCommands )
+ {
+ HandleVtCommandRegistrationL();
+ }
+ TRACE("CVtMediatorPlugin.MediatorCommandsAddedL>")
+ }
+
+// -----------------------------------------------------------------------------
+// ?classname::?member_function
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::MediatorCategoryRemovedL( TUid /*aDomain*/,
+ TUid /*aCategory*/ )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// ?classname::?member_function
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::MediatorEventsRemovedL( TUid /*aDomain*/,
+ TUid aCategory,
+ const REventList& aEvents )
+ {
+ TRACE("CVtMediatorPlugin.MediatorEventsRemovedL<")
+ if ( aCategory == KCatEventsFromTelephony )
+ {
+ ChangeCallDataEventSubscriptionL( aEvents, EFalse );
+ }
+ TRACE("CVtMediatorPlugin.MediatorEventsRemovedL>")
+ }
+
+// -----------------------------------------------------------------------------
+// ?classname::?member_function
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::MediatorCommandsRemovedL( TUid /*aDomain*/,
+ TUid aCategory,
+ const RCommandList& /*aCommands*/ )
+ {
+ TRACE("CVtMediatorPlugin.MediatorCommandsRemovedL<")
+ if ( aCategory == KCatPhoneToVideotelCommands )
+ {
+ // VT has unregistered commands, meaning it is shutting down
+ HandleVtCommandUnregistrationL();
+ }
+ TRACE("CVtMediatorPlugin.MediatorCommandsRemovedL>")
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::MediatorCommandL
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::MediatorCommandL( TUid aDomain,
+ TUid aCategory,
+ TInt aCommandId,
+ TVersion /*aVersion*/,
+ const TDesC8& aData )
+ {
+ TRACE("CVtMediatorPlugin.MediatorCommandL<")
+ if ( aCategory == KCatPhoneToVideotelCommands )
+ {
+ if ( aCommandId == EVtCmdUseDataport )
+ {
+#ifdef _DEBUG
+ // error in responding is ignored but printed on debug build
+ const TInt err =
+#endif
+ iCommandResponder->IssueResponse(
+ aDomain, aCategory, aCommandId, KErrNone, KNullDesC8() );
+ TRACE2("CVtMediatorPlugin.MediatorCommandL EVtCmdUseDataport err=%d", err )
+ HandleDataportCommandL( aData );
+ }
+ else if ( aCommandId == EVtCmdReleaseDataport )
+ {
+ if ( EReady == iState )
+ {
+ const TVersion version(
+ KVideotelMdtrCommandsVersionMajor,
+ KVideotelMdtrCommandsVersionMinor,
+ KVideotelMdtrCommandsVersionBuild );
+
+#ifdef _DEBUG
+ // error in responding is ignored but printed on debug build
+ const TInt err =
+#endif
+ iCommandInitiator->IssueCommand(
+ KMediatorVideoTelephonyDomain,
+ KCatVideotelInternalCommands,
+ EVtMediatorReleaseDataport,
+ version,
+ KNullDesC8() );
+ TRACE2("CVtMediatorPlugin.MediatorCommandL EVtCmdReleaseDataport, send to VT err=%d", err )
+
+ }
+ else
+ {
+#ifdef _DEBUG
+ // error in responding is ignored but printed on debug build
+ const TInt err =
+#endif
+ iCommandResponder->IssueResponse(
+ aDomain,
+ aCategory,
+ aCommandId,
+ KErrNone,
+ KNullDesC8() );
+ TRACE2("CVtMediatorPlugin.MediatorCommandL EVtCmdReleaseDataport, just Resp err=%d", err )
+ }
+
+ }
+ }
+ TRACE("CVtMediatorPlugin.MediatorCommandL>")
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::CommandResponseL
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::CommandResponseL( TUid aDomain, TUid aCategory,
+ TInt aCommandId, TInt /*aStatus*/, const TDesC8& /*aData*/ )
+ {
+ TRACE("CVtMediatorPlugin.CommandResponseL<")
+ if( ( aDomain == KMediatorVideoTelephonyDomain ) &&
+ ( aCategory == KCatVideotelInternalCommands ) )
+ {
+ TInt res =
+ iCommandResponder->IssueResponse(
+ KMediatorVideoTelephonyDomain,
+ KCatPhoneToVideotelCommands,
+ EVtCmdReleaseDataport,
+ KErrNone,
+ KNullDesC8() );
+ TRACE2("CVtMediatorPlugin.CommandResponseL, IssueResponse res: %d", res )
+ User::LeaveIfError( res );
+ }
+ TRACE("CVtMediatorPlugin.CommandResponseL>")
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::CancelMediatorCommand
+//
+// no-op
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::CancelMediatorCommand( TUid /*aDomain*/,
+ TUid /*aCategory*/,
+ TInt /*aCommandId*/ )
+ {
+ }
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::ChangeCallDataEventSubscriptionL
+//
+// Takes care of 'call data' event subscription.
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::ChangeCallDataEventSubscriptionL(
+ const REventList& aEvents,
+ const TBool aEventRegistered )
+ {
+ TRACE("CVtMediatorPlugin.ChangeCLIEventSubscription<")
+
+ TInt res( KErrNone );
+ TInt eventCount = aEvents.Count();
+ while ( eventCount-- )
+ {
+ const TEvent& aEvent = aEvents[ eventCount ];
+ if ( aEvent.iEventId == EPhoneEventCallData )
+ {
+ if ( aEventRegistered )
+ {
+ // Phone has registered Call data event => subscribe it
+ const TVersion version(
+ KTelephonyEventsVersionMajor,
+ KTelephonyEventsVersionMinor,
+ KTelephonyEventsVersionBuild );
+ res = iEventConsumer->SubscribeEvent(
+ KMediatorTelephonyDomain,
+ KCatEventsFromTelephony,
+ EPhoneEventCallData, version );
+ }
+ else
+ {
+ // Phone has unregistered Call data event => unsubscribe it
+ res = iEventConsumer->UnsubscribeEvent(
+ KMediatorTelephonyDomain,
+ KCatEventsFromTelephony,
+ EPhoneEventCallData );
+ }
+ TRACE2(" (un)subscribe result=%d", res )
+ eventCount = 0; // break loop
+ }
+ }
+
+ TRACE2("CVtMediatorPlugin.ChangeCLIEventSubscription result=%d>", res )
+ User::LeaveIfError( res );
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::HandleVtCommandRegistrationL
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::HandleVtCommandRegistrationL()
+ {
+ TRACE("CVtMediatorPlugin.HandleVtCommandRegistrationL<" )
+ if ( iState == EWaitingEventRegistration )
+ {
+ // VT app registered commands => it can also receive events
+ // NOTE: it is expected that VT application first subscribes
+ // to internal events and only after that registers commands to
+ // avoid timing problems.
+ iState = EReady;
+ delete iCallBack;
+ iCallBack = NULL;
+ TCallBack cb( &EventRaiserCallback, this );
+ iCallBack = new ( ELeave ) CAsyncCallBack( cb,
+ CActive::EPriorityStandard );
+ TRACE("CVtMediatorPlugin enque async callback" )
+ iCallBack->CallBack();
+ }
+ TRACE("CVtMediatorPlugin.HandleVtCommandRegistrationL>" )
+ }
+
+TInt CVtMediatorPlugin::EventRaiserCallback( TAny* aAny )
+ {
+ TRACE("CVtMediatorPlugin.EventRaiserCallback<" )
+ CVtMediatorPlugin* plugin = reinterpret_cast<CVtMediatorPlugin*>( aAny );
+ delete plugin->iCallBack;
+ plugin->iCallBack = NULL;
+ TRAP_IGNORE( plugin->RaiseVtEventL() );
+ TRACE("CVtMediatorPlugin.EventRaiserCallback>" )
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::HandleVtCommandUnregistrationL()
+ {
+ // unregistration means that VT app is shutting down.
+ TRACE("CVtMediatorPlugin.HandleVtCommandUnregistrationL<" )
+ ClearData(iActiveVideoCallInfo, iActiveVideoCallState);
+ //ClearData(iWaitingVideoCallInfo);
+ TRACE("CVtMediatorPlugin.HandleVtCommandUnregistrationL>" )
+ }
+
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::LaunchVtAppL()
+ {
+
+ TRACE("CVtMediatorPlugin.LaunchVtAppL<" )
+
+ if ( !IsEnoughMemory() )
+ {
+ const TVersion KTelephonyCmdVersion(
+ KTelephonyCommandsVersionMajor,
+ KTelephonyCommandsVersionMinor,
+ KTelephonyCommandsVersionBuild );
+ const TInt res =
+ iCommandInitiator->IssueCommand(
+ KMediatorTelephonyDomain,
+ KCatVideoTelToPhoneCommands,
+ EVtCmdLowMemory,
+ KTelephonyCmdVersion,
+ KNullDesC8() );
+ ClearData(iActiveVideoCallInfo, iActiveVideoCallState);
+ ClearData(iWaitingVideoCallInfo, iWaitingVideoCallState);
+ TRACE("CVtMediatorPlugin.LaunchVtAppL, Insufficient Memory" )
+ return;
+ }
+
+ iAppDeathActive = new ( ELeave ) CAppDeathActive( *this, iAppThread );
+
+ RWsSession wsSession;
+ User::LeaveIfError( wsSession.Connect() );
+ CleanupClosePushL( wsSession );
+
+ TInt wgId = 0;
+ TBool found = EFalse;
+
+ // Check if there is already application running. Then we do not
+ // start new one - rather we just monitor the existing one.
+ while ( ( wgId != KErrNotFound ) && !found )
+ {
+ CApaWindowGroupName::FindByAppUid(
+ KVtCmVideoTelUiUid,
+ wsSession,
+ wgId );
+
+ TApaTask task( wsSession );
+ task.SetWgId( wgId );
+ if ( task.Exists() )
+ {
+ if ( iAppThread.Open( task.ThreadId() ) == KErrNone )
+ {
+ TExitType exitType = iAppThread.ExitType();
+ found = ( exitType == EExitPending );
+
+ if ( found )
+ {
+ iAppThreadId = task.ThreadId();
+ }
+ }
+ }
+
+ if ( !found )
+ {
+ iAppThread.Close();
+ }
+ }
+ CleanupStack::PopAndDestroy(); // CleanupClosePushL
+
+ // If application was not found, then launch new application.
+ if ( !found )
+ {
+ TThreadId threadId;
+#ifndef SYMBIAN_SUPPORT_UI_FRAMEWORKS_V1
+ CApaCommandLine* cmd = CApaCommandLine::NewLC();
+ cmd->SetExecutableNameL( KVtCmVideoTelUiPath );
+#else // !SYMBIAN_SUPPORT_UI_FRAMEWORKS_V1
+ CApaCommandLine* cmd = CApaCommandLine::NewLC( KVtCmVideoTelUiPath );
+#endif // SYMBIAN_SUPPORT_UI_FRAMEWORKS_V1
+ cmd->SetCommandL( EApaCommandBackground );
+
+ RApaLsSession session;
+ User::LeaveIfError( session.Connect() );
+ CleanupClosePushL( session );
+
+ TInt err = session.StartApp( *cmd, threadId );
+ if ( err > KErrNone )
+ {
+ err = KErrGeneral;
+ }
+ User::LeaveIfError( err );
+ CleanupStack::PopAndDestroy( 2, cmd ); // CleanupClosePushL, cmd
+ User::LeaveIfError( iAppThread.Open( threadId ) );
+ iAppThreadId = threadId;
+ }
+
+ // Start active objects.
+ iState = EWaitingEventRegistration;
+ iAppDeathActive->Start();
+ TRACE("CVtMediatorPlugin.LaunchVtAppL>" )
+ }
+
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::SaveCallData( const TTelephonyCallDataParam& aData, TVtVideoTelephonyCallInformation& iVtCallInfo )
+ {
+ TRACE("CVtMediatorPlugin.SaveCallData<" )
+ iVtCallInfo.iDisplayText = aData.iCLIText.Left(
+ TVtVideoTelephonyCallInformation::TDisplayTextMaxLength );
+
+ TRACE2("CVtMediatorPlugin.SaveCallData iDisplayText=%S",
+ &iVtCallInfo.iDisplayText );
+
+ iVtCallInfo.iCallId = aData.iCallId;
+
+ if ( KNullDesC() != aData.iRemotePhoneNumber )
+ {
+ iVtCallInfo.iVoiceCallPossible = ETrue;
+ }
+ iVtCallInfo.iPhoneNumText = aData.iRemotePhoneNumber;
+ iVtCallInfo.iEventDataValidity |=
+ TVtVideoTelephonyCallInformation::EDisplayTextValid;
+ TRACE2("CVtMediatorPlugin.SaveCallData data saved=%d>",
+ aData.iCallType == ECallTypeVideo )
+ }
+
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::HandleDataportCommandL( const TDesC8& aData )
+ {
+ TRACE("CVtMediatorPlugin.HandleDataportCommandL<" )
+ TDataPortPackage pckg;
+ pckg.Copy( aData );
+ iActiveVideoCallInfo.iDataport = pckg();
+ iActiveVideoCallInfo.iEventDataValidity |=
+ TVtVideoTelephonyCallInformation::EDataportValid;
+ RaiseVtEventL();
+ TRACE("CVtMediatorPlugin.HandleDataportCommandL>" )
+ }
+
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::ClearData
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::ClearData(TVtVideoTelephonyCallInformation& aVtCallInfo, TCallState& aCallState)
+ {
+ TRACE("CVtMediatorPlugin.ClearData<" )
+ if ( aVtCallInfo.iCallId == iActiveVideoCallInfo.iCallId )
+ {
+ iState = EWaitingAppLaunch;
+ }
+ aVtCallInfo.iEventDataValidity = 0;
+ aVtCallInfo.iDataport.Zero();
+ aVtCallInfo.iVoiceCallPossible = EFalse;
+ //for video call, it should be 9/10
+ //for other call, it will be from -1 to 8
+ aVtCallInfo.iCallId = KVtInitCallId;
+ aVtCallInfo.iDisplayText.Zero();
+ aCallState = ECallStateIdle;
+ TRACE("CVtMediatorPlugin.ClearData>" )
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::RegisterVtInternalEventL
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::RegisterVtInternalEventL()
+ {
+ TRACE("CVtMediatorPlugin.RegisterVtInternalEventL<" )
+ iEventProvider = CMediatorEventProvider::NewL();
+
+ TVersion version(
+ KVideotelMdtrEventVersionMajor,
+ KVideotelMdtrEventVersionMinor,
+ KVideotelMdtrEventVersionBuild );
+
+ TCapabilitySet capSet;
+ capSet.SetEmpty();
+ capSet.AddCapability( ECapabilityReadDeviceData );
+
+ const TInt err = iEventProvider->RegisterEvent(
+ KMediatorVideoTelephonyDomain,
+ KCatVideotelInternalEvents,
+ EVtMediatorEventVideoCallInformation,
+ version,
+ capSet );
+
+
+ TRACE2("CVtMediatorPlugin.RegisterVtInternalEventL err=%d>", err )
+ User::LeaveIfError( err );
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::RegisterDataportCommandL
+//
+//
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::RegisterDataportCommandL()
+ {
+ TRACE("CVtMediatorPlugin.RegisterDataportCommandL<" )
+ iCommandResponder = CMediatorCommandResponder::NewL( this );
+
+ TCapabilitySet capSet;
+ capSet.SetEmpty();
+ capSet.AddCapability( ECapabilityWriteDeviceData );
+ MediatorService::TCommand command;
+
+ command.iCaps = capSet;
+ command.iVersion = TVersion(
+ KPhoneToVideotelCmdVersionMajor,
+ KPhoneToVideotelCmdVersionMinor,
+ KPhoneToVideotelCmdVersionBuild );
+ command.iTimeout = KVtEngMdtrCmdTimeout;
+
+ // enable microphone command
+ command.iCommandId = EVtCmdUseDataport;
+ iCommandList.Append( command );
+
+ // Releasedataport command
+ capSet.SetEmpty();
+ capSet.AddCapability( ECapabilityPowerMgmt );
+ command.iCommandId = EVtCmdReleaseDataport;
+ iCommandList.Append( command );
+
+ const TInt err = iCommandResponder->RegisterCommand(
+ KMediatorVideoTelephonyDomain,
+ KCatPhoneToVideotelCommands,
+ iCommandList );
+
+ TRACE2("CVtMediatorPlugin.RegisterDataportCommandL err=%d>", err )
+ User::LeaveIfError( err );
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::RaiseVtEventL
+//
+// Raises VT call info event if in suitable state, i.e. VT app has subscribed
+// the event.
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::RaiseVtEventL()
+ {
+ TRACE("CVtMediatorPlugin.RaiseVtEventL<" )
+ TInt result = KVtAppNotReady; // does not cause leave
+ TRACE2("CVtMediatorPlugin.RaiseVtEventL iState=%d>",
+ iState )
+ TRACE2("CVtMediatorPlugin.RaiseVtEventL iActiveVideoCallState=%d>",
+ iActiveVideoCallState )
+ if ( iState == EReady && // application subscribed to the event
+
+ // don't send event if video call is not starting/ongoing
+ ( iActiveVideoCallState >= ECallStateDialling &&
+ iActiveVideoCallState <= ECallStateConnected ) )
+ {
+ const TVersion version(
+ KVideotelMdtrEventVersionMajor,
+ KVideotelMdtrEventVersionMinor,
+ KVideotelMdtrEventVersionBuild );
+
+ const TVtMediatorInfoPackage pckg( iActiveVideoCallInfo );
+ result = iEventProvider->RaiseEvent(
+ KMediatorVideoTelephonyDomain,
+ KCatVideotelInternalEvents,
+ EVtMediatorEventVideoCallInformation,
+ version,
+ pckg
+ );
+ }
+ TRACE2("CVtMediatorPlugin.RaiseVtEventL result=%d>", result )
+ User::LeaveIfError( result );
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::HandleCallStateChangeL
+//
+// Compares previous and new video call states and resolves based on result
+// if Video telephone applicaton should be launched.
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::HandleCallStateChangeL(
+ const TTelephonyCallDataParam& aData )
+ {
+ TRACE("CVtMediatorPlugin.HandleCallStateChangeL<" )
+
+ TRACE2("CVtMediatorPlugin.HandleCallStateChangeL calltype=%d>",
+ aData.iCallType )
+ TRACE2("CVtMediatorPlugin.HandleCallStateChangeL saved Activecallid=%d>",
+ iActiveVideoCallInfo.iCallId )
+ TRACE2("CVtMediatorPlugin.HandleCallStateChangeL saved Waitingcallid=%d>",
+ iWaitingVideoCallInfo.iCallId )
+ TRACE2("CVtMediatorPlugin.HandleCallStateChangeL callid=%d>",
+ aData.iCallId )
+ TRACE2("CVtMediatorPlugin.HandleCallStateChangeL ActiveCallOldState=%d>",
+ iActiveVideoCallState )
+ TRACE2("CVtMediatorPlugin.HandleCallStateChangeL WaitingCallOldState=%d>",
+ iWaitingVideoCallState )
+ TRACE2("CVtMediatorPlugin.HandleCallStateChangeL NewState=%d>",
+ aData.iCallState )
+
+ //if the call is waitingcall, just save/clear
+ if ( aData.iCallType == ECallTypeVideo ||
+ // check also call id because in call clearing states call type may
+ // be unspecified but call id is saved in call setup and we can
+ // compare to it.
+ iActiveVideoCallInfo.iCallId == aData.iCallId ||
+ iWaitingVideoCallInfo.iCallId == aData.iCallId )
+ {
+ TBool isWaitingCall = ETrue;
+
+ /**
+ * firstly we should check the callid to identify if it is a waitingcal/activecall
+ * imagine the usecase that long press endkey to shutdown both calls.
+ * after that checking iState
+ */
+ if ( iWaitingVideoCallInfo.iCallId == aData.iCallId )
+ {
+ isWaitingCall = ETrue;
+ }
+ else if ( iActiveVideoCallInfo.iCallId == aData.iCallId )
+ {
+ isWaitingCall = EFalse;
+ }
+ //no vt app launched, this happens while vt first launching or end key to shutdown both calls
+ else if ( iState == EWaitingAppLaunch )
+ {
+ isWaitingCall = EFalse;
+ }
+
+ TRACE2("CVtMediatorPlugin.HandleCallStateChangeL isWaitingCall=%d>",
+ isWaitingCall)
+
+ TCallState& callState = isWaitingCall?iWaitingVideoCallState:iActiveVideoCallState;
+ TVtVideoTelephonyCallInformation& vtCallInfo = isWaitingCall?iWaitingVideoCallInfo:iActiveVideoCallInfo;
+
+ TBool launchNeeded = KVtCallStateActionArray[ aData.iCallState ] -
+ KVtCallStateActionArray[callState] > 0;
+ if ( isWaitingCall )
+ {
+ launchNeeded = EFalse;
+ }
+ callState = aData.iCallState;
+
+ switch ( callState )
+ {
+ case ECallStateDialling:
+ case ECallStateRinging:
+ case ECallStateConnecting:
+ case ECallStateConnected:
+ SaveCallData( aData, vtCallInfo);
+ break;
+ default:
+ // data becomes invalid in other states (=call clearing/idle)
+ ClearData(vtCallInfo, callState);
+ break;
+ }
+ if ( launchNeeded )
+ {
+ LaunchVtAppL();
+ }
+ if ( !isWaitingCall )
+ {
+ RaiseVtEventL();
+ }
+ }
+
+ TRACE("CVtMediatorPlugin.HandleCallStateChangeL>" )
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::IsEnoughMemory
+//
+// Check if there is enough memory to launch
+// -----------------------------------------------------------------------------
+//
+TBool CVtMediatorPlugin::IsEnoughMemory()
+ {
+ TRACE("CVtMediatorPlugin::IsEnoughMemory<" )
+ // Fetch amount of free memory.
+ TMemoryInfoV1Buf memory;
+ UserHal::MemoryInfo( memory );
+ TInt freeRam = (TInt)( memory().iFreeRamInBytes );
+ TRACE2("CVtMediatorPlugin::IsEnoughMemory: freeRam = %d", freeRam )
+
+ TBool enoughRam = ETrue;
+
+ if ( freeRam < KRamNeededForVideoCalls )
+ {
+ FreeRam();
+ freeRam = (TInt)( memory().iFreeRamInBytes );
+ TRACE2("CVtMediatorPlugin::IsEnoughMemory: after free, freeRam = %d", freeRam )
+ if ( freeRam < KRamNeededForVideoCalls )
+ {
+ enoughRam = EFalse;
+ TRACE ("CVtMediatorPlugin::IsEnoughMemory : Not enough RAM")
+
+ }
+ }
+ TRACE("CVtMediatorPlugin::IsEnoughMemory>" )
+ return enoughRam;
+ }
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::FreeRam
+// Try to free memory to match the memory usage of VT
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::FreeRam()
+ {
+ TRACE("CVtMediatorPlugin.FreeRam()<")
+ User::CompressAllHeaps();
+ TRACE("CVtMediatorPlugin.FreeRam()>")
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::StopDeathActiveL
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::StopDeathActiveL()
+ {
+ TRACE("CVtMediatorPlugin.StopDeathActive<")
+ delete iAppDeathActive;
+ iAppThread.Close();
+ //if there is a waiting call, check if we need to launch it
+ TRACE2("CVtMediatorPlugin.StopDeathActive WaitintCallID=%d>",
+ iWaitingVideoCallInfo.iCallId)
+ if ( iWaitingVideoCallInfo.iCallId != KVtInitCallId )
+ {
+ iActiveVideoCallInfo = iWaitingVideoCallInfo;
+ iActiveVideoCallState = iWaitingVideoCallState;
+ ClearData(iWaitingVideoCallInfo, iWaitingVideoCallState);
+
+ if ( iActiveVideoCallState == ECallStateDialling ||
+ iActiveVideoCallState == ECallStateRinging ||
+ iActiveVideoCallState == ECallStateConnecting ||
+ iActiveVideoCallState == ECallStateConnected ||
+ iActiveVideoCallState == ECallStateAnswering )
+ {
+ LaunchVtAppL();
+ RaiseVtEventL();
+ }
+ }
+ TRACE("CVtMediatorPlugin.StopDeathActive>")
+ }
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::CAppDeathActive::CAppDeathActive
+// -----------------------------------------------------------------------------
+//
+CVtMediatorPlugin::CAppDeathActive::CAppDeathActive(
+ CVtMediatorPlugin& aMediatorPlugin,
+ RThread& aAppThread
+ )
+ : CActive( CActive::EPriorityStandard ),
+ iMediatorPlugin( aMediatorPlugin ),
+ iAppThread( aAppThread )
+
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::CAppDeathActive::~CAppDeathActive
+// -----------------------------------------------------------------------------
+//
+CVtMediatorPlugin::CAppDeathActive::~CAppDeathActive()
+ {
+ TRACE("CVtMediatorPlugin.~CAppDeathActive")
+ Cancel();
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::CAppDeathActive::Start
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::CAppDeathActive::Start()
+ {
+ TRACE("CVtMediatorPlugin.Start<")
+ Cancel();
+ iAppThread.Logon( iStatus );
+ SetActive();
+ TRACE("CVtMediatorPlugin.Start>")
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::CAppDeathActive::RunL
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::CAppDeathActive::RunL()
+ {
+ //do something here
+ TRACE("CVtMediatorPlugin.RunL<")
+ iMediatorPlugin.StopDeathActiveL();
+ TRACE("CVtMediatorPlugin.RunL>")
+
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::CAppDeathActive::DoCancel
+// -----------------------------------------------------------------------------
+//
+void CVtMediatorPlugin::CAppDeathActive::DoCancel()
+ {
+ iAppThread.LogonCancel( iStatus );
+ }
+
+// -----------------------------------------------------------------------------
+// CVtMediatorPlugin::CAppDeathActive::RunError
+// -----------------------------------------------------------------------------
+//
+TInt CVtMediatorPlugin::CAppDeathActive::RunError( TInt /*aError*/ )
+ {
+ return KErrNone;
+ }