javauis/mmapi_akn/baseline/src/cmmavolumecontrol.cpp
branchRCL_3
changeset 26 2455ef1f5bbc
equal deleted inserted replaced
25:ae942d28ec0e 26:2455ef1f5bbc
       
     1 /*
       
     2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This class is used for volume setting
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 //  INCLUDE FILES
       
    20 #include "cmmaplayer.h"
       
    21 #include "cmmavolumecontrol.h"
       
    22 #include <jdebug.h>
       
    23 #include <MProfile.h>
       
    24 #include <MProfileEngine.h>
       
    25 #include <CProfileChangeNotifyHandler.h>
       
    26 
       
    27 _LIT(KMMAVolumeErrorMsg, "Can't set volume level");
       
    28 
       
    29 const TInt KMMAJavaSoundIndex = 0;
       
    30 const TInt KMMAProfileSoundIndex = 1;
       
    31 const TInt KMMAGlobalVolumeSoundIndex = 2;
       
    32 const TInt KAudioEarpiece = 3;
       
    33 
       
    34 void CMMAVolumeControl::StaticSetLevelL(CMMAVolumeControl* aVolumeControl,
       
    35                                         TInt aLevel)
       
    36 {
       
    37     // Java level is the first
       
    38     aVolumeControl->SetVolumeLevelL(KMMAJavaSoundIndex, aLevel);
       
    39 }
       
    40 
       
    41 void CMMAVolumeControl::StaticGetLevelL(CMMAVolumeControl* aVolumeControl,
       
    42                                         TInt* aLevel)
       
    43 {
       
    44     // Java level is the first
       
    45     aVolumeControl->GetVolumeLevelL(KMMAJavaSoundIndex, aLevel);
       
    46 }
       
    47 
       
    48 
       
    49 EXPORT_C CMMAVolumeControl::CMMAVolumeControl(CMMAPlayer* aPlayer)
       
    50         : iPlayer(aPlayer), iLevel(KMMAVolumeMaxLevel)
       
    51 {
       
    52 }
       
    53 
       
    54 
       
    55 EXPORT_C CMMAVolumeControl::~CMMAVolumeControl()
       
    56 {
       
    57     delete iProfChangeNotifier;
       
    58     iLevels.Close();
       
    59 }
       
    60 
       
    61 
       
    62 EXPORT_C void CMMAVolumeControl::ConstructBaseL()
       
    63 {
       
    64     iPlayer->AddStateListenerL(this);
       
    65 
       
    66     // Add level for javasound, will set in StaticSetLevelL method.
       
    67     SetJavaSoundVolumeLevelL();
       
    68 
       
    69     SetProfileSoundVolumeLevelL();
       
    70 
       
    71     // Sets level to 0 if profile isn't on
       
    72     iLevel = CalculateLevel();
       
    73 
       
    74     // The default value is not yet known. Volume control may change the
       
    75     // volume of the controller before it has been retrieved so when the
       
    76     // state of the player is changed the Java volume is retrieved from
       
    77     // the controller.
       
    78     iLevels[ KMMAJavaSoundIndex ] = KErrNotFound;
       
    79 }
       
    80 
       
    81 void CMMAVolumeControl::SetJavaSoundVolumeLevelL()
       
    82 {
       
    83     // In constructor iLevels array is empty and Java level will be the first,
       
    84     // KMMAJavaSoundIndex.
       
    85     AddLevelL();
       
    86 }
       
    87 
       
    88 void CMMAVolumeControl::SetProfileSoundVolumeLevelL()
       
    89 {
       
    90     // Add level for profile, level's index will be 1, KMMAProfileSoundIndex
       
    91     AddLevelL();
       
    92 }
       
    93 
       
    94 void CMMAVolumeControl::SetProfilesBasedSoundMutingL()
       
    95 {
       
    96     //Get the current active profile id.
       
    97     MProfileEngine* lProfileEngine = CreateProfileEngineL();
       
    98     iProfileId =lProfileEngine->ActiveProfileId();
       
    99     lProfileEngine->Release();
       
   100 
       
   101     // if profile is silent or meeting and no headset or bluetooth device
       
   102     // connected,set profile volume level to 0, otherwise keep the original
       
   103     // value 100
       
   104     if ( (EProfileSilentId == iProfileId || EProfileMeetingId == iProfileId)&&
       
   105             iAudioOutputPreference != KAudioEarpiece )
       
   106     {
       
   107         iLevels[ KMMAProfileSoundIndex ] = 0;
       
   108     }
       
   109 
       
   110     // Gets notfication about profile changes
       
   111     // Notification is sent to MProfileChangeObserver::HandleActiveProfileEventL()
       
   112     iProfChangeNotifier = CProfileChangeNotifyHandler::NewL( this );
       
   113     // Sets level to 0 if profile isn't on
       
   114     iLevel = CalculateLevel();
       
   115 
       
   116 }
       
   117 EXPORT_C void CMMAVolumeControl::HandleActiveProfileEventL(
       
   118                                  TProfileEvent aProfileEvent, TInt aProfileId)
       
   119 {
       
   120     switch (aProfileEvent)
       
   121     {
       
   122     case EProfileNewActiveProfile:
       
   123     {
       
   124         // New profile is activated
       
   125         // Update the volume level, if profile is changed to silent or meeting
       
   126         // then mute it, if no headset or bluetooth device is connected
       
   127         // else set it to max volume level
       
   128         TInt level = 0;
       
   129         iProfileId = aProfileId;
       
   130 
       
   131         if ( EProfileSilentId != aProfileId &&
       
   132                 EProfileMeetingId != aProfileId)
       
   133         {
       
   134 
       
   135             level = KMMAVolumeMaxLevel;
       
   136         }
       
   137         else if (iAudioOutputPreference == KAudioEarpiece)
       
   138         {
       
   139             level = KMMAVolumeMaxLevel;
       
   140         }
       
   141         else
       
   142         {
       
   143             level = 0;
       
   144         }
       
   145         TRAPD( error, SetVolumeLevelL( KMMAProfileSoundIndex, level ) );
       
   146         if ( error != KErrNone )
       
   147         {
       
   148             iPlayer->PostStringEvent( CMMAPlayerEvent::EError,
       
   149                                       KMMAVolumeErrorMsg );
       
   150         }
       
   151         break;
       
   152     }
       
   153     default: // do nothing
       
   154         break;
       
   155     }
       
   156 }
       
   157 
       
   158 
       
   159 
       
   160 EXPORT_C const TDesC& CMMAVolumeControl::ClassName() const
       
   161 {
       
   162     return KMMAVolumeControlName;
       
   163 }
       
   164 
       
   165 void CMMAVolumeControl::SetLevelL(TInt aLevel)
       
   166 {
       
   167     // Level cannot be set to derived control if player is not prefetched.
       
   168     if (iPlayer->State() > CMMAPlayer::ERealized)
       
   169     {
       
   170         DoSetLevelL(aLevel);
       
   171     }
       
   172     iLevel = aLevel;
       
   173 }
       
   174 
       
   175 EXPORT_C void CMMAVolumeControl::StateChanged(TInt aState)
       
   176 {
       
   177     DEBUG_INT("CMMAVolumeControl::StateChanged - state %d", aState);
       
   178     // Set the volume if the player is prefetched
       
   179     if (aState == CMMAPlayer::EPrefetched)
       
   180     {
       
   181         TRAPD(error,
       
   182         {
       
   183             // Get the default value for the Java sound level
       
   184             if (iLevels[ KMMAJavaSoundIndex ] == KErrNotFound)
       
   185             {
       
   186                 iLevels[ KMMAJavaSoundIndex ] = DoGetLevelL();
       
   187                 iLevel = CalculateLevel();
       
   188             }
       
   189             SetLevelL(iLevel);
       
   190 
       
   191         });
       
   192         if (error != KErrNone)
       
   193         {
       
   194             iPlayer->PostStringEvent(CMMAPlayerEvent::EError,
       
   195                                      KMMAVolumeErrorMsg);
       
   196         }
       
   197     }
       
   198 
       
   199     // Level is already set for Global Volume so no need to set it again
       
   200     // Notify the initial global volume value to java
       
   201     // Notify only if STATE == CMMAPlayer::ERealized
       
   202     // Error ID AKUR-7G69Q5 GLOBAL VOLUME EVENT CR
       
   203     if (aState == CMMAPlayer::ERealized)
       
   204     {
       
   205         if ((iLevels.Count() - 1) == KMMAGlobalVolumeSoundIndex)
       
   206         {
       
   207             if ((iLevels[ KMMAGlobalVolumeSoundIndex ] != KErrNotFound) && 
       
   208             (iLevels[ KMMAGlobalVolumeSoundIndex] != iInitialGlobalVolumeLevel))
       
   209             {
       
   210                 DEBUG("MMA::CMMAVolumeControl::StateChanged : Post GLOBAL VOL EVENT  ");
       
   211                 DEBUG_INT("MMA::CMMAVolumeControl::StateChanged : Post complete Val = %d ",
       
   212                                        iLevels[ KMMAGlobalVolumeSoundIndex ]);
       
   213                 iPlayer->PostLongEvent(CMMAPlayerEvent::ENOKIA_EXTERNAL_VOLUME_EVENT,
       
   214                                        iLevels[ KMMAGlobalVolumeSoundIndex ]);
       
   215             }
       
   216         }
       
   217     }
       
   218 }
       
   219 
       
   220 EXPORT_C void CMMAVolumeControl::RefreshVolume()
       
   221 {
       
   222     DEBUG("MMA::CMMAVolumeControl::RefreshVolume ++ ");
       
   223     TRAPD(error,
       
   224     {
       
   225         // Get the default value for the Java sound level
       
   226         if (iLevels[ KMMAJavaSoundIndex ] == KErrNotFound)
       
   227         {
       
   228             iLevels[ KMMAJavaSoundIndex ] = DoGetLevelL();
       
   229             iLevel = CalculateLevel();
       
   230         }
       
   231         SetLevelL(iLevel);
       
   232 
       
   233     });
       
   234 
       
   235     if (error != KErrNone)
       
   236     {
       
   237         iPlayer->PostStringEvent(CMMAPlayerEvent::EError,
       
   238                                  KMMAVolumeErrorMsg);
       
   239     }
       
   240     DEBUG("MMA::CMMAVolumeControl::RefreshVolume -- ");
       
   241 }
       
   242 
       
   243 EXPORT_C void CMMAVolumeControl::RefreshControl()
       
   244 {
       
   245     RefreshVolume();
       
   246 }
       
   247 
       
   248 EXPORT_C TInt CMMAVolumeControl::AddLevelL()
       
   249 {
       
   250     User::LeaveIfError(iLevels.Append(KMMAVolumeMaxLevel));
       
   251 
       
   252     // New level is the last element
       
   253     return iLevels.Count() - 1;
       
   254 }
       
   255 
       
   256 EXPORT_C void CMMAVolumeControl::SetVolumeLevelL(TInt aLevelIndex,
       
   257         TInt aVolumeLevel)
       
   258 {
       
   259     DEBUG_INT2("CMMAVolumeControl::SetVolumeLevelL - setting index %d, level %d",
       
   260                aLevelIndex, aVolumeLevel);
       
   261     if (0 >= iLevels.Count() ||  iLevels.Count() > 4)
       
   262     {
       
   263         return ;
       
   264     }
       
   265     TInt oldVolumeLevel = iLevels[ aLevelIndex ];
       
   266     iLevels[ aLevelIndex ] = aVolumeLevel;
       
   267     SetLevelL(CalculateLevel());
       
   268 
       
   269     // send event if level is really changed
       
   270     if ((aLevelIndex == KMMAJavaSoundIndex) &&
       
   271             (aVolumeLevel != oldVolumeLevel))
       
   272     {
       
   273         iPlayer->PostObjectEvent(CMMAPlayerEvent::EVolumeChanged,
       
   274                                  iControlObject);
       
   275     }
       
   276 
       
   277     // send event if global volume level is really changed
       
   278     // Error ID AKUR-7G69Q5 GLOBAL VOLUME EVENT CR
       
   279     if ((aLevelIndex == KMMAGlobalVolumeSoundIndex) &&
       
   280             (aVolumeLevel != oldVolumeLevel))
       
   281     {
       
   282 
       
   283         iPlayer->PostLongEvent(CMMAPlayerEvent::ENOKIA_EXTERNAL_VOLUME_EVENT,
       
   284                                iLevels[ aLevelIndex ]);
       
   285     }
       
   286 }
       
   287 
       
   288 void CMMAVolumeControl::InitializeGlobalVolumeLevel(TInt aGlobalVolumeLevel)
       
   289 {
       
   290     iInitialGlobalVolumeLevel = aGlobalVolumeLevel;
       
   291 }
       
   292 void CMMAVolumeControl::GetVolumeLevelL(TInt aLevelIndex,
       
   293                                         TInt* aVolumeLevel)
       
   294 {
       
   295     DEBUG_INT("CMMAVolumeControl::GetVolumeLevelL - level index %d", aLevelIndex);
       
   296 
       
   297     // Return max volume if the default Java volume level is not yet known
       
   298     if (aLevelIndex == KMMAJavaSoundIndex &&
       
   299             iLevels[ KMMAJavaSoundIndex ] == KErrNotFound)
       
   300     {
       
   301         *aVolumeLevel = KMMAVolumeMaxLevel;
       
   302         return;
       
   303     }
       
   304 
       
   305     *aVolumeLevel = iLevels[ aLevelIndex ];
       
   306 
       
   307     DEBUG_INT("CMMAVolumeControl::GetVolumeLevelL - level %d", *aVolumeLevel);
       
   308 }
       
   309 
       
   310 EXPORT_C void CMMAVolumeControl::SetAudioOutputPreferenceL(
       
   311     TInt aRoutingPreference)
       
   312 {
       
   313     iAudioOutputPreference = aRoutingPreference;
       
   314     // If audio o/p preference is set to private then set the profile sound
       
   315     // to max value else if profile is in silent or meeting set the profile
       
   316     // sound to 0   
       
   317     if ( iAudioOutputPreference == KAudioEarpiece)
       
   318     {
       
   319        SetVolumeLevelL(KMMAProfileSoundIndex, KMMAVolumeMaxLevel);
       
   320     }
       
   321     else if (EProfileSilentId == iProfileId || EProfileMeetingId == iProfileId)
       
   322     {
       
   323        SetVolumeLevelL(KMMAProfileSoundIndex, 0);
       
   324     }
       
   325 }
       
   326 
       
   327 TInt CMMAVolumeControl::CalculateLevel()
       
   328 {
       
   329     TInt levelCount = iLevels.Count();
       
   330 
       
   331     // 64 bit integer must be used to have more than 4 levels.
       
   332     TInt64 level = KMMAVolumeMaxLevel;
       
   333     TInt64 sum = 1;
       
   334 
       
   335     // All levels in the array are percentage of the max volume (0..100).
       
   336     // Actual sound level will be multiplying all levels.
       
   337     for (TInt i = 0; i < levelCount; i++)
       
   338     {
       
   339         DEBUG_INT2("CMMAVolumeControl::CalculateLevel value at iLevels[ %d ] is %d",i,iLevels[i]);
       
   340         // If the level is not known it is expected to be max volume
       
   341         level = (iLevels[ i ] == KErrNotFound ?
       
   342                  level * KMMAVolumeMaxLevel :
       
   343                  level * iLevels[ i ]);
       
   344         sum *= KMMAVolumeMaxLevel;
       
   345     }
       
   346     return level / sum;
       
   347 }
       
   348 //  END OF FILE