diff -r 613943a21004 -r 9386f31cc85b bluetoothengine/btserviceutil/src/btdevrepositoryimpl.cpp --- a/bluetoothengine/btserviceutil/src/btdevrepositoryimpl.cpp Tue Aug 31 15:25:10 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,470 +0,0 @@ -/* -* 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: respository of remote Bluetooth devices. -* -*/ - -#include "btdevrepositoryimpl.h" -#include -#include -#include -#include "btserviceutilconsts.h" - -// --------------------------------------------------------------------------- -// Tells if two CBTDevice instances are for the same remote device -// --------------------------------------------------------------------------- -// -TBool CompareDeviceByAddress( const CBTDevice& aDevA, const CBTDevice& aDevB ) - { - return aDevA.BDAddr() == aDevB.BDAddr(); - } - -// --------------------------------------------------------------------------- -// Tells if these two instances are for the same remote device -// --------------------------------------------------------------------------- -// -TBool MatchDeviceAddress(const TBTDevAddr* aAddr, const CBTDevice& aDev) - { - return *aAddr == aDev.BDAddr(); - } - -// --------------------------------------------------------------------------- -// Tells if these two instances are for the same remote device -// --------------------------------------------------------------------------- -// -TBool MatchDeviceAddress(const TBTDevAddr* aAddr, const CBtDevExtension& aDev) - { - return *aAddr == aDev.Device().BDAddr(); - } - -// ======== MEMBER FUNCTIONS ======== - -// --------------------------------------------------------------------------- -// C++ default constructor -// --------------------------------------------------------------------------- -// -CBtDevRepositoryImpl::CBtDevRepositoryImpl() - { - } - -// --------------------------------------------------------------------------- -// Symbian 2nd-phase constructor -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::ConstructL() - { - // connect to registry - User::LeaveIfError( iBTRegServ.Connect() ); - User::LeaveIfError( iBTRegistry.Open( iBTRegServ ) ); - iRegistryActive = CBtSimpleActive::NewL( - *this, BtServiceUtil::ECreateRemoteDeviceViewRequest ); - // Start to get the list of devices from registry. - CreateRemoteDeviceView(); - - User::LeaveIfError( iBtRegistryKey.Attach( - KPropertyUidBluetoothCategory, - KPropertyKeyBluetoothGetRegistryTableChange ) ); - - iRegistryKeyActive = CBtSimpleActive::NewL( *this, BtServiceUtil::ERegistryPubSubWatcher ); - iBtRegistryKey.Subscribe( iRegistryKeyActive->RequestStatus() ); - iRegistryKeyActive->GoActive(); - iBtengConn = CBTEngConnMan::NewL( this ); - } - -// --------------------------------------------------------------------------- -// NewL -// --------------------------------------------------------------------------- -// -CBtDevRepositoryImpl* CBtDevRepositoryImpl::NewL() - { - CBtDevRepositoryImpl* self = NULL; - self = new (ELeave) CBtDevRepositoryImpl(); - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - return self; - } - -// --------------------------------------------------------------------------- -// Destructor -// --------------------------------------------------------------------------- -// -CBtDevRepositoryImpl::~CBtDevRepositoryImpl() - { - iObservers.Close(); - delete iBtengConn; - delete iRegistryActive; - delete iRegRespRemoteDevices; - iDevices.ResetAndDestroy(); - iDevices.Close(); - iBTRegistry.Close(); - iBTRegServ.Close(); - delete iRegistryKeyActive; - iBtRegistryKey.Close(); - } - -// --------------------------------------------------------------------------- -// AddObserverL -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::AddObserverL( MBtDevRepositoryObserver* aObserver ) - { - // Do not allow null pointer. - if ( aObserver ) - { - iObservers.AppendL( aObserver ); - } - } - -// --------------------------------------------------------------------------- -// RemoveObserver -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::RemoveObserver( MBtDevRepositoryObserver* aObserver ) - { - TInt i = iObservers.Find( aObserver ); - if ( i >= 0 ) - { - iObservers.Remove( i ); - } - } - -// --------------------------------------------------------------------------- -// IsInitialized -// --------------------------------------------------------------------------- -// -TBool CBtDevRepositoryImpl::IsInitialized() const - { - return iInitialized; - } - -// --------------------------------------------------------------------------- -// AllDevices -// --------------------------------------------------------------------------- -// -const RDevExtensionArray& CBtDevRepositoryImpl::AllDevices() const - { - return iDevices; - } - -// --------------------------------------------------------------------------- -// Device -// --------------------------------------------------------------------------- -// -const CBtDevExtension* CBtDevRepositoryImpl::Device( - const TBTDevAddr& aAddr ) const - { - TInt pos = iDevices.Find( aAddr, MatchDeviceAddress); - if ( pos > -1 ) - { - return iDevices[pos]; - } - return NULL; - } - -// --------------------------------------------------------------------------- -// ReInitialize -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::ReInitialize() - { - iInitialized = EFalse; - if ( !iRegistryActive->IsActive() ) - { - CreateRemoteDeviceView(); - } - else - { - // This counter-increasing - // will force to re-create a registry view later. - ++iNotHandledRegEventCounter; - } - } - -// --------------------------------------------------------------------------- -// From class MBtSimpleActiveObserver. -// Checks if there is an authentication result. -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::RequestCompletedL( CBtSimpleActive* aActive, TInt aStatus ) - { - if ( aActive->RequestId() == BtServiceUtil::ECreateRemoteDeviceViewRequest ) - { - HandleCreateRemoteDeviceViewCompletedL( aStatus ); - } - else if ( aActive->RequestId() == BtServiceUtil::EGetRemoteDevicesRequest ) - { - HandleGetRemoteDevicesCompletedL( aStatus ); - } - else if ( aActive->RequestId() == BtServiceUtil::ERegistryPubSubWatcher ) - { - TInt myChangedTable; - iBtRegistryKey.Subscribe( aActive->RequestStatus() ); - aActive->GoActive(); - TInt err = iBtRegistryKey.Get( myChangedTable ); - if( !err && myChangedTable == KRegistryChangeRemoteTable ) - { - if ( !iRegistryActive->IsActive() ) - { - CreateRemoteDeviceView(); - } - else - { - iNotHandledRegEventCounter++; - } - } - } - } - -// --------------------------------------------------------------------------- -// From class MBtSimpleActiveObserver. -// Checks if there is an authentication result. -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::CancelRequest( TInt aRequestId ) - { - if ( aRequestId == BtServiceUtil::ECreateRemoteDeviceViewRequest ) - { - iBTRegistry.CancelRequest(iRegistryActive->RequestStatus()); - } - else if ( aRequestId == BtServiceUtil::EGetRemoteDevicesRequest ) - { - iRegRespRemoteDevices->Cancel(); - } - else if ( aRequestId == BtServiceUtil::ERegistryPubSubWatcher ) - { - iBtRegistryKey.Cancel(); - } - } - -// --------------------------------------------------------------------------- -// From class MBtSimpleActiveObserver. -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::HandleError( CBtSimpleActive* aActive, TInt aError ) - { - (void) aError; - if ( aActive->RequestId() == BtServiceUtil::ECreateRemoteDeviceViewRequest || - aActive->RequestId() == BtServiceUtil::EGetRemoteDevicesRequest ) - {// leave happened in registry operation, delete registry response: - delete iRegRespRemoteDevices; - iRegRespRemoteDevices = NULL; - } - } - -// --------------------------------------------------------------------------- -// From class MBTEngConnObserver. -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::ConnectComplete( TBTDevAddr& aAddr, TInt aErr, - RBTDevAddrArray* aConflicts) - { - // connection is single profile based, to make sure getting the correct status, - // we always retrieve it from btengconnman: - (void)aConflicts; - (void) aErr; - TInt pos = iDevices.Find( aAddr, MatchDeviceAddress ); - if ( pos > -1 ) - { - TBTEngConnectionStatus old = iDevices[pos]->ServiceConnectionStatus(); - TBTEngConnectionStatus status = EBTEngNotConnected; - // error returned from the call is treated as not connected. - (void) iBtengConn->IsConnected( aAddr, status ); - iDevices[pos]->SetServiceConnectionStatus( status ); - - if ( old != status && - ( status == EBTEngConnected || - status == EBTEngNotConnected ) ) - { - for ( TInt i = 0; i < iObservers.Count(); ++i ) - { - iObservers[i]->ServiceConnectionChanged( - *(iDevices[pos]), status == EBTEngConnected ); - } - } - } - } - -// --------------------------------------------------------------------------- -// From class MBTEngConnObserver. -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::DisconnectComplete( TBTDevAddr& aAddr, TInt aErr ) - { - // unified handling for connections status events: - ConnectComplete( aAddr, aErr, NULL); - } - -// --------------------------------------------------------------------------- -// issue creating a remote device view from the registry -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::CreateRemoteDeviceView() - { - iNotHandledRegEventCounter = 0; - (void) iBTRegistry.CloseView(); - TBTRegistrySearch searchPattern; - searchPattern.FindAll(); - iRegistryActive->SetRequestId( BtServiceUtil::ECreateRemoteDeviceViewRequest ); - iBTRegistry.CreateView( searchPattern, iRegistryActive->iStatus ); - iRegistryActive->GoActive(); - } - -// --------------------------------------------------------------------------- -// gets the paired devices from the view created by CreatePairedDevicesView -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::GetRemoteDevicesL() - { - delete iRegRespRemoteDevices; - iRegRespRemoteDevices = NULL; - iRegRespRemoteDevices = CBTRegistryResponse::NewL( iBTRegistry ); - iRegistryActive->SetRequestId( BtServiceUtil::EGetRemoteDevicesRequest ); - iRegRespRemoteDevices->Start( iRegistryActive->iStatus ); - iRegistryActive->GoActive(); - } - -// --------------------------------------------------------------------------- -// re-create a paired device view if registry was changed during the previous -// operation. otherwise if the view is not empty, get the remote devices. -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::HandleCreateRemoteDeviceViewCompletedL( TInt aStatus ) - { - // aStatus may indicate the number of devices from registry. - // However, our algorithm does not rely on this return error - // for implementation simplicity. - (void) aStatus; - if (iNotHandledRegEventCounter) - { // more registry change detected, create paired device view again: - CreateRemoteDeviceView( ); - } - else - { - GetRemoteDevicesL( ); - } - } - -// --------------------------------------------------------------------------- -// update remote device list. if registry was changed, create a new view. -// otherwise inform client for any changes. -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::HandleGetRemoteDevicesCompletedL( TInt aStatus ) - { - // aStatus may indicate the number of devices from registry. - // However, our algorithm does not rely on this return error. - (void) aStatus; - if (iNotHandledRegEventCounter) - { // more registry change detected, create paired device view again: - CreateRemoteDeviceView( ); - return; - } - - UpdateRemoteDeviceRepositoryL(); - if ( !iInitialized ) - { - iInitialized = ETrue; - // The first time we have got the device lists from registry, - // Get the connections statuses of these devices from bteng. - for ( TInt i = iDevices.Count() - 1; i > -1; --i ) - { - TBTEngConnectionStatus status = EBTEngNotConnected; - // error returned from the call is treated as not connected. - (void) iBtengConn->IsConnected( iDevices[i]->Addr(), status ); - iDevices[i]->SetServiceConnectionStatus( status ); - } - for ( TInt i = 0; i < iObservers.Count(); ++i ) - { - iObservers[i]->RepositoryInitialized(); - } - } - } - -// --------------------------------------------------------------------------- -// update remote devices in local array with the latest data -// --------------------------------------------------------------------------- -// -void CBtDevRepositoryImpl::UpdateRemoteDeviceRepositoryL() - { - TIdentityRelation addrComp( CompareDeviceByAddress ); - RBTDeviceArray& devsFromReg = iRegRespRemoteDevices->Results(); - for ( TInt i = iDevices.Count() - 1; i > -1; --i ) - { - TInt pos = devsFromReg.Find( &(iDevices[i]->Device()), addrComp ); - if ( pos > KErrNotFound ) - { - // Device is found in registry, check if its properties have been changed - TUint similarity = devsFromReg[pos]->CompareTo( iDevices[i]->Device() ); - TBool changed = EFalse; - if ( similarity != - ( CBTDevice::EAllNameProperties | - TBTNamelessDevice::EAllNamelessProperties) ) - { - // This device was updated in registry. - // move its ownership to local store - iDevices[i]->SetDeviceL( devsFromReg[pos] ); - changed = ETrue; - } - else - { - // This device has no update: - delete devsFromReg[pos]; - } - // either the instance at pos has been moved or deleted. - devsFromReg.Remove( pos ); - if ( iInitialized && changed ) - { - for ( TInt counter = 0; counter < iObservers.Count(); ++counter ) - { - iObservers[counter]->ChangedInRegistry( *iDevices[i], similarity ); - } - } - } - else - { - // This device was deleted from registry. - // Free it from the local store before informing client. - TBTDevAddr addr = iDevices[i]->Addr(); - delete iDevices[i]; - iDevices.Remove( i ); - if ( iInitialized ) - { - for ( TInt counter = 0; counter < iObservers.Count(); ++counter ) - { - iObservers[counter]->DeletedFromRegistry( addr ); - } - } - } - } - - // Remaining devices in iRegRespRemoteDevices are new devices: - for ( TInt i = devsFromReg.Count()- 1; i > -1 ; --i ) - { - CBtDevExtension* devExt = CBtDevExtension::NewLC( devsFromReg[i] ); - iDevices.AppendL( devExt ); - CleanupStack::Pop( devExt ); - devsFromReg.Remove( i ); - if ( iInitialized ) - { - for ( TInt counter = 0; counter < iObservers.Count(); ++counter ) - { - iObservers[counter]->AddedToRegistry( *devExt ); - } - } - } - // the devices in devsFromReg was either deleted, or moved. - delete iRegRespRemoteDevices; - iRegRespRemoteDevices = NULL; - }