mmsharing/mmshengine/src/musengtelephoneutils.cpp
branchRCL_3
changeset 33 bc78a40cd63c
parent 32 73a1feb507fb
--- a/mmsharing/mmshengine/src/musengtelephoneutils.cpp	Tue Aug 31 15:12:07 2010 +0300
+++ b/mmsharing/mmshengine/src/musengtelephoneutils.cpp	Wed Sep 01 12:31:01 2010 +0100
@@ -19,74 +19,31 @@
 // USER
 #include "musengtelephoneutils.h"
 #include "musengaudioroutingobserver.h"
+#include "musengmcesession.h"
+#include "musengvolumechangeobserver.h"
 #include "muslogger.h"
 
 // SYSTEM
 #include <centralrepository.h>
-#include <telincallvolcntrlcrkeys.h>
+#include <telephonydomaincrkeys.h>
 #include <e32property.h>
 #include <telephonydomainpskeys.h>
 #include <CPhCltCommandHandler.h> // for CPhCltCommandHandler
 
-// Constants
-const TInt KMusEngMaxVolume = 10;
-const TInt KMusEngMinVolume = 0;
-
-
-
 
 // -----------------------------------------------------------------------------
 //
 // -----------------------------------------------------------------------------
 //
-CMusEngTelephoneUtils* CMusEngTelephoneUtils::NewL( 
-    MMusEngAudioRoutingObserver& aAudioRoutingObserver )
+CMusEngTelephoneUtils* CMusEngTelephoneUtils::NewL()
     {
-    CMusEngTelephoneUtils* self = 
-        new( ELeave )CMusEngTelephoneUtils( aAudioRoutingObserver );
+    CMusEngTelephoneUtils* self = new( ELeave ) CMusEngTelephoneUtils();
     CleanupStack::PushL( self );
     self->ConstructL();
     CleanupStack::Pop( self );
     return self;
     }
 
-// -----------------------------------------------------------------------------
-//
-// -----------------------------------------------------------------------------
-//
-CMusEngTelephoneUtils::CMusEngTelephoneUtils( 
-    MMusEngAudioRoutingObserver& aAudioRoutingObserver ) 
-    : CActive( CActive::EPriorityStandard ),
-      iAudioRoutingObserver( aAudioRoutingObserver )
-    {
-    iAudioOutputAtStartup = CTelephonyAudioRouting::ENotActive;
-    }
-
-
-// -----------------------------------------------------------------------------
-//
-// -----------------------------------------------------------------------------
-//
-void CMusEngTelephoneUtils::ConstructL()
-    {
-    MUS_LOG( "mus: [ENGINE]  -> CMusEngTelephoneUtils::ConstructL()" )
-
-    // Volume control
-    iRepository = CRepository::NewL( KCRUidInCallVolume );
-
-    // Audio routing control
-    iTelephonyAudioRouting = CTelephonyAudioRouting::NewL( *this );
-
-    iAudioOutputAtStartup = iTelephonyAudioRouting->Output();
-    
-    // Phone
-    MUS_LOG( "mus: [ENGINE]     Use static DLL" )
-    iPhoneCommandHandler = CPhCltCommandHandler::NewL();
-        
-    CActiveScheduler::Add( this );
-
-    MUS_LOG( "mus: [ENGINE]  <- CMusEngTelephoneUtils::ConstructL()" )
-    }
 
 // -----------------------------------------------------------------------------
 //
@@ -104,34 +61,43 @@
         {
         CTelephonyAudioRouting::TAudioOutput currentMode =
                                             iTelephonyAudioRouting->Output();
-        if( currentMode != iAudioOutputAtStartup )
+        MUS_LOG1( "mus: [ENGINE] iAudioOutputAtStartup: %d", iAudioOutputAtStartup );
+        MUS_LOG1( "mus: [ENGINE] currentMode: %d", currentMode );
+        // When active call is dropped, audio output is set to ENotActive,
+        // but in some cases Mush engine get deleted before OutputChanged()
+        // notification comes. In that case we shouldn't touch output. 
+        if( currentMode != iAudioOutputAtStartup && 
+            currentMode != CTelephonyAudioRouting::ENotActive )
             {
             // As going down, let audiorouting api to show notification
             iTelephonyAudioRouting->SetShowNote( ETrue );
-            TRAPD( err, 
-                iTelephonyAudioRouting->SetOutputL( iAudioOutputAtStartup ) )
+            TRAPD( err, DoSetOutputL( iAudioOutputAtStartup ) );
             MUS_LOG1( "mus: [ENGINE]    final route change completed: %d", err )
             err++;
-        	}
+            }
         }
 
+    if ( iNotifier )
+        {
+        iNotifier->StopListening();
+        delete iNotifier;
+        }    
+
     delete iRepository;
     delete iTelephonyAudioRouting;
     MUS_LOG( "mus: [ENGINE]  <- CMusEngTelephoneUtils::~CMusEngTelephoneUtils()" )
     }
 
+
 // -----------------------------------------------------------------------------
 //
 // -----------------------------------------------------------------------------
 //
-TBool CMusEngTelephoneUtils::AudioRoutingCanBeChanged()
+TBool CMusEngTelephoneUtils::AudioRoutingCanBeChanged() const
     {
     MUS_LOG( "mus: [ENGINE]  -> CMusEngTelephoneUtils::AudioRoutingCanBeChanged" )
     
-    TBool retValue = ( iTelephonyAudioRouting->Output() !=
-                       CTelephonyAudioRouting::EWiredAudioAccessory &&
-                       iTelephonyAudioRouting->Output() !=
-                       CTelephonyAudioRouting::EBTAudioAccessory &&
+    TBool retValue = ( 
                        iTelephonyAudioRouting->Output() !=
                        CTelephonyAudioRouting::ETTY );
     
@@ -141,46 +107,107 @@
     return retValue;
     }
 
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TBool CMusEngTelephoneUtils::IsAudioRoutingHeadset() const
+    {
+    MUS_LOG( "mus: [ENGINE]  -> CMusEngTelephoneUtils::IsAudioRoutingHeadset" )
+	    
+    TBool retValue = ( iTelephonyAudioRouting->Output() ==
+                       CTelephonyAudioRouting::EBTAudioAccessory ||
+                       iTelephonyAudioRouting->Output() ==
+                       CTelephonyAudioRouting::EWiredAudioAccessory );
+	    
+    MUS_LOG1( "mus: [ENGINE]  <- CMusEngTelephoneUtils::IsAudioRoutingHeadset: %d",
+               retValue )
+	              
+    return retValue;
+    }
+
 // -----------------------------------------------------------------------------
 //
 // -----------------------------------------------------------------------------
 //
-void CMusEngTelephoneUtils::LoudspeakerL( TBool aEnable )
+TBool CMusEngTelephoneUtils::IsAudioRoutingLoudSpeaker() const
+    {
+    MUS_LOG( "mus: [ENGINE]  -> CMusEngTelephoneUtils::IsAudioRoutingLoudSpeaker" )
+    TBool retValue = EFalse;
+    
+    CTelephonyAudioRouting::TAudioOutput currentMode =
+                                            iTelephonyAudioRouting->Output();
+    MUS_LOG1( "mus: [ENGINE] iAudioOutputAtStartup: %d", iAudioOutputAtStartup );
+    MUS_LOG1( "mus: [ENGINE] currentMode: %d", currentMode );
+    
+    if( currentMode != iAudioOutputAtStartup && 
+        currentMode == CTelephonyAudioRouting::ELoudspeaker )
+    	{
+    
+         retValue = ETrue;
+    
+    	}
+    	
+    MUS_LOG1( "mus: [ENGINE]  <- CMusEngTelephoneUtils::IsAudioRoutingLoudSpeaker: %d",
+               retValue )
+	              
+    return retValue;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTelephoneUtils::LoudspeakerL( TBool aEnable, TBool aShowDialog )
     {
     MUS_LOG1( "mus: [ENGINE]  -> CMusEngTelephoneUtils::LoudspeakerL(%d)",
               aEnable )
     
-    // Disable note shown by audiorouting api as it causes
-    // application going to background for a while. Instead, display
-    // note by ourselves once setting output completes. This mechanism
-    // is needed only for loudspeaker enabling as going to background
-    // causes problems only at beginning of sharing session.
-    iTelephonyAudioRouting->SetShowNote( EFalse );              
     if ( aEnable )
         {
         if ( iTelephonyAudioRouting->Output() == 
-             CTelephonyAudioRouting::EHandset )
+             CTelephonyAudioRouting::EHandset || 
+             iTelephonyAudioRouting->Output() == 
+             CTelephonyAudioRouting::EBTAudioAccessory|| 
+             iTelephonyAudioRouting->Output() == 
+             CTelephonyAudioRouting::EWiredAudioAccessory )  
             {
-            iTelephonyAudioRouting->SetOutputL( 
-                CTelephonyAudioRouting::ELoudspeaker );
+            // Disable note shown by audiorouting api as it causes
+            // application going to background for a while. Instead, display
+            // note by ourselves once setting output completes. This mechanism
+            // is needed only for loudspeaker enabling as going to background
+            // causes problems only at beginning of sharing session.
+            if ( aShowDialog )
+                {   
+                iTelephonyAudioRouting->SetShowNote( EFalse );
+                
+                iShowDialog = aShowDialog;
+                }
+    
+            DoSetOutputL( CTelephonyAudioRouting::ELoudspeaker );
             }
         }
     else
-        {        
+        {
+        iTelephonyAudioRouting->SetShowNote( aShowDialog );
+        
         if ( iAudioOutputAtStartup == CTelephonyAudioRouting::ELoudspeaker )
             {
-            iTelephonyAudioRouting->SetOutputL( 
-                CTelephonyAudioRouting::EHandset );
+            DoSetOutputL( CTelephonyAudioRouting::EHandset );
             }
         else
             {
-            iTelephonyAudioRouting->SetOutputL( iAudioOutputAtStartup );
+            DoSetOutputL( iAudioOutputAtStartup );
             }
         }
+
+    
                                 
     MUS_LOG( "mus: [ENGINE]  <- CMusEngTelephoneUtils::LoudspeakerL(...)" )
     }
 
+
 // -----------------------------------------------------------------------------
 //
 // -----------------------------------------------------------------------------
@@ -192,7 +219,16 @@
     }
 
 // -----------------------------------------------------------------------------
-// Gets the CS call volume level.
+// Returns locally cached the CS call volume level.
+// -----------------------------------------------------------------------------
+//
+TInt CMusEngTelephoneUtils::GetVolume() const
+    {
+    return iCurrentVolume;
+    }
+        
+// -----------------------------------------------------------------------------
+// Gets the CS call volume level from central repository.
 // Leaves if error occurs when accessing central repository.
 // -----------------------------------------------------------------------------
 //
@@ -209,9 +245,11 @@
         User::LeaveIfError( iRepository->Get( KTelIncallEarVolume,
                                               currentVolume ) );
         }
+
     return ValidateVolume( currentVolume );
     }
 
+
 // -----------------------------------------------------------------------------
 // Sets the CS call volume level.
 // Leaves if error occurs when accessing central repository.
@@ -220,8 +258,8 @@
 void CMusEngTelephoneUtils::SetVolumeL( TInt aVolume )
     {
     TInt newVolume = ValidateVolume( aVolume );
-
-    if ( GetVolumeL() != newVolume )
+    MUS_LOG1( "mus: [ENGINE]  -> CMusEngTelephoneUtils::SetVolumeL(), %d", newVolume )
+    if ( iCurrentVolume != newVolume )
         {
         if ( IsLoudSpeakerEnabled() )
             {
@@ -233,9 +271,11 @@
             User::LeaveIfError( iRepository->Set( KTelIncallEarVolume, 
                                                   newVolume ) );
             }
+        iCurrentVolume = newVolume;
         }
     }
 
+
 // -----------------------------------------------------------------------------
 //
 // -----------------------------------------------------------------------------
@@ -256,6 +296,7 @@
     MUS_LOG( "mus: [ENGINE]  <- CMusEngTelephoneUtils::MuteMicL()" )
     }
 
+
 // -----------------------------------------------------------------------------
 //
 // -----------------------------------------------------------------------------
@@ -275,6 +316,27 @@
     return ( psVal == EPSTelMicMuteOn );
     }
 
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTelephoneUtils::SetAudioRoutingObserver( 
+                                    MMusEngAudioRoutingObserver* aObserver )
+    {
+    iAudioRoutingObserver = aObserver;
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTelephoneUtils::SetVolumeChangeObserver( 
+                                    MMusEngVolumeChangeObserver* aObserver )
+    {
+    iVolumeObserver = aObserver;
+    }
+
 // -----------------------------------------------------------------------------
 // 
 // -----------------------------------------------------------------------------
@@ -290,6 +352,23 @@
     MUS_LOG( "mus: [ENGINE]  <- CMusEngTelephoneUtils::RunL()" )
     }
 
+// -------------------------------------------------------------------------
+//  If RunL() leaves,It should be handled here.
+// -------------------------------------------------------------------------
+//
+TInt CMusEngTelephoneUtils::RunError( TInt aError )
+    {
+    MUS_LOG1( "mus: [ENGINE]     -> CMusEngTelephoneUtils::\
+              RunError() return #%d", aError )
+    
+    // Nothing can be done here.
+    aError = KErrNone;
+
+    MUS_LOG( "mus: [ENGINE]  <- CMusEngTelephoneUtils::RunError()" )
+    return aError;
+    }
+
+
 // -----------------------------------------------------------------------------
 // 
 // -----------------------------------------------------------------------------
@@ -304,24 +383,26 @@
         }
         
     MUS_LOG( "mus: [ENGINE]  <- CMusEngTelephoneUtils::DoCancel()" )
-    } 
+    }
+    
 
 // -----------------------------------------------------------------------------
 //
 // -----------------------------------------------------------------------------
 //
 void CMusEngTelephoneUtils::AvailableOutputsChanged( 
-    CTelephonyAudioRouting& /*aTelephonyAudioRouting*/ )
+                        CTelephonyAudioRouting& /*aTelephonyAudioRouting*/ )
     {
     // NOP
     }
 
+
 // -----------------------------------------------------------------------------
 //
 // -----------------------------------------------------------------------------
 //
 void CMusEngTelephoneUtils::OutputChanged( 
-    CTelephonyAudioRouting& aTelephonyAudioRouting )
+                CTelephonyAudioRouting& aTelephonyAudioRouting )
     {
     MUS_LOG( "mus: [ENGINE]  -> CMusEngTelephoneUtils::OutputChanged()" )
 
@@ -332,8 +413,13 @@
     
     MUS_LOG1( "mus: [ENGINE]     New audio routing is %d", iAudioOutputAtStartup )
     
-    iAudioRoutingObserver.AudioRoutingChanged();
-        
+    if ( iAudioRoutingObserver )
+        {
+        iAudioRoutingObserver->AudioRoutingChanged( EFalse );
+        }
+    
+    UpdateCurrentVolume(ETrue);
+    
     MUS_LOG( "mus: [ENGINE]  <- CMusEngTelephoneUtils::OutputChanged()" )
     }
     
@@ -343,18 +429,97 @@
 // -----------------------------------------------------------------------------
 //
 void CMusEngTelephoneUtils::SetOutputComplete( 
-    CTelephonyAudioRouting& /*aTelephonyAudioRouting*/,
-    TInt aError )
+                    CTelephonyAudioRouting& /*aTelephonyAudioRouting*/,
+                    TInt aError )
     {
     MUS_LOG( "mus: [ENGINE]  -> CMusEngTelephoneUtils::SetOutputComplete()" )
 
     if ( aError == KErrNone )
         {
-        iAudioRoutingObserver.AudioRoutingChanged();
+        if ( iAudioRoutingObserver )
+            {
+            // If audio routing api didn't shown note and show dialog mode is on,
+            // we know that this completion is for such setoutput call for which
+            // we need to show the note. Show note mode is turned off only in that
+            // case.
+            TBool dialogShownByUs( EFalse );
+            TBool dialogShownByAudioRouting( EFalse );     
+            aError = iTelephonyAudioRouting->GetShowNote( dialogShownByAudioRouting );
+            if ( aError == KErrNone && !dialogShownByAudioRouting && iShowDialog )
+                {
+                dialogShownByUs = iShowDialog;
+                iShowDialog = EFalse;
+                }
+        
+            iAudioRoutingObserver->AudioRoutingChanged( dialogShownByUs );
+            }
+
+        UpdateCurrentVolume(ETrue);
         }
     
     MUS_LOG( "mus: [ENGINE]  <- CMusEngTelephoneUtils::SetOutputComplete()" )
     }
+                            
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTelephoneUtils::UpdateCurrentVolume( TBool aAudioRouteChanged )
+    {
+    TInt volume(0);
+    TRAPD(error, volume = GetVolumeL() );
+    if( (KErrNone == error) && (iCurrentVolume != volume) )
+         {
+         iCurrentVolume = volume;
+         if ( iVolumeObserver )
+             {
+             iVolumeObserver->VolumeChanged( volume, aAudioRouteChanged );
+             }
+         }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CMusEngTelephoneUtils::CMusEngTelephoneUtils() 
+	: CActive( CActive::EPriorityStandard )
+    {
+    iAudioOutputAtStartup = CTelephonyAudioRouting::ENotActive;
+    }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CMusEngTelephoneUtils::ConstructL()
+    {
+    MUS_LOG( "mus: [ENGINE]  -> CMusEngTelephoneUtils::ConstructL()" )
+
+    // Volume control
+    iRepository = CRepository::NewL( KCRUidInCallVolume );
+    
+    iNotifier = CCenRepNotifyHandler::NewL( *this, *iRepository );
+    iNotifier->StartListeningL();
+    
+    // Audio routing control
+    iTelephonyAudioRouting = CTelephonyAudioRouting::NewL( *this );
+
+    iAudioOutputAtStartup = iTelephonyAudioRouting->Output();
+    MUS_LOG1( "mus: [ENGINE] iAudioOutputAtStartup: %d", iAudioOutputAtStartup );
+    // Phone
+    MUS_LOG( "mus: [ENGINE]     Use static DLL" )
+    iPhoneCommandHandler = CPhCltCommandHandler::NewL();
+     
+    iCurrentVolume = GetVolumeL();
+    
+    CActiveScheduler::Add( this );
+
+    MUS_LOG( "mus: [ENGINE]  <- CMusEngTelephoneUtils::ConstructL()" )
+    }
+
 
 // -----------------------------------------------------------------------------
 // Validates that requested volume level is valid (between 1-10) and if it is
@@ -378,3 +543,61 @@
         
     return aVolume;
     }
+
+
+// -----------------------------------------------------------------------------
+// Set output if setting is currently allowed.
+// -----------------------------------------------------------------------------
+//
+void CMusEngTelephoneUtils::DoSetOutputL( 
+    CTelephonyAudioRouting::TAudioOutput aAudioOutput )
+    {
+    MUS_LOG( "mus: [ENGINE]  -> CMusEngTelephoneUtils::DoSetOutputL()" )
+    if ( iAudioRoutingObserver && !iAudioRoutingObserver->AudioRouteChangeAllowed() )
+        {
+        MUS_LOG( "mus: [ENGINE]     change not allowed!" )
+        User::Leave( KErrAccessDenied );
+        }
+    iTelephonyAudioRouting->SetOutputL( aAudioOutput );
+    MUS_LOG( "mus: [ENGINE]  <- CMusEngTelephoneUtils::DoSetOutputL()" )
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMusEngTelephoneUtils::HandleNotifyGeneric
+// ---------------------------------------------------------------------------
+//
+void CMusEngTelephoneUtils::HandleNotifyGeneric( TUint32 aId )
+    {
+    MUS_LOG( "mus: [ENGINE] -> CMusEngTelephoneUtils::HandleNotifyGeneric()" )
+    TInt error = KErrArgument;
+    TInt volume = 0;
+    if ( KTelIncallEarVolume == aId )
+        {
+        error = iRepository->Get( KTelIncallEarVolume, volume );        
+        MUS_LOG1( "mus: [ENGINE] EAR volume: %d", volume );
+        }
+    else if ( KTelIncallLoudspeakerVolume == aId )
+        {
+        error = iRepository->Get( KTelIncallLoudspeakerVolume, volume );        
+        MUS_LOG1( "mus: [ENGINE] Loudspeakers volume: %d", volume );
+        }
+    
+    volume = ValidateVolume(volume);
+    if ( (KErrNone == error) && (iCurrentVolume != volume) )
+        {
+        MUS_LOG1( "mus: [ENGINE] volume changed: %d!, notifying UI...", volume )
+        iCurrentVolume = volume;
+        if( iVolumeObserver  )
+            {
+            iVolumeObserver->VolumeChanged( volume, EFalse );
+            }
+        }
+    else
+        {
+        MUS_LOG( "mus: [ENGINE] volume hasn't changed!, do nothing..." )    
+        }
+        
+    MUS_LOG1( "mus: [ENGINE] <- CMusEngTelephoneUtils::HandleNotifyGeneric(), error:%d",
+            error );
+    }