diff -r 1ddbe54d0645 -r ccb4f6b3db21 accessoryservices/autoaudioasy/src/cautoaudioasyservice.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accessoryservices/autoaudioasy/src/cautoaudioasyservice.cpp Tue Aug 31 16:29:05 2010 +0300 @@ -0,0 +1,273 @@ +/* +* Copyright (c) 2010 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 handles connect and disconnect to AccFw. +* +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "cautoaudioasyservice.h" +#include "cautoaudioasypropertyobserver.h" +#include "acc_debug.h" + +#define SET_STATE(state) (iState=state) + +// ---------------------------------------------------------------------------------- +// CAutoAudioAsyService::CAutoAudioAsyService() +// ---------------------------------------------------------------------------------- +CAutoAudioAsyService::CAutoAudioAsyService () + : CActive ( EPriorityStandard ) + { + CActiveScheduler::Add ( this ); + } + +// ---------------------------------------------------------------------------------- +// CAutoAudioAsyService::NewL () +// ---------------------------------------------------------------------------------- +CAutoAudioAsyService* CAutoAudioAsyService::NewL () + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::NewL" ); + CAutoAudioAsyService* self = new ( ELeave ) CAutoAudioAsyService (); + CleanupStack::PushL ( self ); + self->ConstructL (); + CleanupStack::Pop ( self ); + return self; + } + +// ---------------------------------------------------------------------------------- +// CAutoAudioAsyService::ConstructL () +// ---------------------------------------------------------------------------------- +void CAutoAudioAsyService::ConstructL () + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::ConstructL" ); + User::LeaveIfError ( iAccessoryServer.Connect () ); + User::LeaveIfError ( iAccessoryControl.CreateSubSession ( iAccessoryServer ) ); + SET_STATE ( EServiceStateIdle ); + } + +// ---------------------------------------------------------------------------------- +// CAutoAudioAsyService::~CAutoAudioAsyService() +// ---------------------------------------------------------------------------------- +CAutoAudioAsyService::~CAutoAudioAsyService () + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::~CAutoAudioAsyService" ); + Cancel (); + + delete iPropertyObserver; + iAccessoryControl.CloseSubSession (); + iAccessoryServer.Close (); + + FreeResources (); + } + +void CAutoAudioAsyService::StartL () + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::StartL" ); + iPropertyObserver = CAutoAudioAsyPropertyObserver::NewL ( KPSUidAccessoryServices, KPSAutoKeyRTPStreamingConnectionStatus, *this ); + } + +// ---------------------------------------------------------------------------------- +// CAutoAudioAsyService::PropertyChange () +// Defined in MAutoAudioAsyPropertyListener interface. +// Receives notifications about RTP Streaming channel property changes. Property changes occur +// when accessory is connected or disconnected or headunit attached or detached +// ---------------------------------------------------------------------------------- +void CAutoAudioAsyService::PropertyChange ( RProperty& aProperty, TUid aUid, TUint aKey, TInt aStatus ) + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::PropertyChange" ); + + TInt propValue; + TInt status = aProperty.Get ( propValue ); + COM_TRACE_1 ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::PropertyChange -- request property value %d", propValue ); + + if ( aUid == KPSUidAccessoryServices && aKey == KPSAutoKeyRTPStreamingConnectionStatus ) + { + // Check if audio accessory has been connected + if ( ( status == KErrNone ) && ( aStatus == KErrNone ) ) + { + if ( propValue == EAudioConnectionStatusUnidirectional ) // Current release supports only UniDirectional, so other key values ignored. + { + TInt err; + switch ( iState ) + { + case EServiceStateIdle: + TRAP ( err, ConnectAccessoryL () ); + if ( err != KErrNone ) + { + COM_TRACE_1 ("[AccFW:AutoAudioAsy] ConnectAccessoryL error %d", err ); + FreeResources (); // switch to EServiceStateIdle + } + break; + + case EServiceStateConnecting: + case EServiceStateConnected: + // Nothing to do + break; + } + return; + } + } + + // Otherwise assume that it's disconnected + AccessoryDisconnected (); + } + } + +// ---------------------------------------------------------------------------------- +// CAutoAudioAsyService::AccessoryDisconnected () +// Called when a disconnect notification is received +// ---------------------------------------------------------------------------------- +void CAutoAudioAsyService::AccessoryDisconnected () + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::AccessoryDisconnected" ); + TRequestStatus status; + switch ( iState ) + { + case EServiceStateConnected: + iAccessoryControl.DisconnectAccessory ( status, iGenericId->GenericID () ); + User::WaitForRequest ( status ); + FreeResources (); // sets state to EServiceStateIdle + break; + + case EServiceStateConnecting: + Cancel (); + break; + + default: + // nothing to do in this case + break; + } + } + +// ---------------------------------------------------------------------------------- +// CAutoAudioAsyService::ConnectAccessoryL () +// Notifies the accessory server and switches to EServiceStateConnecting state. +// ---------------------------------------------------------------------------------- +void CAutoAudioAsyService::ConnectAccessoryL () + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::ConnectAccessoryL" ); + + RArray nameValueArray; + CleanupClosePushL ( nameValueArray ); + + // Set GenericID header + COM_TRACE_ ( "[AccFW:AutoAudioAsy] Set generic header" ); + iGenericIDHeader.iAccessoryDeviceType = KDTCarKit; + iGenericIDHeader.iPhysicalConnection = KPCUSB; + iGenericIDHeader.iApplicationProtocol = 0x0; + iGenericIDHeader.iCapabilitiesSubblocks = KSBAudioSubblock; + iGenericIDHeader.iHWDeviceID = 0x0; + iGenericIDHeader.iHWModelID = KNullDesC; + + iGenericId = CAccConGenericID::NewL (); + + COM_TRACE_ ( "[AccFW:AutoAudioAsy] Set capabilities" ); + + // Set "Audio Output Type" capability + COM_TRACE_ ( "[AccFW:AutoAudioAsy] KAccAudioOutputType " ); + nameValueArray.AppendL ( TAccPolNameValueRecord ( KAccAudioOutputType, + EAccAudioOutPutTypePublic, EAPVInt, EAPVPolicy ) ); + + // Set "Audio stereo" capability + COM_TRACE_ ( "[AccFW:AutoAudioAsy] KAccStereoAudio " ); + nameValueArray.AppendL ( TAccPolNameValueRecord ( KAccStereoAudio ) ); + + // Set "Integrated audio output" + COM_TRACE_ ( "[AccFW:AutoAudioAsy] KAccIntegratedAudioOutput " ); + nameValueArray.AppendL ( TAccPolNameValueRecord ( KAccIntegratedAudioOutput ) ); + + // Set "RTP streaming" + COM_TRACE_ ( "[AccFW:AutoAudioAsy] KAccRTPStreaming " ); + nameValueArray.AppendL ( TAccPolNameValueRecord ( KAccRTPStreaming ) ); + + // Make generic id + CAccConfigFileParser* accConfigFileParser = CAccConfigFileParser::NewL ( KNullDesC ); + CleanupStack::PushL ( accConfigFileParser ); + accConfigFileParser->ParseGenericIDL ( iGenericId, iGenericIDHeader, nameValueArray ); + + // Connect accessory + COM_TRACE_ ( "[AccFW:AutoAudioAsy] Connecting accessory..." ); + iAccessoryControl.ConnectAccessory ( iStatus, iGenericId, EFalse ); + SET_STATE ( EServiceStateConnecting ); + SetActive (); + + CleanupStack::PopAndDestroy ( accConfigFileParser ); + CleanupStack::PopAndDestroy ( &nameValueArray ); + } + +// ---------------------------------------------------------------------------------- +// CActive methods +// ---------------------------------------------------------------------------------- +void CAutoAudioAsyService::DoCancel () + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::DoCancel" ); + iAccessoryControl.CancelConnectAccessory (); + FreeResources (); + } + +TInt CAutoAudioAsyService::RunError ( TInt /*aError*/ ) + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::RunError" ); + return KErrNone; + } + +void CAutoAudioAsyService::RunL () + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::RunL" ); + TInt retVal ( iStatus.Int () ); + COM_TRACE_1 ( "[AccFW:AutoAudioAsy] Connected with return value %d", retVal ); + + if ( KErrNone == retVal ) + { + switch ( iState ) + { + case EServiceStateConnecting: + SET_STATE ( EServiceStateConnected ); + break; + + case EServiceStateIdle: + case EServiceStateConnected: + default: + COM_TRACE_ ( "State machine broken" ); + break; + } + } + else + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] Accessory Server failed to accept connection, freeing up resources" ); + FreeResources (); + } + } + +// ---------------------------------------------------------------------------------- +// Frees resources and set state to EServiceStateIdle +// ---------------------------------------------------------------------------------- +void CAutoAudioAsyService::FreeResources () + { + COM_TRACE_ ( "[AccFW:AutoAudioAsy] CAutoAudioAsyService::FreeResources" ); + + if ( iState != EServiceStateIdle ) + { + SET_STATE ( EServiceStateIdle ); + } + + delete iGenericId; + iGenericId = NULL; + }