diff -r 000000000000 -r ff3acec5bc43 mpxmusicplayer/metadatahandler/src/mpxmetadatahandlerimp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mpxmusicplayer/metadatahandler/src/mpxmetadatahandlerimp.cpp Thu Dec 17 08:45:05 2009 +0200 @@ -0,0 +1,849 @@ +/* +* Copyright (c) 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: Implementation of metadata handler +* +*/ + + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mpxmetadatahandler.h" +#include "mpxmetadatahandlerimp.h" + +// CONSTANTS +const TInt KMPXOneSecInMilliSecs( 1000 ); + +// Definition of remotely controllable application settings +// The commented settings are not used here, included for reference. +_LIT( KMPlayerSettingsDefs, "mplayeravrcpsettings.rsc" ); +const TInt KAvrcpEqualizerMode = 0x01; +const TInt KAvrcpRepeatMode = 0x02; +const TInt KAvrcpShuffleMode = 0x03; +//const TInt KAvrcpScanMode = 0x04; + +const TInt KAvrcpOff = 0x01; +const TInt KAvrcpOn = 0x02; + +// Off 0x01 +//const TInt KAvrcpSingleTrackRepeat = 0x02; +//const TInt KAvrcpAllTracksRepeat = 0x03; +//const TInt KAvrcpGroupRepeat = 0x04; + +// Off 0x01 +const TInt KAvrcpAllTracksShuffle = 0x02; +//const TInt KAvrcpGroupShuffle = 0x03; + +// Extended settings defined for Music Player +// Note that these are also defined in mplayeravrcpsettings.rss +const TInt KAvrcpBassBoostMode = 0x80; +const TInt KAvrcpStereoWideningMode = 0x81; + +const TUid KCRUidMusicPlayerSettings = {0x101FFCDC}; +const TUint32 KMPlayerEqPresetId = 0x00000001; + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// C++ default constructor can NOT contain any code, that might leave. +// --------------------------------------------------------------------------- +// +CMPXMetaDataHandlerImp::CMPXMetaDataHandlerImp() + { + } + +// --------------------------------------------------------------------------- +// Symbian 2nd phase constructor can leave. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::ConstructL(CRemConInterfaceSelector &aInterfaceSelector) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::ConstructL(CRemConInterfaceSelector)"); + + iPlayerInformationTarget = CPlayerInfoTarget::NewL(aInterfaceSelector, + iPlayerCapabilitiesObserver, + iPlayerApplicationSettingsObserver, + iPlayerEventsObserver, *this); + iMediaInfoTarget = CRemConMediaInformationTarget::NewL( aInterfaceSelector, *this ); + + iGroupNavigationTarget = CRemConGroupNavigationApiTarget::NewL( aInterfaceSelector, *this ); + + // Get the playback utility instance from engine. + iPlaybackUtility = MMPXPlaybackUtility::UtilityL( KPbModeDefault ); + iPlaybackUtility->AddObserverL( *this ); + + MMPXSource* s = iPlaybackUtility->Source(); + if ( s ) + { + RArray attrs; + CleanupClosePushL(attrs); + (void) attrs.Append( KMPXMediaGeneralTitle ); + (void) attrs.Append( KMPXMediaGeneralDuration ); + (void) attrs.Append( KMPXMediaGeneralId ); + (void) attrs.Append( KMPXMediaMusicArtist ); + (void) attrs.Append( KMPXMediaMusicAlbum ); + (void) attrs.Append( KMPXMediaMusicGenre ); + s->MediaL( attrs.Array(), *this, NULL ); + CleanupStack::PopAndDestroy( &attrs ); + } + + RFs fs; + User::LeaveIfError( fs.Connect() ); + CleanupClosePushL( fs ); + + TParse parse; + parse.Set( KMPlayerSettingsDefs, &KDC_RESOURCE_FILES_DIR, NULL ); + + TFileName resourceFile( parse.FullName() ); + + User::LeaveIfError( MPXUser::CompleteWithDllPath( resourceFile ) ); + BaflUtils::NearestLanguageFile( fs, resourceFile ); + CResourceFile* playerSettingsResourceFile = CResourceFile::NewLC( fs, resourceFile, 0, 0 ); + PlayerApplicationSettingsResourceInit::DefineAttributesL( *iPlayerApplicationSettingsObserver, *playerSettingsResourceFile ); + CleanupStack::PopAndDestroy( playerSettingsResourceFile ); + CleanupStack::PopAndDestroy( &fs ); + + // Adding two optional events, mandatory ERegisterNotificationPlaybackStatusChanged + // and ERegisterNotificationTrackChanged are added by SOS. + User::LeaveIfError( iPlayerCapabilitiesObserver->AddEvent(ERegisterNotificationPlaybackPosChanged)); + User::LeaveIfError( iPlayerCapabilitiesObserver->AddEvent(ERegisterNotificationPlayerApplicationSettingChanged)); + + iEqPresetListener = CEqualizerPresetChangeListener::NewL(*this); + iLastEqPresetId = iEqPresetListener->GetCurrentPresetL(); + iEqPresetListener->StartL(); + iTrackNumber = 0; + iColId.iUid = -1; + } + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +MMPXMetaDataHandler* CMPXMetaDataHandlerImp::NewL(CRemConInterfaceSelector &aInterfaceSelector) + { + CMPXMetaDataHandlerImp* self = new(ELeave)CMPXMetaDataHandlerImp(); + CleanupStack::PushL( self ); + self->ConstructL(aInterfaceSelector); + CleanupStack::Pop(self); + + return self; + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CMPXMetaDataHandlerImp::~CMPXMetaDataHandlerImp() + { + if( iEqPresetListener ) + { + iEqPresetListener->Stop(); + delete iEqPresetListener; + } + if( iPlaybackUtility ) + { + TRAP_IGNORE( iPlaybackUtility->RemoveObserverL( *this ) ); + iPlaybackUtility->Close(); + } + + delete iTrackTitle; + delete iArtist; + delete iAlbum; + delete iGenre; + } + +// --------------------------------------------------------------------------- +// Handle playback message. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::DoHandlePlaybackMessageL( + const CMPXMessage& aMessage ) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::DoHandlePlaybackMessageL(CMPXMessage)"); + + TMPXMessageId id( aMessage.ValueTObjectL( KMPXMessageGeneralId ) ); + if ( KMPXMessagePbMediaChanged == id ) + { + if ( aMessage.IsSupported( KMPXMessagePbMedia ) ) + { + CMPXMedia* media( aMessage.Value( KMPXMessagePbMedia ) ); + User::LeaveIfNull( media ); + iPlaybackPosition = 0; + DoHandleMediaL( *media, KErrNone ); + } + } + else if ( KMPXMessageGeneral == id ) + { + TInt type( aMessage.ValueTObjectL( KMPXMessageGeneralType )); + TInt data( aMessage.ValueTObjectL( KMPXMessageGeneralData )); + switch ( aMessage.ValueTObjectL( KMPXMessageGeneralEvent ) ) + { + case TMPXPlaybackMessage::EPropertyChanged: + { + TMPXPlaybackProperty property( static_cast( type ) ); + TInt error( KErrNone ); + DoHandlePropertyL( property, data, error ); + break; + } + case TMPXPlaybackMessage::EStateChanged: + { + MPX_DEBUG2( "CMPXMetaDataHandlerImp::HandlePlaybackMessageL - EStateChanged(%d)", type ); + + TMPXPlaybackState state = static_cast( type ); + DoHandleStateChangedL( state ); + break; + } + case TMPXPlaybackMessage::EMediaChanged: + { + MMPXSource* s = iPlaybackUtility->Source(); + if ( s ) + { + RArray attrs; + CleanupClosePushL(attrs); + (void) attrs.Append( KMPXMediaGeneralTitle ); + (void) attrs.Append( KMPXMediaGeneralDuration ); + (void) attrs.Append( KMPXMediaGeneralId ); + (void) attrs.Append( KMPXMediaMusicArtist ); + (void) attrs.Append( KMPXMediaMusicAlbum ); + (void) attrs.Append( KMPXMediaMusicGenre ); + MPX_DEBUG1( "CMPXMetaDataHandlerImp::HandlePlaybackMessageL Media changed, calling MediaL to refresh" ); + s->MediaL( attrs.Array(), *this, NULL ); + CleanupStack::PopAndDestroy( &attrs ); + } + break; + } + default: + { + break; + } + } + } + } + +// --------------------------------------------------------------------------- +// Handle playback property. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::DoHandlePropertyL( + TMPXPlaybackProperty aProperty, + TInt aValue, + TInt aError ) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::DoHandlePropertyL" ); + MPX_DEBUG4( "CMPXMetaDataHandlerImp::HandlePropertyL - Property(%d); Value(%d); Error(%d)", aProperty, aValue, aError ); + + TInt attr = 0; + TInt val = KAvrcpOff; + if ( KErrNone == aError ) + { + switch ( aProperty ) + { + case EPbPropertyPosition: + { + iPlaybackPosition = aValue / KMPXOneSecInMilliSecs; + // AVRCP 1.3 - inform remote device of the new position + // ( Todo: check that we don't call too often) + iPlayerEventsObserver->SetPlaybackPosition(aValue); // aPlaybackPosInMicroSeconds is converted to 32 bit value + break; + } + case EPbPropertyRepeatMode: + { + attr = KAvrcpRepeatMode; // Repeat mode status + // TMPlayerRepeatMode values are in the same order as AVRCP 1.3, + // but starting at 0 instead of 1. + val = (TInt) aValue + 1; + break; + } + case EPbPropertyRandomMode: + { + attr = KAvrcpShuffleMode; // Shuffle on/off status + TBool random = aValue; + if( random ) + { + val = KAvrcpAllTracksShuffle; + } + break; + } + default: + { + break; + } + } + if( attr ) + { + iPlayerApplicationSettingsObserver->SetAttributeL( attr, val ); + } + } + } + +// --------------------------------------------------------------------------- +// Handle media properties. +// Notes: The client is responsible for delete the object of aProperties. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::DoHandleMediaL( + const CMPXMedia& aMedia, TInt aError ) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::DoHandleMediaL" ); + + // Delete old title no matter there's error or not + delete iTrackTitle; + iTrackTitle = NULL; + delete iArtist; + iArtist = NULL; + delete iAlbum; + iAlbum = NULL; + delete iGenre; + iGenre = NULL; + TInt lastTrackNumber = -1; + if ( KErrNone == aError ) + { + // Keep track of the current track's title + iTrackTitle = aMedia.ValueText( KMPXMediaGeneralTitle ).AllocL(); + TInt *playingTime = aMedia.Value( KMPXMediaGeneralDuration ); + if(playingTime) + { + iPlayingTime = *playingTime; // In milliseconds. + } + MMPXSource* s = iPlaybackUtility->Source(); + if ( s ) + { + CMPXCollectionPlaylist* pl = s->PlaylistL(); + if( pl ) + { + lastTrackNumber = pl->Path().Index() + 1; // What if PlaylistItemCount is zero? + delete pl; + } + } + + iArtist = aMedia.ValueText( KMPXMediaMusicArtist ).AllocL(); + iAlbum = aMedia.ValueText( KMPXMediaMusicAlbum ).AllocL(); + iGenre = aMedia.ValueText( KMPXMediaMusicGenre ).AllocL(); + + TUid colId = aMedia.ValueTObjectL(KMPXMediaGeneralId); + + + MPX_DEBUG2( "CMPXMetaDataHandlerImp::DoHandleMediaL - Track title(%S)", iTrackTitle); + MPX_DEBUG4( "CMPXMetaDataHandlerImp::DoHandleMediaL - Artist(%S); Album(%S); Genre(%S)", iArtist, iAlbum, iGenre ); + MPX_DEBUG4( "CMPXMetaDataHandlerImp::DoHandleMediaL - Playing time(%d); Track number(%d); UID(%d)", iPlayingTime, lastTrackNumber, colId.iUid); + + if ( colId.iUid != iColId.iUid || lastTrackNumber != iTrackNumber ) + { + iColId = colId; + iTrackNumber = lastTrackNumber; + iPlayerEventsObserver->TrackChanged(iColId.iUid, iPlayingTime); + } + else + { + MPX_DEBUG1( "CMPXMetaDataHandlerImp::DoHandleMediaL DUPLICATE Trace Change Received" ); + } + } + } + +// --------------------------------------------------------------------------- +// Handle playback state changed. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::DoHandleStateChangedL( + TMPXPlaybackState aState ) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::DoHandleStateChangedL" ); + switch ( aState ) + { + case EPbStateStopped: + { + iPlayerState = aState; + iPlayerEventsObserver->PlaybackStatusChanged(MPlayerEventsObserver::EStopped); + break; + } + case EPbStatePlaying: + iPlayerState = aState; + // Start the time if needed, otherwise, update content if visible + iPlayerEventsObserver->PlaybackStatusChanged(MPlayerEventsObserver::EPlaying); + break; + case EPbStatePaused: + { + iPlayerState = aState; + // Start the time if needed, otherwise, update content if visible + iPlayerEventsObserver->PlaybackStatusChanged(MPlayerEventsObserver::EPaused); + break; + } + case EPbStateSeekingForward: + { + iPlayerEventsObserver->PlaybackStatusChanged(MPlayerEventsObserver::EFwdSeek); + break; + } + case EPbStateSeekingBackward: + { + iPlayerEventsObserver->PlaybackStatusChanged(MPlayerEventsObserver::ERevSeek); + break; + } + default: + { + // do nothing + break; + } + } + } + +// --------------------------------------------------------------------------- +// From MMPXPlaybackObserver +// Handle playback message. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::HandlePlaybackMessage( + CMPXMessage* aMessage, TInt aError ) + { + if ( aError == KErrNone && aMessage ) + { + TRAP_IGNORE( DoHandlePlaybackMessageL( *aMessage ) ); + } + } + +// --------------------------------------------------------------------------- +// From MMPXPlaybackCallback +// Handle playback property. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::HandlePropertyL( + TMPXPlaybackProperty aProperty, + TInt aValue, + TInt aError ) + { + TRAP_IGNORE( DoHandlePropertyL( aProperty, aValue, aError ) ); + } + +// --------------------------------------------------------------------------- +// From MMPXPlaybackCallback +// Handle sub player names. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::HandleSubPlayerNamesL( + TUid /* aPlayer */, + const MDesCArray* /* aSubPlayers */, + TBool /* aComplete */, + TInt /* aError */ ) + { + MPX_FUNC( "CMPXMediaKeyHandlerImp::HandleSubPlayerNamesL" ); + } + +// --------------------------------------------------------------------------- +// From MMPXPlaybackCallback +// Handle media properties. +// Notes: The client is responsible for delete the object of aMedia. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::HandleMediaL( + const CMPXMedia& aMedia, TInt aError ) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::HandleMediaL" ); + TRAP_IGNORE( DoHandleMediaL( aMedia, aError ) ); + } + +// --------------------------------------------------------------------------- +// From MMPXCollectionPlaylistObserver +// Handle collection playlist change. +// Notes: aError values: +// KErrNotFound - Playlist is updated, current item removed +// KErrNone - Playlist is updated, current item is valid +// KErrEof - Playlist is updated, current item removed and reached to the end of playlist +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::HandleCollectionPlaylistChange(TInt aError) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::HandleCollectionPlaylistChange" ); + + if( aError ) + { + // Update the media item. + MMPXSource* s = iPlaybackUtility->Source(); + if ( s ) + { + RArray attrs; + // Failing the next operations here is not fatal. + (void) attrs.Append( KMPXMediaGeneralTitle ); + (void) attrs.Append( KMPXMediaGeneralDuration ); + (void) attrs.Append( KMPXMediaGeneralId ); + (void) attrs.Append( KMPXMediaMusicArtist ); + (void) attrs.Append( KMPXMediaMusicAlbum ); + (void) attrs.Append( KMPXMediaMusicGenre ); + // Ignore the leave. If this occurs, we just don't get + // an updated media information for time being. + TRAP_IGNORE(s->MediaL( attrs.Array(), *this, NULL )); + attrs.Close(); + } + } + } + +// --------------------------------------------------------------------------- +// From MPlayerApplicationSettingsNotify +// This is called when the controller has changed a setting +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::MpasnSetPlayerApplicationValueL( + const RArray& aAttributeID, const RArray& aAttributeValue ) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::MpasnSetPlayerApplicationValueL" ); + + for( TInt i = 0; i < aAttributeID.Count(); i++ ) + { + switch( aAttributeID[ i ] ) + { + case KAvrcpEqualizerMode: + { + TInt equalizer = aAttributeValue[ i ] == KAvrcpOff ? KEqualizerPresetNone : iLastEqPresetId; + iEqPresetListener->ChangePresetL(equalizer); +// iLastEqPresetId = equalizer; + break; + } + case KAvrcpRepeatMode: + { + // TMPlayerRepeatMode values are in the same order + // as AVRCP 1.3, but starting at 0 instead of 1. + TInt repeat = aAttributeValue[ i ] - 1; + iPlaybackUtility->SetL(EPbPropertyRepeatMode, repeat); + break; + } + case KAvrcpShuffleMode: + { + TBool random = aAttributeValue[ i ] == KAvrcpOff ? EFalse : ETrue; + iPlaybackUtility->SetL(EPbPropertyRandomMode, random); + break; + } + case KAvrcpBassBoostMode: + { + TBool boost = aAttributeValue[ i ] == KAvrcpOff ? EFalse : ETrue; +// iSettingModel->SetBassBoostL( boost ); + break; + } + case KAvrcpStereoWideningMode: + { + TBool widening = aAttributeValue[ i ] == KAvrcpOff ? EFalse : ETrue; +// iSettingModel->SetStereoWideningL( widening ); + break; + } + default: + { + // Leaving results in sending an error back to the controller. + User::Leave( KErrNotSupported ); + break; + } + } + } + } + +// ----------------------------------------------------------------------------- +// From MRemConMediaInformationTargetObserver +// For each element in aAttributeList the client should respond by calling +// CRemConMediaInformationTarget::AttributeValue(). After all attributes have +// been supplied the client should call CRemConMediaInformationTarget::Completed(). +// @param aAttributeList A list of TAttributeID requested by the controller +// ----------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::MrcmitoGetCurrentlyPlayingMetadata( + TMediaAttributeIter& aAttributeIter ) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::MrcmitoGetCurrentlyPlayingMetadata" ); + const TInt KMaxMediaAttrLen = 50; // Replace with suitable value + TBuf8 attrBuf; + TMediaAttributeId attrId; + aAttributeIter.Start(); + while( aAttributeIter.Next( attrId ) ) + { + TInt err = KErrNotFound; + HBufC* detail = NULL; + TInt64 val = 0; + switch( attrId ) + { + case ETitleOfMedia: + { + detail = iTrackTitle; + break; + } + case ENameOfArtist: + { + detail = iArtist; + break; + } + case ENameOfAlbum: + { + detail = iAlbum; + break; + } + case ETrackNumber: + { + val = iTrackNumber; + break; + } + case ENumberOfTracks: + { + MMPXSource* s = iPlaybackUtility->Source(); + if ( s ) + { + CMPXCollectionPlaylist* pl = NULL; + TRAP(err, pl = s->PlaylistL()); + if( !err && pl ) + { + val = pl->Count(); // What if PlaylistItemCount is zero? + } + delete pl; + } + break; + } + case EGenre: + { + detail = iGenre; + break; + } + case EPlayingTime: + { + // No need to check for boundaries, assuming the file length < 10^15 seconds + val = iPlayingTime; // If playing time does not exist, what then? + break; + } + default: + break; + } + if( val ) + { + // 'val' and 'detail' are mutually exclusive. We still set detail to + // null, to avoid the possiblility that "delete detail" will delete + // a member variable if NewL fails. + detail = NULL; + TRAP_IGNORE( detail = HBufC::NewL( KMaxMediaAttrLen ) ); + if( detail ) + { + detail->Des().NumUC( val ); + } + } + if( detail ) + { + if( CnvUtfConverter::ConvertFromUnicodeToUtf8( attrBuf, *detail ) ) + { + attrBuf.Zero(); // Check if this generates the right response + } + } + if( val ) + { + delete detail; + detail = NULL; + } + iMediaInfoTarget->AttributeValue( attrId, attrBuf ); + } + iMediaInfoTarget->Completed(); + } + + + +// --------------------------------------------------------------------------- +// From class MRemConGroupNavigationTargetObserver. +// A 'Next Group' command has been received. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::MrcgntoNextGroup(TRemConCoreApiButtonAction aButtonAct) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::MrcgntoNextGroup" ); + (void) aButtonAct; + // Not supported yet, return an error. + TRequestStatus* status = NULL; + iGroupNavigationTarget->NextGroupResponse( status, KErrAvrcpMetadataInvalidParameter ); + } + +// --------------------------------------------------------------------------- +// From class MRemConGroupNavigationTargetObserver. +// A 'Previous Group' command has been received. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::MrcgntoPreviousGroup(TRemConCoreApiButtonAction aButtonAct) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::MrcgntoPreviousGroup" ); + (void) aButtonAct; + // Not supported yet, return an error. + TRequestStatus* status = NULL; + iGroupNavigationTarget->PreviousGroupResponse( status, KErrAvrcpMetadataInvalidParameter ); + } + + +// --------------------------------------------------------------------------- +// From class MEqualizerPresetChangeListenerObserver +// Callback for receiving changes in the equalizer preset settings. +// --------------------------------------------------------------------------- +// +void CMPXMetaDataHandlerImp::EqualizerPresetChangedL(TInt aNewPreset) + { + MPX_FUNC( "CMPXMetaDataHandlerImp::EqualizerPresetChanged" ); + TInt val = KAvrcpOff; + if( aNewPreset != KEqualizerPresetNone) + { + iLastEqPresetId = aNewPreset; // Store last used preset + val = KAvrcpOn; + } + iPlayerApplicationSettingsObserver->SetAttributeL( KAvrcpEqualizerMode, val ); + } + + +// --------------------------------------------------------------------------- +// C++ default constructor +// --------------------------------------------------------------------------- +// +CEqualizerPresetChangeListener::CEqualizerPresetChangeListener(MEqualizerPresetChangeListenerObserver& aObserver) +: CActive(EPriorityStandard), + iObserver(aObserver) + { + MPX_FUNC( "CEqualizerPresetChangeListener::CEqualizerPresetChangeListener" ); + } + +// --------------------------------------------------------------------------- +// Symbian 2nd-phase constructor +// --------------------------------------------------------------------------- +// +void CEqualizerPresetChangeListener::ConstructL() + { + MPX_FUNC( "CEqualizerPresetChangeListener::ConstructL" ); + CActiveScheduler::Add( this ); + iRepository = CRepository::NewL(KCRUidMusicPlayerSettings); + } + +// --------------------------------------------------------------------------- +// NewL +// --------------------------------------------------------------------------- +// +CEqualizerPresetChangeListener* CEqualizerPresetChangeListener::NewL(MEqualizerPresetChangeListenerObserver& aObserver) + { + MPX_FUNC( "CEqualizerPresetChangeListener::NewL" ); + CEqualizerPresetChangeListener* self = new(ELeave)CEqualizerPresetChangeListener( aObserver ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CEqualizerPresetChangeListener::~CEqualizerPresetChangeListener() + { + MPX_FUNC( "CEqualizerPresetChangeListener::~CEqualizerPresetChangeListener" ); + Stop(); + delete iRepository; + } + +// --------------------------------------------------------------------------- +// Get the current equalizer preset ID +// --------------------------------------------------------------------------- +// +TInt CEqualizerPresetChangeListener::GetCurrentPresetL() + { + MPX_FUNC( "CEqualizerPresetChangeListener::GetCurrentPresetL" ); + TInt preset; + User::LeaveIfError(iRepository->Get(KMPlayerEqPresetId, preset)); + return preset; + } + +// --------------------------------------------------------------------------- +// Set the equalizer preset +// --------------------------------------------------------------------------- +// +void CEqualizerPresetChangeListener::ChangePresetL(TInt aNewPreset) + { + MPX_FUNC( "CEqualizerPresetChangeListener::ChangePresetL" ); + User::LeaveIfError(iRepository->Set(KMPlayerEqPresetId, aNewPreset)); + } + +// --------------------------------------------------------------------------- +// Start listening to equalizer preset changes +// --------------------------------------------------------------------------- +// +void CEqualizerPresetChangeListener::StartL() + { + MPX_FUNC( "CEqualizerPresetChangeListener::StartL" ); + User::LeaveIfError(iRepository->NotifyRequest(KMPlayerEqPresetId, iStatus)); + SetActive(); + } + +// --------------------------------------------------------------------------- +// Stop listening to equalizer preset changes +// --------------------------------------------------------------------------- +// +void CEqualizerPresetChangeListener::Stop() + { + MPX_FUNC( "CEqualizerPresetChangeListener::Stop" ); + Cancel(); + } + +// --------------------------------------------------------------------------- +// From class CActive. +// Called by the active scheduler when the request has been completed. +// --------------------------------------------------------------------------- +// +void CEqualizerPresetChangeListener::RunL() + { + MPX_FUNC( "CEqualizerPresetChangeListener::RunL" ); + iObserver.EqualizerPresetChangedL(GetCurrentPresetL()); + StartL(); + } + +// --------------------------------------------------------------------------- +// From class CActive. +// Called by the active scheduler when the request has been cancelled. +// --------------------------------------------------------------------------- +// +void CEqualizerPresetChangeListener::DoCancel() + { + MPX_FUNC( "CEqualizerPresetChangeListener::DoCancel" ); + iRepository->NotifyCancel(KMPlayerEqPresetId); + delete iRepository; + iRepository = NULL; + } + +// --------------------------------------------------------------------------- +// From class CActive. +// Called by the active scheduler when an error in RunL has occurred. +// --------------------------------------------------------------------------- +// +TInt CEqualizerPresetChangeListener::RunError( TInt aError ) + { + MPX_FUNC( "CEqualizerPresetChangeListener::RunError" ); + (void) aError; + // In case of an exception in RunL, re-subscribe to Central Repository, + // and ignore the return value. If it fails we just won't be sending + // equalizer updates anymore. + if( !iRepository->NotifyRequest( KMPlayerEqPresetId, iStatus ) ) + { + SetActive(); + } + return KErrNone; + }