diff -r ae942d28ec0e -r 2455ef1f5bbc javauis/mmapi_akn/baseline/src/cmmavolumecontrol.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javauis/mmapi_akn/baseline/src/cmmavolumecontrol.cpp Wed Sep 01 12:33:18 2010 +0100 @@ -0,0 +1,348 @@ +/* +* Copyright (c) 2002-2007 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: This class is used for volume setting +* +*/ + + +// INCLUDE FILES +#include "cmmaplayer.h" +#include "cmmavolumecontrol.h" +#include +#include +#include +#include + +_LIT(KMMAVolumeErrorMsg, "Can't set volume level"); + +const TInt KMMAJavaSoundIndex = 0; +const TInt KMMAProfileSoundIndex = 1; +const TInt KMMAGlobalVolumeSoundIndex = 2; +const TInt KAudioEarpiece = 3; + +void CMMAVolumeControl::StaticSetLevelL(CMMAVolumeControl* aVolumeControl, + TInt aLevel) +{ + // Java level is the first + aVolumeControl->SetVolumeLevelL(KMMAJavaSoundIndex, aLevel); +} + +void CMMAVolumeControl::StaticGetLevelL(CMMAVolumeControl* aVolumeControl, + TInt* aLevel) +{ + // Java level is the first + aVolumeControl->GetVolumeLevelL(KMMAJavaSoundIndex, aLevel); +} + + +EXPORT_C CMMAVolumeControl::CMMAVolumeControl(CMMAPlayer* aPlayer) + : iPlayer(aPlayer), iLevel(KMMAVolumeMaxLevel) +{ +} + + +EXPORT_C CMMAVolumeControl::~CMMAVolumeControl() +{ + delete iProfChangeNotifier; + iLevels.Close(); +} + + +EXPORT_C void CMMAVolumeControl::ConstructBaseL() +{ + iPlayer->AddStateListenerL(this); + + // Add level for javasound, will set in StaticSetLevelL method. + SetJavaSoundVolumeLevelL(); + + SetProfileSoundVolumeLevelL(); + + // Sets level to 0 if profile isn't on + iLevel = CalculateLevel(); + + // The default value is not yet known. Volume control may change the + // volume of the controller before it has been retrieved so when the + // state of the player is changed the Java volume is retrieved from + // the controller. + iLevels[ KMMAJavaSoundIndex ] = KErrNotFound; +} + +void CMMAVolumeControl::SetJavaSoundVolumeLevelL() +{ + // In constructor iLevels array is empty and Java level will be the first, + // KMMAJavaSoundIndex. + AddLevelL(); +} + +void CMMAVolumeControl::SetProfileSoundVolumeLevelL() +{ + // Add level for profile, level's index will be 1, KMMAProfileSoundIndex + AddLevelL(); +} + +void CMMAVolumeControl::SetProfilesBasedSoundMutingL() +{ + //Get the current active profile id. + MProfileEngine* lProfileEngine = CreateProfileEngineL(); + iProfileId =lProfileEngine->ActiveProfileId(); + lProfileEngine->Release(); + + // if profile is silent or meeting and no headset or bluetooth device + // connected,set profile volume level to 0, otherwise keep the original + // value 100 + if ( (EProfileSilentId == iProfileId || EProfileMeetingId == iProfileId)&& + iAudioOutputPreference != KAudioEarpiece ) + { + iLevels[ KMMAProfileSoundIndex ] = 0; + } + + // Gets notfication about profile changes + // Notification is sent to MProfileChangeObserver::HandleActiveProfileEventL() + iProfChangeNotifier = CProfileChangeNotifyHandler::NewL( this ); + // Sets level to 0 if profile isn't on + iLevel = CalculateLevel(); + +} +EXPORT_C void CMMAVolumeControl::HandleActiveProfileEventL( + TProfileEvent aProfileEvent, TInt aProfileId) +{ + switch (aProfileEvent) + { + case EProfileNewActiveProfile: + { + // New profile is activated + // Update the volume level, if profile is changed to silent or meeting + // then mute it, if no headset or bluetooth device is connected + // else set it to max volume level + TInt level = 0; + iProfileId = aProfileId; + + if ( EProfileSilentId != aProfileId && + EProfileMeetingId != aProfileId) + { + + level = KMMAVolumeMaxLevel; + } + else if (iAudioOutputPreference == KAudioEarpiece) + { + level = KMMAVolumeMaxLevel; + } + else + { + level = 0; + } + TRAPD( error, SetVolumeLevelL( KMMAProfileSoundIndex, level ) ); + if ( error != KErrNone ) + { + iPlayer->PostStringEvent( CMMAPlayerEvent::EError, + KMMAVolumeErrorMsg ); + } + break; + } + default: // do nothing + break; + } +} + + + +EXPORT_C const TDesC& CMMAVolumeControl::ClassName() const +{ + return KMMAVolumeControlName; +} + +void CMMAVolumeControl::SetLevelL(TInt aLevel) +{ + // Level cannot be set to derived control if player is not prefetched. + if (iPlayer->State() > CMMAPlayer::ERealized) + { + DoSetLevelL(aLevel); + } + iLevel = aLevel; +} + +EXPORT_C void CMMAVolumeControl::StateChanged(TInt aState) +{ + DEBUG_INT("CMMAVolumeControl::StateChanged - state %d", aState); + // Set the volume if the player is prefetched + if (aState == CMMAPlayer::EPrefetched) + { + TRAPD(error, + { + // Get the default value for the Java sound level + if (iLevels[ KMMAJavaSoundIndex ] == KErrNotFound) + { + iLevels[ KMMAJavaSoundIndex ] = DoGetLevelL(); + iLevel = CalculateLevel(); + } + SetLevelL(iLevel); + + }); + if (error != KErrNone) + { + iPlayer->PostStringEvent(CMMAPlayerEvent::EError, + KMMAVolumeErrorMsg); + } + } + + // Level is already set for Global Volume so no need to set it again + // Notify the initial global volume value to java + // Notify only if STATE == CMMAPlayer::ERealized + // Error ID AKUR-7G69Q5 GLOBAL VOLUME EVENT CR + if (aState == CMMAPlayer::ERealized) + { + if ((iLevels.Count() - 1) == KMMAGlobalVolumeSoundIndex) + { + if ((iLevels[ KMMAGlobalVolumeSoundIndex ] != KErrNotFound) && + (iLevels[ KMMAGlobalVolumeSoundIndex] != iInitialGlobalVolumeLevel)) + { + DEBUG("MMA::CMMAVolumeControl::StateChanged : Post GLOBAL VOL EVENT "); + DEBUG_INT("MMA::CMMAVolumeControl::StateChanged : Post complete Val = %d ", + iLevels[ KMMAGlobalVolumeSoundIndex ]); + iPlayer->PostLongEvent(CMMAPlayerEvent::ENOKIA_EXTERNAL_VOLUME_EVENT, + iLevels[ KMMAGlobalVolumeSoundIndex ]); + } + } + } +} + +EXPORT_C void CMMAVolumeControl::RefreshVolume() +{ + DEBUG("MMA::CMMAVolumeControl::RefreshVolume ++ "); + TRAPD(error, + { + // Get the default value for the Java sound level + if (iLevels[ KMMAJavaSoundIndex ] == KErrNotFound) + { + iLevels[ KMMAJavaSoundIndex ] = DoGetLevelL(); + iLevel = CalculateLevel(); + } + SetLevelL(iLevel); + + }); + + if (error != KErrNone) + { + iPlayer->PostStringEvent(CMMAPlayerEvent::EError, + KMMAVolumeErrorMsg); + } + DEBUG("MMA::CMMAVolumeControl::RefreshVolume -- "); +} + +EXPORT_C void CMMAVolumeControl::RefreshControl() +{ + RefreshVolume(); +} + +EXPORT_C TInt CMMAVolumeControl::AddLevelL() +{ + User::LeaveIfError(iLevels.Append(KMMAVolumeMaxLevel)); + + // New level is the last element + return iLevels.Count() - 1; +} + +EXPORT_C void CMMAVolumeControl::SetVolumeLevelL(TInt aLevelIndex, + TInt aVolumeLevel) +{ + DEBUG_INT2("CMMAVolumeControl::SetVolumeLevelL - setting index %d, level %d", + aLevelIndex, aVolumeLevel); + if (0 >= iLevels.Count() || iLevels.Count() > 4) + { + return ; + } + TInt oldVolumeLevel = iLevels[ aLevelIndex ]; + iLevels[ aLevelIndex ] = aVolumeLevel; + SetLevelL(CalculateLevel()); + + // send event if level is really changed + if ((aLevelIndex == KMMAJavaSoundIndex) && + (aVolumeLevel != oldVolumeLevel)) + { + iPlayer->PostObjectEvent(CMMAPlayerEvent::EVolumeChanged, + iControlObject); + } + + // send event if global volume level is really changed + // Error ID AKUR-7G69Q5 GLOBAL VOLUME EVENT CR + if ((aLevelIndex == KMMAGlobalVolumeSoundIndex) && + (aVolumeLevel != oldVolumeLevel)) + { + + iPlayer->PostLongEvent(CMMAPlayerEvent::ENOKIA_EXTERNAL_VOLUME_EVENT, + iLevels[ aLevelIndex ]); + } +} + +void CMMAVolumeControl::InitializeGlobalVolumeLevel(TInt aGlobalVolumeLevel) +{ + iInitialGlobalVolumeLevel = aGlobalVolumeLevel; +} +void CMMAVolumeControl::GetVolumeLevelL(TInt aLevelIndex, + TInt* aVolumeLevel) +{ + DEBUG_INT("CMMAVolumeControl::GetVolumeLevelL - level index %d", aLevelIndex); + + // Return max volume if the default Java volume level is not yet known + if (aLevelIndex == KMMAJavaSoundIndex && + iLevels[ KMMAJavaSoundIndex ] == KErrNotFound) + { + *aVolumeLevel = KMMAVolumeMaxLevel; + return; + } + + *aVolumeLevel = iLevels[ aLevelIndex ]; + + DEBUG_INT("CMMAVolumeControl::GetVolumeLevelL - level %d", *aVolumeLevel); +} + +EXPORT_C void CMMAVolumeControl::SetAudioOutputPreferenceL( + TInt aRoutingPreference) +{ + iAudioOutputPreference = aRoutingPreference; + // If audio o/p preference is set to private then set the profile sound + // to max value else if profile is in silent or meeting set the profile + // sound to 0 + if ( iAudioOutputPreference == KAudioEarpiece) + { + SetVolumeLevelL(KMMAProfileSoundIndex, KMMAVolumeMaxLevel); + } + else if (EProfileSilentId == iProfileId || EProfileMeetingId == iProfileId) + { + SetVolumeLevelL(KMMAProfileSoundIndex, 0); + } +} + +TInt CMMAVolumeControl::CalculateLevel() +{ + TInt levelCount = iLevels.Count(); + + // 64 bit integer must be used to have more than 4 levels. + TInt64 level = KMMAVolumeMaxLevel; + TInt64 sum = 1; + + // All levels in the array are percentage of the max volume (0..100). + // Actual sound level will be multiplying all levels. + for (TInt i = 0; i < levelCount; i++) + { + DEBUG_INT2("CMMAVolumeControl::CalculateLevel value at iLevels[ %d ] is %d",i,iLevels[i]); + // If the level is not known it is expected to be max volume + level = (iLevels[ i ] == KErrNotFound ? + level * KMMAVolumeMaxLevel : + level * iLevels[ i ]); + sum *= KMMAVolumeMaxLevel; + } + return level / sum; +} +// END OF FILE