diff -r 22de2e391156 -r 20ac952a623c remotecontrol/avrcp/playerinformation/src/playerinformation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/remotecontrol/avrcp/playerinformation/src/playerinformation.cpp Wed Oct 13 16:20:29 2010 +0300 @@ -0,0 +1,293 @@ +// Copyright (c) 2008-2009 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: +// + +/** + @file + @publishedAll + @released +*/ + +#include +#include +#include +#include + +#include "playerapplicationsetting.h" +#include "eventsmask.h" +#include "playerinformation.h" + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, LOG_COMPONENT_AVRCP_PLAYER_INFO); +#endif + +EXPORT_C CPlayerInfoTarget* CPlayerInfoTarget::NewL(CRemConInterfaceSelector& aInterfaceSelector, + MPlayerCapabilitiesObserver*& aPlayerCapabilitiesObserver, + MPlayerApplicationSettingsObserver*& aPlayerApplicationSettingsObserver, + MPlayerEventsObserver*& aPlayerEventsObserver, + MPlayerApplicationSettingsNotify& aApplicationSettingNotifier ) + { + LOG_STATIC_FUNC + + CPlayerInfoTarget* self = new(ELeave) CPlayerInfoTarget(aInterfaceSelector, aApplicationSettingNotifier); + CleanupStack::PushL(self); + self->ConstructL( aPlayerCapabilitiesObserver, aPlayerApplicationSettingsObserver, aPlayerEventsObserver ); + CleanupStack::Pop(self); + return self; + } + +/** +Constructs this interface. +@param aInterfaceSelector An interface selector for use with this interface. +@internalComponent +@released +*/ +CPlayerInfoTarget::CPlayerInfoTarget(CRemConInterfaceSelector& aInterfaceSelector, MPlayerApplicationSettingsNotify& aApplicationSettingNotifier) +: CRemConInterfaceBase(TUid::Uid(KRemConPlayerInformationUid), + KMaxLengthPlayerInformationMsg, + aInterfaceSelector, + ERemConClientTypeTarget), + iApplicationSettingNotifier(aApplicationSettingNotifier), + iPlaybackStatusUpdatePending(EFalse) + { + } + + +void CPlayerInfoTarget::ConstructL(MPlayerCapabilitiesObserver*& aPlayerCapabilitiesObserver, + MPlayerApplicationSettingsObserver*& aPlayerApplicationSettingsObserver, + MPlayerEventsObserver*& aPlayerEventsObserver ) + { + // reserve two AV/C frames, for this reasoning: + // GetCapabilities (PDU 0x10) can generate a response + // which is (255 * 3 bytes) + 2 bytes = 767 total and + // will fit into two AVC frames. Other PDUs generate + // less than this, except for PDUs 0x15 and 0x16 which + // use their own buffer pre-allocated by calling Size() + iOutBuf.CreateL(KAVCFrameMaxLength * 2); + + BaseConstructL(); + + aPlayerCapabilitiesObserver = this; + aPlayerApplicationSettingsObserver = this; + aPlayerEventsObserver = this; + + // default values for event notifiers + iPlayBackStatus = EStopped; + + // If no track currently selected + iTrackId = KNoTrackSelected; + + iLengthInMilliseconds = 0; + iTrackPosition = EStart; + + // If no track currently selected, then return KPlaybackPositionUnknown + iPlaybackPositionInMilliseconds = KPlaybackPositionUnknown; + iLastNotifiedPlaybackPositionInMilliseconds = KPlaybackPositionUnknown; + + // The time interval used for playback position notification + iPlayBackIntervalInMilliseconds = 0; + + // Try to detect battery status from hardware P&S properties + iBatteryStatus = DetectBatteryStatus(); + + // The Bluetooth SIG vendor id must always be present + // See AVRCP 1.3 Specification, section 5.5.1, table 5.4 + iCompanyIdList.AppendL(KBluetoothSIGVendorId); + + // AVRCP 1.3 specification, Appendix H says that PlaybackStatusChanged + // and TrackChanged event notification support is mandatory, so add these + iSupportedNotificationEventList = new (ELeave) TEventsMask(); + iSupportedNotificationEventList->Append(ERegisterNotificationPlaybackStatusChanged); + iSupportedNotificationEventList->Append(ERegisterNotificationTrackChanged); + } + +EXPORT_C CPlayerInfoTarget::~CPlayerInfoTarget() + { + iPendingNotificationEventList.Close(); + iCompanyIdList.Close(); + iOutBuf.Close(); + + // Free up all the settings memory + THashMapIter iter(iPlayerApplicationSettings); + CPlayerApplicationSettings* const* setting = iter.NextValue(); + while ( setting != NULL ) + { + delete *setting; + setting = iter.NextValue(); + } + + // Now close the hash table itself + iPlayerApplicationSettings.Close(); + delete iSupportedNotificationEventList; + } + + +TAny* CPlayerInfoTarget::GetInterfaceIf(TUid aUid) + { + TAny* ret = NULL; + if ( aUid == TUid::Uid(KRemConInterfaceIf2) ) + { + ret = reinterpret_cast( + static_cast(this) + ); + } + + return ret; + } + +// from MRemConInterfaceIf +void CPlayerInfoTarget::MrcibNewMessage(TUint aOperationId, const TDesC8& aData, TRemConMessageSubType aMsgSubType) + { + LOG(_L("CPlayerInfoTarget::MrcibNewMessage")); + LOG1(_L("\taOperationId = 0x%02x"), aOperationId); + LOG1(_L("\taData.Length = %d"), aData.Length()); + LOG1(_L("\taMsgSubType = 0x%02x"), aMsgSubType); + + TMetadataTransferPDU currentOp = RAvrcpIPC::GetPDUIdFromIPCOperationId(aOperationId); + + switch (currentOp) + { + case EGetCapabilities: + { + /* process this in playercapabilities */ + ProcessGetCapabilities( aData ); + break; + } + case EListPlayerApplicationSettingAttributes: + { + /* respond with Player Application Attributes*/ + ProcessListPlayerApplicationAttributes( aOperationId ); + break; + } + case EGetPlayerApplicationSettingAttributeText: + { + /* respond with Player Application Attribute Text*/ + ProcessGetPlayerApplicationAttributeText( aData, aOperationId ); + break; + } + case EListPlayerApplicationSettingValues: + { + /* respond with Player Application Values*/ + ProcessListPlayerApplicationValues( aData, aOperationId ); + break; + } + case EGetPlayerApplicationSettingValueText: + { + /* respond with Application Value Text*/ + ProcessGetPlayerApplicationValueText( aData, aOperationId ); + break; + } + case EGetCurrentPlayerApplicationSettingValue: + { + /* respond with Current Player Application Value*/ + ProcessGetCurrentPlayerApplicationValue( aData, aOperationId ); + break; + } + case ESetPlayerApplicationSettingValue: + { + /* Set Player Application Value*/ + ProcessSetPlayerApplicationValue( aData, aOperationId ); + break; + } + case EGetPlayStatus: + { + // process in playerevents + ProcessGetPlayStatus(); + break; + } + case ERegisterNotification: + { + // obtain eventId from aOperationId + TRegisterNotificationEvent eventId = RAvrcpIPC::GetEventIdFromIPCOperationId(aOperationId); + + // register for Notifications + if (aMsgSubType == ERemConNotifyCommandAwaitingInterim) + { + ProcessGetStatusAndBeginObserving(aOperationId, eventId, aData); + } + else if (aMsgSubType == ERemConNotifyCommandAwaitingChanged) + { + ProcessGetStatus(aOperationId, eventId); + } + break; + } + case EGetPlayStatusUpdate: + { + // process in playerevents + ProcessGetPlayStatusUpdate(aData); + break; + } + default: + break; + } + + } + +MPlayerEventsObserver::TTargetBatteryStatus CPlayerInfoTarget::DetectBatteryStatus() + { + MPlayerEventsObserver::TTargetBatteryStatus status = ECritical; + TInt err = KErrNone; + TInt batteryStatus = EBatteryStatusUnknown; + TInt chargingStatus = EChargingStatusNotConnected; + err = RProperty::Get(KPSUidHWRMPowerState,KHWRMBatteryStatus,batteryStatus); + if (!err) + { + err = RProperty::Get(KPSUidHWRMPowerState,KHWRMChargingStatus,chargingStatus); + } + + switch (batteryStatus) + { + // Normal or Charging + case EBatteryStatusOk: + { + if (chargingStatus == EChargingStatusCharging || + chargingStatus == EChargingStatusAlmostComplete || + chargingStatus == EChargingStatusChargingContinued) + { + iBatteryStatus = EExternal; + } + else + { + if (chargingStatus == EChargingStatusChargingComplete) + { + iBatteryStatus = EFullCharge; + } + else + { + iBatteryStatus = ENormal; + } + } + } + break; + // Warning + case EBatteryStatusLow: + { + iBatteryStatus = EWarning; + } + break; + // Critical + case EBatteryStatusEmpty: + { + iBatteryStatus = ECritical; + } + break; + // Unknown state, set as ECritical + case EBatteryStatusUnknown: + { + iBatteryStatus = ECritical; + } + break; + } + return status; + }