--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fmradio/fmradioengine/src/fmradiosystemeventdetector.cpp Tue Feb 02 00:17:10 2010 +0200
@@ -0,0 +1,427 @@
+/*
+* Copyright (c) 2005 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: Observer for system events
+*
+*/
+
+#include "fmradiovariant.hrh" // include first for variation
+#include <e32def.h> // Define before audiopolicy defs
+#include <e32std.h> // Define before audiopolicy defs
+#include <eikdef.h>
+#include <sacls.h>
+#include <voiceuidomainpskeys.h>
+#include <ctsydomainpskeys.h>
+#ifndef __WINS__
+
+#ifdef __FMRADIO_ADVANCED_AUTO_RESUME
+
+const TInt KFMRadioAudioCategoryArrayGranularity = 3;
+#include <internal/audiopolicypubsubdata.h>
+#include <internal/audiosw_pubsubkeys.h>
+
+#else
+
+#include <AudioClientsListPSData.h>
+#include <AudioClientsListPSKeys.h>
+
+#endif // __FMRADIO_ADVANCED_AUTO_RESUME
+
+#endif //__WINS__
+
+#include "debug.h"
+#include "fmradiosystemeventdetector.h"
+#include "fmradiosystemeventdetectorobserver.h"
+
+const TInt KFMRadioAutoResumeDelay = 2000000; // micro seconds -> 2 seconds
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------------------------
+// CFMRadioSystemEventDetector::CFMRadioSystemEventDetector
+// C++ default constructor can NOT contain any code, that might leave.
+// ---------------------------------------------------------------------------
+//
+CFMRadioSystemEventDetector::CFMRadioSystemEventDetector(MFMRadioSystemEventDetectorObserver& aObserver)
+ : iObserver( aObserver ),
+ iIsNetworkCoverage( EFalse),
+ iIsVoiceUiActive( EFalse )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// CFMRadioSystemEventDetector::ConstructL
+// EPOC default constructor can leave.
+// ---------------------------------------------------------------------------
+//
+void CFMRadioSystemEventDetector::ConstructL()
+ {
+ CFMRadioPropertyObserver* networkObserver =
+ CFMRadioPropertyObserver::NewLC( *this,
+ KUidSystemCategory,
+ KUidNetworkStatusValue,
+ CFMRadioPropertyObserver::EFMRadioPropertyInt );
+
+ iPropertyArray.AppendL( networkObserver );
+ CleanupStack::Pop( networkObserver );
+
+ CFMRadioPropertyObserver* voiceUiObserver =
+ CFMRadioPropertyObserver::NewLC( *this,
+ KPSUidVoiceUiAccMonitor,
+ KVoiceUiOpenKey,
+ CFMRadioPropertyObserver::EFMRadioPropertyInt );
+
+ iPropertyArray.AppendL( voiceUiObserver );
+ CleanupStack::Pop( voiceUiObserver );
+ // Initialize call state observer.
+ iCallStatusObserver = CFMRadioPropertyObserver::NewL( *this,
+ KPSUidCtsyCallInformation,
+ KCTsyCallState,
+ CFMRadioPropertyObserver::EFMRadioPropertyInt);
+
+ iCallStatusObserver->ActivateL();
+ iIsCallActive = iCallStatusObserver->ValueInt() != EPSCTsyCallStateNone;
+
+ iAutoResumeTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+
+#ifndef __WINS__
+#ifdef __FMRADIO_ADVANCED_AUTO_RESUME
+ // Define audio types for not resuming.
+ // Audio categories are currently defined by adaptation of each hw platform.
+ // Nokia adaptation uses following definitions, which must be replaced by corresponding
+ // adaptation specific definitions of licensee adaptation.
+ // No general Symbian Foundation definitions for categories exists yet.
+ iNoAutoResumeAudioCategories = RArray<TInt>( KFMRadioAudioCategoryArrayGranularity );
+ iNoAutoResumeAudioCategories.AppendL( ECatMediaPlayer );
+ iNoAutoResumeAudioCategories.AppendL( ECatMobileTv );
+ iNoAutoResumeAudioCategories.AppendL( ECatUnknownPlayer );
+ iNoAutoResumeAudioCategories.Compress();
+#endif // __FMRADIO_ADVANCED_AUTO_RESUME
+ // Start listening audio client events.
+ CFMRadioPropertyObserver* audioPolicyObserver =
+ CFMRadioPropertyObserver::NewLC( *this,
+ KPSUidMMFAudioServer,
+ KAudioPolicyAudioClients,
+ CFMRadioPropertyObserver::EFMRadioPropertyByteArray );
+
+ iPropertyArray.AppendL( audioPolicyObserver );
+ CleanupStack::Pop( audioPolicyObserver );
+#endif
+ for ( TInt i = 0; i < iPropertyArray.Count(); i++ )
+ {
+ iPropertyArray[i]->ActivateL();
+ }
+
+ TInt networkAvailability = iPropertyArray[EFMRadioNetworkCoverageProperty]->ValueInt();
+
+ if (networkAvailability == ESANetworkAvailable)
+ {
+ iIsNetworkCoverage = ETrue;
+ }
+ else
+ {
+ iIsNetworkCoverage = EFalse;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CFMRadioSystemEventDetector::~CFMRadioSystemEventDetector
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CFMRadioSystemEventDetector::~CFMRadioSystemEventDetector()
+ {
+ delete iCallStatusObserver;
+ iPropertyArray.ResetAndDestroy();
+ iPropertyArray.Close();
+ iNoAutoResumeAudioCategories.Close();
+ delete iAutoResumeTimer;
+ }
+
+// ---------------------------------------------------------------------------
+// CFMRadioSystemEventDetector::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CFMRadioSystemEventDetector* CFMRadioSystemEventDetector::NewL(
+ MFMRadioSystemEventDetectorObserver& aObserver)
+ {
+ CFMRadioSystemEventDetector* self = new (ELeave) CFMRadioSystemEventDetector(aObserver);
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CFMRadioSystemEventDetector::HandlePropertyChangeL
+// Handling of the int property changes is done here.
+// Observer components are getting notifications in correspondence with what
+// has changed
+// ---------------------------------------------------------------------------
+//
+void CFMRadioSystemEventDetector::HandlePropertyChangeL( const TUid& aCategory,
+ const TUint aKey,
+ const TInt aValue )
+ {
+ if (aCategory == KUidSystemCategory && aKey == KUidNetworkStatusValue)
+ {
+ switch (aValue)
+ {
+ case ESANetworkAvailable:
+ {
+ if (!iIsNetworkCoverage)
+ {
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector - iObserver NetworkUpCallbackL") ) );
+ iIsNetworkCoverage = ETrue;
+ iObserver.NetworkUpCallbackL();
+ }
+ break;
+ }
+ case ESANetworkUnAvailable:
+ {
+ if (iIsNetworkCoverage)
+ {
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector - iObserver NetworkDownCallbackL") ) );
+ iIsNetworkCoverage = EFalse;
+ iObserver.NetworkDownCallbackL();
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ else if ( aCategory == KPSUidCtsyCallInformation && aKey == KCTsyCallState )
+ {
+ if ( ( !iIsCallActive ) && ( aValue > EPSCTsyCallStateNone ) )
+ {
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector - iObserver iIsCallActive = ETrue;") ) );
+ iIsCallActive = ETrue;
+ iObserver.CallActivatedCallbackL();
+ }
+ else if ( ( iIsCallActive ) && ( aValue <= EPSCTsyCallStateNone ) )
+ {
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector - iObserver iIsCallActive = EFalse;") ) );
+ iIsCallActive = EFalse;
+ iObserver.CallDeactivatedCallbackL();
+ }
+ else
+ {
+ // No change
+ }
+ }
+ else if ( aCategory == KPSUidVoiceUiAccMonitor && aKey == KVoiceUiOpenKey )
+ {
+ switch (aValue)
+ {
+ case KVoiceUiIsClose:
+ {
+ if (iIsVoiceUiActive)
+ {
+ iIsVoiceUiActive = EFalse;
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector - iObserver KVoiceUiIsClose") ) );
+ if ( iNumberOfActiveAudioClients == 0 )
+ {
+ NotifyAudioResourcesAvailability();
+ }
+ }
+ break;
+ }
+ case KVoiceUiIsOpen:
+ {
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector - iObserver KVoiceUiIsOpen") ) );
+ if (!iIsVoiceUiActive)
+ {
+ iIsVoiceUiActive = ETrue;
+
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ else // NOP
+ {
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// CFMRadioSystemEventDetector::HandlePropertyChangeErrorL
+// This is a callback function which is called when a P&S components returns
+// an error
+// ---------------------------------------------------------------------------
+//
+void CFMRadioSystemEventDetector::HandlePropertyChangeErrorL( const TUid& /*aCategory*/,
+ const TUint /*aKey*/,
+ TInt /*aError*/ )
+ {
+ }
+
+#ifndef __WINS__
+// ---------------------------------------------------------------------------
+// Handling of the byte array property changes is done here.
+// Observer components are getting notifications in correspondence with what
+// has changed
+// ---------------------------------------------------------------------------
+//
+void CFMRadioSystemEventDetector::HandlePropertyChangeL( const TUid& aCategory,
+ const TUint aKey,
+ const TDesC8& aValue)
+ {
+ if ( aCategory == KPSUidMMFAudioServer )
+ {
+ if ( aKey == KAudioPolicyAudioClients )
+ {
+ TAudioClientList audioClients;
+ audioClients.Copy( aValue );
+
+ iNumberOfActiveAudioClients = audioClients().iNumOfProcesses;
+ FTRACE(FPrint(_L("CFMRadioSystemEventDetector::HandlePropertyChangeL() number of audio clients: = %d"), iNumberOfActiveAudioClients));
+
+ TBool autoResumePossible = ETrue;
+
+ if ( iNumberOfActiveAudioClients > 0 )
+ {
+ // cancel any previously started audio resume call
+ iAutoResumeTimer->Cancel();
+ }
+
+ // Check all playing audios!
+ for ( TInt i = 0; i < iNumberOfActiveAudioClients; i++ )
+ {
+ TInt cat = audioClients().iClientCategoryList[i];
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector - audio category %d"), cat ) );
+
+ if ( iNoAutoResumeAudioCategories.Find(cat) != KErrNotFound )
+ {
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector - Radio audio will not be resumed") ) );
+ autoResumePossible = EFalse;
+ }
+ else
+ {
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector - radio audio might be resumed") ) );
+ }
+ }
+
+ // Decide audio resource availability from audio category info.
+ if ( !autoResumePossible )
+ {
+ // Auto resume forbidden
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector::HandlePropertyChangeL - AudioAutoResumeForbiddenL ") ) );
+ iObserver.AudioAutoResumeForbiddenL();
+ }
+ else if ( iNumberOfActiveAudioClients == 0 )
+ {
+ if ( !iIsVoiceUiActive )
+ {
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector::HandlePropertyChangeL - NotifyAudioResourcesAvailabilityL") ) );
+ NotifyAudioResourcesAvailability();
+ }
+ }
+ else
+ {
+ // NOP. Some auto resume neutral audio is playing
+ }
+ }
+ }
+ }
+
+
+#endif //__WINS__
+
+#ifdef __WINS__
+// ---------------------------------------------------------------------------
+// Dummy version for WINS in order to avoid compiler warnings.
+// The real implementation of function is above.
+// ---------------------------------------------------------------------------
+//
+void CFMRadioSystemEventDetector::HandlePropertyChangeL( const TUid& /*aCategory*/,
+ const TUint /*aKey*/,
+ const TDesC8& /*aValue*/)
+ {
+ }
+#endif // __WINS__
+
+// Handling of the text property changes is done here.
+// Observer components are getting notifications in correspondence with what
+// has changed
+// ---------------------------------------------------------------------------
+//
+void CFMRadioSystemEventDetector::HandlePropertyChangeL( const TUid& /*aCategory*/,
+ const TUint /*aKey*/,
+ const TDesC& /*aValue*/)
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// CFMRadioSystemEventDetector::IsNetworkCoverage
+// ---------------------------------------------------------------------------
+//
+TBool CFMRadioSystemEventDetector::IsNetworkCoverage() const
+ {
+#ifdef __WINS__
+ return ETrue;
+#else
+ return iIsNetworkCoverage;
+#endif
+ }
+
+// ---------------------------------------------------------------------------
+// CFMRadioSystemEventDetector::IsCallActive
+// ---------------------------------------------------------------------------
+//
+TBool CFMRadioSystemEventDetector::IsCallActive() const
+ {
+ return iIsCallActive;
+ }
+
+// ---------------------------------------------------------------------------
+// CFMRadioSystemEventDetector::NotifyAudioResourcesAvailability
+// ---------------------------------------------------------------------------
+//
+void CFMRadioSystemEventDetector::NotifyAudioResourcesAvailability()
+ {
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector::NotifyAudioResourcesAvailability") ) );
+ // call observer interface after a delay
+ iAutoResumeTimer->Cancel();
+ iAutoResumeTimer->Start( TTimeIntervalMicroSeconds32( KFMRadioAutoResumeDelay ),
+ TTimeIntervalMicroSeconds32( 0 ),
+ TCallBack( StaticAutoResumeTimerCallback, this ) );
+ }
+
+// ---------------------------------------------------------------------------
+// CFMRadioSystemEventDetector::StaticAutoResumeTimerCallback
+// ---------------------------------------------------------------------------
+//
+TInt CFMRadioSystemEventDetector::StaticAutoResumeTimerCallback( TAny* aSelfPtr )
+ {
+ FTRACE( FPrint( _L("CFMRadioSystemEventDetector::StaticAutoResumeTimerCallback") ) );
+ CFMRadioSystemEventDetector* self = static_cast<CFMRadioSystemEventDetector*>( aSelfPtr );
+ if ( self )
+ {
+ self->iAutoResumeTimer->Cancel();
+ TRAP_IGNORE( self->iObserver.AudioResourcesAvailableL() )
+ }
+ return KErrNone;
+ }
+
+// end of file