internetradio2.0/uisrc/irsystemeventdetector.cpp
changeset 0 09774dfdd46b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/internetradio2.0/uisrc/irsystemeventdetector.cpp	Mon Apr 19 14:01:53 2010 +0300
@@ -0,0 +1,480 @@
+/*
+* Copyright (c) 2004-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:  
+*   Class provides implementation to detect system events and notify UI 
+*   components of the event, Class keeps several instances of 
+*   CIRPropertyObserver2, and those instances send event notifications 
+*   about the particular system component state change. 
+*
+*/
+	
+
+#include <e32def.h> // Define before audiopolicy defs
+#include <e32std.h> // Define before audiopolicy defs
+#include <eikdef.h>
+
+#ifndef __WINS__
+
+//#include <audiopolicypubsubdata.h>
+//#include <audiosw_pubsubkeys.h>
+
+#endif //__WINS__
+
+#include <ctsydomainpskeys.h>
+#include <wlaninternalpskeys.h>
+#include <sacls.h>
+#ifdef MUSICSHOP_AVAILABLE
+#include <voiceuidomainpskeys.h>
+#endif
+#include <featmgr.h>
+//d #include <vrdebug.h>
+
+#include "irsystemeventdetector.h"
+#include "irsystemeventdetectorobserver.h"
+#include "irdebug.h"
+
+/** Granularity for audio category arrays. */
+const TInt KVRAudioCategoryArrayGranularity = 3;
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------------------------
+// C++ default constructor can NOT contain any code, that might leave.
+// ---------------------------------------------------------------------------
+//
+CIRSystemEventDetector::CIRSystemEventDetector(MIRSystemEventDetectorObserver&  aObserver) 
+    :    iObserver(aObserver),
+         iIsMobileNetworkCoverage(EFalse),
+         iIsWlanCoverage(EFalse),
+         iIsCallActive(EFalse),
+         iIsAudioResourcesAvailable(ETrue),
+         iIsVoiceUiActive(EFalse)
+    {
+    IRLOG_DEBUG( "CIRSystemEventDetector::CIRSystemEventDetector" );
+    }
+
+// ---------------------------------------------------------------------------
+// EPOC default constructor can leave.
+// ---------------------------------------------------------------------------
+//
+void CIRSystemEventDetector::ConstructL()
+    {
+    IRLOG_DEBUG( "CIRSystemEventDetector::ConstructL - Entering" );
+    FeatureManager::InitializeLibL();
+    TBool wlanSupported = FeatureManager::FeatureSupported(KFeatureIdProtocolWlan);
+    FeatureManager::UnInitializeLib();
+    
+
+        iNetworkStatusObserver = CIRPropertyObserver2::NewL(*this, 
+                                 KUidSystemCategory, 
+                                 KUidNetworkStatusValue, 
+                                 CIRPropertyObserver2::EIRPropertyInt);
+        iNetworkStatusObserver->ActivateL();
+        
+    iIsMobileNetworkCoverage = (iNetworkStatusObserver->ValueInt() == ESANetworkAvailable) ? 
+    										ETrue : EFalse;
+
+    // On S60 platform, there is no guaranteed way of seeing whether WLAN is explicitly turned off
+    // in the settings, or whether the network is available. We use the P&S key KPSUidWlan/KPSWlanIndicator
+    // because it is the best we can get.
+    if (wlanSupported)
+        {
+        iWlanObserver = CIRPropertyObserver2::NewL(*this,
+                        KPSUidWlan,
+                        KPSWlanIndicator,
+                        CIRPropertyObserver2::EIRPropertyInt);
+        iWlanObserver->ActivateL();
+
+        TInt wlanStatus = iWlanObserver->ValueInt();
+        iIsWlanCoverage = (wlanStatus == EPSWlanIndicatorActive || wlanStatus == 
+        			EPSWlanIndicatorActiveSecure) ? ETrue : EFalse;
+        }
+    else
+        {
+        iIsWlanCoverage = EFalse;
+        }
+
+    // Initialize call state observer.
+    iCallStatusObserver = CIRPropertyObserver2::NewL(*this, 
+                                                      KPSUidCtsyCallInformation, 
+                                                      KCTsyCallState, 
+                                                      CIRPropertyObserver2::EIRPropertyInt);
+    iCallStatusObserver->ActivateL();
+    iIsCallActive = iCallStatusObserver->ValueInt() != EPSCTsyCallStateNone;
+    
+#ifdef MUSICSHOP_AVAILABLE
+    // Initialize voice ui observer.
+    iVoiceUiObserver = CIRPropertyObserver2::NewL(*this, KPSUidVoiceUiAccMonitor, KVoiceUiOpenKey,
+    					 CIRPropertyObserver2::EIRPropertyInt);
+    iVoiceUiObserver->ActivateL();    					    
+#endif
+    IRLOG_DEBUG( "CIRSystemEventDetector::ConstructL - Exiting" );
+
+#ifndef __WINS__
+    // Define audio types for not resuming.
+    iNoAutoResumeAudioCategories = RArray<TInt>( KVRAudioCategoryArrayGranularity );
+//    iNoAutoResumeAudioCategories.AppendL(ECatMediaPlayer)
+//    iNoAutoResumeAudioCategories.AppendL(ECatMobileTv)
+//    iNoAutoResumeAudioCategories.AppendL(ECatUnknownPlayer)
+    iNoAutoResumeAudioCategories.Compress();
+    // Start listening audio client events
+//	iAudioPolicyObserver = CIRPropertyObserver2::NewL(*this, KPSUidMMFAudioServer, KAudioPolicyAudioClients, CIRPropertyObserver2::EIRPropertyByteArray)
+//	iAudioPolicyObserver->ActivateL()
+#endif
+    }
+
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CIRSystemEventDetector::~CIRSystemEventDetector()
+    {
+    IRLOG_DEBUG( "CIRSystemEventDetector::~CIRSystemEventDetector - Entering" );
+    FeatureManager::UnInitializeLib();
+    delete iCallStatusObserver;
+    delete iNetworkStatusObserver;
+    delete iVoiceUiObserver;
+//    delete iAudioPolicyObserver
+    delete iWlanObserver;
+
+    iNoAutoResumeAudioCategories.Close();
+    IRLOG_DEBUG( "CIRSystemEventDetector::~CIRSystemEventDetector - Exiting" );
+    }
+    
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CIRSystemEventDetector* CIRSystemEventDetector::NewL(
+                                    MIRSystemEventDetectorObserver&  aObserver)
+    {
+    IRLOG_DEBUG( "CIRSystemEventDetector::NewL - Entering" );
+    CIRSystemEventDetector* self = new (ELeave) CIRSystemEventDetector(aObserver);
+    
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    IRLOG_DEBUG( "CIRSystemEventDetector::NewL - Exiting" );
+    return self;
+    }
+    
+// ---------------------------------------------------------------------------
+// Handling of the int property changes is done here. 
+// Observer components are getting notifications in correspondence with what 
+// has changed
+// ---------------------------------------------------------------------------
+//
+void CIRSystemEventDetector::HandlePropertyChangeL( const TUid& aCategory, 
+                                                    const TUint aKey, 
+                                                    const TInt aValue )
+	{
+	IRLOG_DEBUG( "CIRSystemEventDetector::HandlePropertyChangeL - Entering" );
+    if (aCategory == KUidSystemCategory && aKey == KUidNetworkStatusValue)
+    	{
+    	switch (aValue)
+    		{
+    		case ESANetworkAvailable:
+    			{
+                SetNetworkCoverageL( ETrue, iIsWlanCoverage );
+    			break;
+    			}
+    		case ESANetworkUnAvailable:
+    			{
+                SetNetworkCoverageL( EFalse, iIsWlanCoverage );
+    			break;
+    			}
+    		default:
+    			{
+    			break;   			
+    			}
+    		}
+    	}
+    else if (aCategory == KPSUidCtsyCallInformation && aKey == KCTsyCallState)
+    	{
+		if ((!iIsCallActive) && (aValue > EPSCTsyCallStateNone)) 
+			{
+			iIsCallActive = ETrue;
+			iObserver.CallActivatedCallbackL();
+			}
+		else if ((iIsCallActive) && (aValue <= EPSCTsyCallStateNone))
+			{
+			iIsCallActive = EFalse;
+			iObserver.CallDeactivatedCallbackL();	
+			}
+        }
+    else if ( aCategory == KPSUidWlan && aKey == KPSWlanIndicator )
+        {
+        switch (aValue)
+            {
+            case EPSWlanIndicatorActive:
+            case EPSWlanIndicatorActiveSecure:
+                {
+                SetNetworkCoverageL( iIsMobileNetworkCoverage, ETrue );
+                break;
+                }
+            case EPSWlanIndicatorNone:
+            case EPSWlanIndicatorAvailable:
+                {
+                SetNetworkCoverageL( iIsMobileNetworkCoverage, EFalse );
+                break;
+                }
+            default:
+                {
+                break;
+                }
+			}
+    	}
+#ifdef MUSICSHOP_AVAILABLE
+    else if ( aCategory == KPSUidVoiceUiAccMonitor && aKey == KVoiceUiOpenKey )
+        {
+        switch (aValue)
+    		{
+    		case KVoiceUiIsClose:
+    			{
+				if (iIsVoiceUiActive)
+				    {
+				    iIsVoiceUiActive = EFalse;
+				    if (iIsAudioResourcesAvailable)
+				        {
+            		    iObserver.AudioResourcesAvailableL();
+				        }
+				    }
+    			break;
+    			}
+    		case KVoiceUiIsOpen:
+    			{
+    			if (!iIsVoiceUiActive)
+    			    {
+    			    iIsVoiceUiActive = ETrue;
+    			    }
+    			break;
+    			}
+    		default:
+    			{
+    			break;   			
+    			}
+    		}
+        }
+#endif
+    else // NOP
+    	{
+    	}
+    IRLOG_DEBUG( "CIRSystemEventDetector::HandlePropertyChangeL - Exiting" );
+ 	}
+
+#ifndef __WINS__	
+// ---------------------------------------------------------------------------
+// Handling of the byte array property changes is done here. 
+// Observer components are getting notifications in correspondence with what 
+// has changed
+// ---------------------------------------------------------------------------
+//
+void CIRSystemEventDetector::HandlePropertyChangeL( const TUid& aCategory, 
+                                                    const TUint aKey, 
+                                                    const TDesC8& aValue)
+	{
+/*    if (aCategory == KPSUidMMFAudioServer)
+        {        
+        if (aKey == KAudioPolicyAudioClients)
+            {
+            TBool atLeastOneAutoResumeAudioPlaying(EFalse);
+            TBool atLeastOneNoAutoResumeAudioPlaying(EFalse);
+            TBool radioPlaying(EFalse);
+            TAudioClientList audioClients;
+            audioClients.Copy(aValue);
+            // Check all playing audios
+            for ( TInt i = 0; i < audioClients().iNumOfProcesses ; i++ )
+                {
+                TInt cat = audioClients().iClientCategoryList[i];
+                VRDEBUG2(" *** S60VisualRadio -- Check audio cat %d", cat);
+                if (cat == ECatFmRadio)
+                    {
+                    radioPlaying = ETrue;
+                    }
+                else if (iNoAutoResumeAudioCategories.Find(cat) != KErrNotFound)
+                    {
+                    atLeastOneNoAutoResumeAudioPlaying = ETrue;
+                    }
+                else
+                    {
+                    atLeastOneAutoResumeAudioPlaying = ETrue;
+                    }
+                }
+                
+            if (!radioPlaying)
+                {
+                // Decide audio resource availability from audio category info.
+                if (atLeastOneNoAutoResumeAudioPlaying)
+            		{
+            		VRDEBUG(" *** S60VisualRadio -- Audio resources not available. Change informed.");
+            		iIsAudioResourcesAvailable = EFalse;
+            		iObserver.AudioAutoResumeForbiddenL();
+            		}
+            	else if (!atLeastOneAutoResumeAudioPlaying)
+            		{
+            		if (!iIsVoiceUiActive)
+            		    {
+            		    VRDEBUG(" *** S60VisualRadio -- Audio resources available. Change informed.");
+            		    iIsAudioResourcesAvailable = ETrue;
+            		    iObserver.AudioResourcesAvailableL();
+            		    }
+            		else
+            		    {
+            		    VRDEBUG(" *** S60VisualRadio -- Audio resources available. Change not informed.");
+            		    iIsAudioResourcesAvailable = ETrue;
+            		    }
+            		}
+            	else
+            	    {
+            	    VRDEBUG(" *** S60VisualRadio -- Audio resources not available. Change not informed.");
+            		iIsAudioResourcesAvailable = EFalse;
+            	    }
+                }
+            else // audio resources are considered to be available when radio is playing
+                {
+                iIsAudioResourcesAvailable = ETrue;
+                }
+            }
+        }
+ */	}
+ 	
+#else //__WINS__
+// ---------------------------------------------------------------------------
+// Dummy version for WINS in order to avoid compiler warnings. 
+// The real implementation of function is above.
+// ---------------------------------------------------------------------------
+//
+void CIRSystemEventDetector::HandlePropertyChangeL( const TUid& /*aCategory*/, 
+                                                    const TUint /*aKey*/, 
+                                                    const TDesC8& /*aValue*/)
+	{
+	IRLOG_DEBUG( "CIRSystemEventDetector::HandlePropertyChangeL" );
+ 	}
+#endif
+
+// ---------------------------------------------------------------------------
+// Handling of the text property changes is done here. 
+// Observer components are getting notifications in correspondence with what 
+// has changed
+// ---------------------------------------------------------------------------
+//
+void CIRSystemEventDetector::HandlePropertyChangeL( const TUid& /*aCategory*/, 
+                                                    const TUint /*aKey*/, 
+                                                    const TDesC& /*aValue*/)
+	{
+	IRLOG_DEBUG( "CIRSystemEventDetector::HandlePropertyChangeL" );
+	}
+
+// ---------------------------------------------------------------------------
+// This is a callback function which is called when a P&S components returns 
+// an error
+// ---------------------------------------------------------------------------
+//
+void CIRSystemEventDetector::HandlePropertyChangeErrorL( const TUid& aCategory, 
+                                                         const TUint aKey, 
+                                                         TInt aError )
+	{
+	IRLOG_DEBUG( "CIRSystemEventDetector::HandlePropertyChangeErrorL - Entering" );
+#ifdef MUSICSHOP_AVAILABLE
+	if ( aCategory == KPSUidVoiceUiAccMonitor && aKey == KVoiceUiOpenKey && aError == KErrNotFound )
+        {
+        HandlePropertyChangeL( KPSUidVoiceUiAccMonitor, KVoiceUiOpenKey, KVoiceUiIsClose );
+        }
+    else
+        {
+        iObserver.ErrorCallbackL(aError);
+        }
+#else  // remove warnings
+    if ( aCategory.iUid == 0x101F8543 || aKey || aError)
+        {
+        // do nothing
+        }
+#endif
+	IRLOG_DEBUG( "CIRSystemEventDetector::HandlePropertyChangeErrorL - Exiting" );
+	}
+
+// ---------------------------------------------------------------------------
+TBool CIRSystemEventDetector::IsMobileNetworkCoverage() const
+    {
+    IRLOG_DEBUG( "CIRSystemEventDetector::IsMobileNetworkCoverage" );
+    return iIsMobileNetworkCoverage;
+    }
+// CIRSystemEventDetector::IsNetworkCoverage
+// ---------------------------------------------------------------------------
+//
+TBool CIRSystemEventDetector::IsNetworkCoverage() const
+	{
+	 IRLOG_DEBUG( "CIRSystemEventDetector::IsNetworkCoverage" );
+    return iIsWlanCoverage || iIsMobileNetworkCoverage;
+	}
+
+// ---------------------------------------------------------------------------
+// CIRSystemEventDetector::IsCallActive
+// ---------------------------------------------------------------------------
+//
+TBool CIRSystemEventDetector::IsCallActive() const
+	{
+	IRLOG_DEBUG( "CIRSystemEventDetector::IsCallActive" );
+	return iIsCallActive;
+	}
+	
+// ---------------------------------------------------------------------------
+// CIRSystemEventDetector::IsAudioResourcesAvailable
+// ---------------------------------------------------------------------------
+//
+TBool CIRSystemEventDetector::IsAudioResourcesAvailable() const
+	{
+	IRLOG_DEBUG( "CIRSystemEventDetector::IsAudioResourcesAvailable" );
+	return iIsAudioResourcesAvailable;
+	}
+
+// ---------------------------------------------------------------------------
+// CIRSystemEventDetector::IsVoiceUiActive
+// ---------------------------------------------------------------------------
+//
+TBool CIRSystemEventDetector::IsVoiceUiActive() const
+    {
+    IRLOG_DEBUG( "CIRSystemEventDetector::IsVoiceUiActive" );
+    return iIsVoiceUiActive;
+    }
+    
+
+// ---------------------------------------------------------------------------
+// CIRSystemEventDetector::SetNetworkCoverageL
+// ---------------------------------------------------------------------------
+//
+void CIRSystemEventDetector::SetNetworkCoverageL( const TBool aIsMobileNetworkCoverage,
+					 const TBool aIsWlanCoverage )
+    {
+    IRLOG_DEBUG( "CIRSystemEventDetector::SetNetworkCoverageL - Entering" );
+
+    TBool wasCoverage = IsNetworkCoverage();
+    iIsMobileNetworkCoverage = aIsMobileNetworkCoverage;
+    iIsWlanCoverage = aIsWlanCoverage;
+    TBool isCoverage = IsNetworkCoverage();
+
+    if (isCoverage != wasCoverage)
+        {
+        if (isCoverage)
+            {
+            iObserver.NetworkUpCallbackL();
+            }
+        else
+            {
+            iObserver.NetworkDownCallbackL();
+            }
+        IRLOG_DEBUG( "CIRSystemEventDetector::SetNetworkCoverageL - Exiting" );
+        }
+    }