bluetoothengine/btui/devmodel/src/btdevmodelbase.cpp
changeset 19 43824b19ee35
parent 17 f05641c183ff
child 33 837dcc42fd6a
equal deleted inserted replaced
17:f05641c183ff 19:43824b19ee35
     1 /*
       
     2 * Copyright (c) 2006-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:  Maintain a Bluetooth devices data model for UI components.
       
    15 *
       
    16 */
       
    17 
       
    18 #include "btdevice.h"
       
    19 #include "btdevmodelbase.h"
       
    20 #include <btengutil.h>
       
    21 #include "debug.h"
       
    22 #include "btui.h"
       
    23 #include "btregistryobserver.h"
       
    24 
       
    25 // --------------------------------------------------------------------------------------------
       
    26 // 1st phaze constructor
       
    27 // --------------------------------------------------------------------------------------------
       
    28 CBTDevModelBase::CBTDevModelBase(MBTDeviceObserver* aObserver, TBTDeviceSortOrder* aOrder)
       
    29     : iObserver(aObserver)
       
    30     {
       
    31 	TRACE_FUNC_ENTRY
       
    32 	iSortOrder=aOrder;
       
    33     TRACE_FUNC_EXIT    
       
    34 	
       
    35     }
       
    36 
       
    37 // --------------------------------------------------------------------------------------------
       
    38 // Destructor
       
    39 // --------------------------------------------------------------------------------------------
       
    40 CBTDevModelBase::~CBTDevModelBase()
       
    41     {
       
    42     TRACE_FUNC_ENTRY
       
    43     delete iRegistryObserver;
       
    44 
       
    45     for(TInt i=0;i<iDeviceArray.Count();i++)
       
    46     	delete iDeviceArray[i];    
       
    47 	iDeviceArray.Close();
       
    48 	delete iDevice;
       
    49 	iDevice=NULL;
       
    50 
       
    51     for(TInt i=0;i<iQueue.Count();i++)
       
    52     	delete iQueue[i];    
       
    53 	iQueue.Close();
       
    54 	
       
    55 	if(iDevMan)
       
    56 		iDevMan->Cancel();
       
    57     delete iDevMan;
       
    58     
       
    59     delete iSortOrder;
       
    60     TRACE_FUNC_EXIT        
       
    61     }
       
    62 // --------------------------------------------------------------------------------------------
       
    63 // CBTDevModelBase::IsAnyDeviceConnected
       
    64 // Allways false, since base class does not support connection
       
    65 // --------------------------------------------------------------------------------------------    
       
    66 
       
    67 TBool CBTDevModelBase::IsAnyDeviceConnected()
       
    68     {
       
    69     TRACE_FUNC_ENTRY
       
    70     return EFalse;
       
    71    
       
    72     }
       
    73     
       
    74 // --------------------------------------------------------------------------------------------
       
    75 // CBTDevModelBase::GetDevice
       
    76 // --------------------------------------------------------------------------------------------    
       
    77 TInt CBTDevModelBase::GetDevice(TBTDevice& aDevice)	
       
    78     {
       
    79     TRACE_FUNC_ENTRY
       
    80 	TBTDeviceOp op=aDevice.iOperation;
       
    81 
       
    82     TInt index = GetIndexByAddress(aDevice.iAddr,aDevice.iIndex); 
       
    83 
       
    84     if (index < 0 )
       
    85         {
       
    86         if(aDevice.iAddr == KNullAddress )
       
    87         	{
       
    88         	return KErrArgument;
       
    89         	} 
       
    90         else
       
    91        		{
       
    92 			return KErrNotFound ;
       
    93        		} 
       
    94         }
       
    95     if(index >= iDeviceArray.Count())
       
    96     	return KErrOverflow;
       
    97             
       
    98     aDevice=*iDeviceArray[index];
       
    99     aDevice.iOperation=op;
       
   100     TRACE_FUNC_EXIT        
       
   101     return KErrNone;
       
   102     }
       
   103 // --------------------------------------------------------------------------------------------
       
   104 // CBTDevModelBase::ChangeAllDevices
       
   105 // --------------------------------------------------------------------------------------------        
       
   106 void CBTDevModelBase::ChangeAllDevices(const TBTDeviceOp aOperation)
       
   107     {
       
   108     TRACE_FUNC_ENTRY
       
   109     TInt count = iDeviceArray.Count();  
       
   110     
       
   111     for (TInt i = 0; i < count; i++)
       
   112         {        
       
   113         //TBTDevice device;
       
   114         //device=iDeviceArray[i];
       
   115         //device.iIndex = i;
       
   116         //device.iOperation = aOperation;
       
   117         //ChangeDevice(device);
       
   118         iDeviceArray[i]->iIndex = i;
       
   119         iDeviceArray[i]->iOperation = aOperation;
       
   120         ChangeDevice(*iDeviceArray[i]);        
       
   121         }        
       
   122     TRACE_FUNC_EXIT    
       
   123     }
       
   124 
       
   125 // --------------------------------------------------------------------------------------------
       
   126 // CBTDevModelBase::GetIndexByAddress
       
   127 //
       
   128 // returns the index of the address, if one is not null address.
       
   129 // if it is give aNullAdressIndex
       
   130 // --------------------------------------------------------------------------------------------
       
   131 TInt CBTDevModelBase::GetIndexByAddress(TBTDevAddr aAddr,TInt aNullAdressIndex)
       
   132 	{
       
   133     TRACE_FUNC_ENTRY	
       
   134 	
       
   135     if(aAddr == KNullAddress )
       
   136     	{
       
   137 		TRACE_FUNC_EXIT        			    	
       
   138     	return aNullAdressIndex;
       
   139     	}
       
   140     	else
       
   141     	{
       
   142 	    TInt count = iDeviceArray.Count();
       
   143 	    TInt i;
       
   144 	    for (i = 0; i < count; i++)
       
   145 	        {
       
   146 	        if (iDeviceArray[i]->iAddr == aAddr) break;
       
   147 	        }
       
   148 		if(i == count)
       
   149 			{
       
   150 			TRACE_FUNC_EXIT        		
       
   151 			return KErrNotFound ;	
       
   152 			}
       
   153 	    
       
   154 		else
       
   155 			{
       
   156 			TRACE_FUNC_EXIT        		
       
   157 			return i;		
       
   158 			}	    		
       
   159     	}	    		    
       
   160 	}
       
   161 // --------------------------------------------------------------------------------------------
       
   162 // CBTDevModelBase::DoChangeDevice
       
   163 // --------------------------------------------------------------------------------------------            
       
   164 TInt CBTDevModelBase::DoChangeDeviceL(const TBTDevice& aDevice)
       
   165     {
       
   166     TRACE_FUNC_ENTRY
       
   167     //check that the command in progress has been started       
       
   168    	__ASSERT_DEBUG(iDevice==NULL,PANIC(EBTPanicDevManQueueIsCorrupt));
       
   169 
       
   170     TInt index = GetIndexByAddress(aDevice.iAddr, aDevice.iIndex ); 
       
   171         
       
   172     if (index == KErrNotFound)
       
   173         {
       
   174         TRACE_INFO(_L("index not found"));
       
   175 	    TRACE_FUNC_EXIT    
       
   176         if (aDevice.iAddr == KNullAddress) 
       
   177         	{
       
   178     		return KErrArgument;
       
   179         	}
       
   180         else
       
   181     		{
       
   182     		return KErrNotFound ;
       
   183     		} 
       
   184         }
       
   185     if(index >= iDeviceArray.Count())
       
   186     	{
       
   187         TRACE_INFO((_L("index is %d, max expected is %d"), index, iDeviceArray.Count()));
       
   188    		TRACE_FUNC_EXIT	   
       
   189     	return KErrOverflow;
       
   190     	}
       
   191 
       
   192     
       
   193     TBTDevice* device = iDeviceArray[index];
       
   194     // store pointer to the indexed TBTDevice
       
   195 
       
   196 	// untrust trusted device to be deleted, and delete it only after that
       
   197     if( (device->iStatus & EStatusTrusted ) 
       
   198     	&& aDevice.iOperation== EOpUnpair )
       
   199         	{
       
   200         	device=new (ELeave) TBTDevice(*iDeviceArray[index]);
       
   201         	device->iOperation=EOPInternalUntust;
       
   202         	iQueue.Insert(device,0);
       
   203         	TInt rvalue=DoChangeDeviceL(*device);
       
   204         	TRACE_FUNC_EXIT	   
       
   205         	return rvalue;
       
   206         	}
       
   207     
       
   208  
       
   209     iDevice = new (ELeave) TBTDevice(*device);
       
   210     iDevice->iOperation = aDevice.iOperation;
       
   211 
       
   212     CBTDevice* regDevice = CBTDevice::NewL(iDevice->iAddr);
       
   213 
       
   214     regDevice->SetPaired( aDevice.iLinkKeyType );
       
   215     
       
   216     TBTDeviceSecurity security;
       
   217     
       
   218     if(aDevice.iOperation != EOpChangeName)
       
   219         {
       
   220         regDevice->SetDeviceNameL( BTDeviceNameConverter::ToUTF8L( iDevice->iName ) );
       
   221         
       
   222         // BTEngDevMan will delete friendly name when modify device if friendly name is not set
       
   223         // So if friendly name has been set before, it need to be set again before modify it for
       
   224         // any other purpuse e.g change security
       
   225         regDevice->SetFriendlyNameL(iDevice->iFriendlyName);
       
   226         }  
       
   227         
       
   228     switch (aDevice.iOperation)
       
   229         {
       
   230         case EOpUntrust:
       
   231         case EOPInternalUntust:        
       
   232         	security.SetNoAuthenticate(EFalse);
       
   233             security.SetNoAuthorise(EFalse);	
       
   234         	regDevice->SetGlobalSecurity(security);	        	
       
   235         	UnsetStatusFlags(iDeviceArray[index]->iStatus,EStatusTrusted );  	        
       
   236 			break;
       
   237 				        	
       
   238         case EOpTrust:	        
       
   239             security.SetNoAuthenticate(EFalse); 
       
   240             security.SetNoAuthorise(ETrue);	            
       
   241             security.SetBanned(EFalse);
       
   242         	regDevice->SetGlobalSecurity(security);	        	
       
   243             
       
   244             SetStatusFlags(iDeviceArray[index]->iStatus,EStatusTrusted );
       
   245             break;  
       
   246 
       
   247         case EOpUnblock:
       
   248          	// unblock may be done to a number of devices.
       
   249         	// So we want it to happen as quicky as possible
       
   250         	iRegistryObserver->Cancel();
       
   251           	UnsetStatusFlags( iDevice->iStatus,EStatusBlocked );
       
   252           	security.SetBanned(EFalse );
       
   253             regDevice->DeleteLinkKey();
       
   254 
       
   255             regDevice->SetGlobalSecurity(security);                   	
       
   256         	break;
       
   257         	
       
   258         case EOpBlock:	            
       
   259             security.SetBanned(ETrue );
       
   260             security.SetNoAuthenticate(EFalse );
       
   261             security.SetNoAuthorise(EFalse);
       
   262             regDevice->SetGlobalSecurity(security);
       
   263             regDevice->DeleteLinkKey();
       
   264 
       
   265 			UnsetStatusFlags( iDevice->iStatus,EStatusTrusted );
       
   266         	SetStatusFlags( iDevice->iStatus,EStatusBlocked );
       
   267 			break;
       
   268 
       
   269         case EOpUnpair:
       
   270         	// unpair may be done to a number of devices.
       
   271         	// So we want it to happen as quicky as possible
       
   272         	iRegistryObserver->Cancel();				
       
   273             regDevice->DeleteLinkKey();
       
   274 
       
   275             UnsetStatusFlags(iDevice->iStatus,EStatusPaired);
       
   276             security.SetNoAuthenticate(EFalse );
       
   277             security.SetNoAuthorise(EFalse );         
       
   278             regDevice->SetGlobalSecurity(security);               
       
   279             break;
       
   280 
       
   281         case EOpChangeName:
       
   282             if (IsNameExisting(aDevice.iName)) 
       
   283             	{
       
   284             	delete regDevice;
       
   285             	regDevice=NULL;
       
   286             	return KErrAlreadyExists;
       
   287             	}
       
   288                 
       
   289             regDevice->SetFriendlyNameL(aDevice.iName);
       
   290             iDevice->iName = aDevice.iName;
       
   291             
       
   292             // set iFriendlyName to remember that friendly name has been set
       
   293             iDevice->iFriendlyName = aDevice.iName;
       
   294             break;
       
   295 
       
   296         default:
       
   297             delete regDevice;
       
   298             delete iDevice;
       
   299             iDevice=NULL;
       
   300 			TRACE_FUNC_EXIT            
       
   301             return KErrNotSupported;
       
   302         }
       
   303     iDevMan->ModifyDevice(*regDevice);
       
   304     delete regDevice;
       
   305 
       
   306    	TRACE_FUNC_EXIT    
       
   307     return KErrNone;
       
   308     }
       
   309 // --------------------------------------------------------------------------------------------
       
   310 // CBTDevModelBase::DoChangeDevice
       
   311 // --------------------------------------------------------------------------------------------                
       
   312 void CBTDevModelBase::DoCancelChangeL(const TBTDevice& /*aDevice*/)
       
   313     {
       
   314     TRACE_FUNC_ENTRY
       
   315     iDevMan->Cancel();    
       
   316 	TRACE_FUNC_EXIT    
       
   317     }
       
   318 
       
   319 // --------------------------------------------------------------------------------------------
       
   320 // CBTDevModelBase::CreateDevice
       
   321 // --------------------------------------------------------------------------------------------                    
       
   322 TBTDevice* CBTDevModelBase::CreateDeviceL(const CBTDevice* aRegDevice,
       
   323         TNameEntry* aNameEntry)
       
   324     {
       
   325     TRACE_FUNC_ENTRY
       
   326     TRACE_BDADDR(aRegDevice->BDAddr());
       
   327     TRACE_INFO((_L("CoD %b"), aRegDevice->DeviceClass().DeviceClass()));
       
   328     TBTDevice* device = new (ELeave) TBTDevice();
       
   329     if ( aNameEntry )
       
   330         {
       
   331         device->iNameEntry = *aNameEntry;
       
   332         }
       
   333     switch( aRegDevice->DeviceClass().MajorDeviceClass() )
       
   334         {
       
   335         case EMajorDeviceComputer:
       
   336 			device->iType=EDeviceComputer;
       
   337             break;
       
   338         case EMajorDevicePhone:
       
   339         	device->iType=EDevicePhone;
       
   340             break;
       
   341         case EMajorDeviceAudioDevice:
       
   342         	if ( aRegDevice->DeviceClass().MinorDeviceClass() == EMinorDeviceAVCarAudio ||
       
   343         	     aRegDevice->DeviceClass().MinorDeviceClass() == EMinorDeviceAVHandsfree)
       
   344         		{
       
   345         		device->iType=EDeviceCarkit;
       
   346         		}
       
   347         	else
       
   348         		{
       
   349         		device->iType=EDeviceAudio;
       
   350         		}
       
   351             break;
       
   352 		
       
   353         case EMajorDevicePeripheral:
       
   354         	if ( aRegDevice->DeviceClass().MinorDeviceClass() == EMinorDevicePeripheralKeyboard )
       
   355         		{
       
   356 				device->iType=EDeviceKeyboard;
       
   357         		}
       
   358         	else 
       
   359         		{
       
   360         		
       
   361         		if ( aRegDevice->DeviceClass().MinorDeviceClass() == EMinorDevicePeripheralPointer )
       
   362         			{
       
   363 					device->iType=EDeviceMice;
       
   364         			}	
       
   365         		else
       
   366         			{
       
   367         			device->iType=EDeviceDefault;
       
   368         			}
       
   369         		}
       
   370         	break;
       
   371         	
       
   372         case EMajorDeviceImaging:
       
   373         	if ( aRegDevice->DeviceClass().MinorDeviceClass() == EMinorDeviceImagingPrinter )
       
   374         		{
       
   375 				device->iType=EDevicePrinter;
       
   376         		}
       
   377         	else
       
   378         		{
       
   379         		device->iType=EDeviceDefault;
       
   380         		}
       
   381         	break;
       
   382         
       
   383         default:
       
   384         	device->iType=EDeviceDefault;
       
   385           	break;
       
   386         }
       
   387     device->iAddr = aRegDevice->BDAddr();
       
   388     
       
   389     TBTDeviceSecurity security = aRegDevice->GlobalSecurity();
       
   390     
       
   391     if(security.Banned() )
       
   392     	{
       
   393     	SetStatusFlags(device->iStatus,EStatusBlocked);
       
   394     	}
       
   395     if( IsUserAwarePaired( aRegDevice->AsNamelessDevice() ) )
       
   396     	{
       
   397     	SetStatusFlags(device->iStatus,EStatusPaired);
       
   398     	device->iLinkKeyType = aRegDevice->LinkKeyType();  	
       
   399     	}
       
   400     if( security.NoAuthorise())
       
   401     	SetStatusFlags(device->iStatus,EStatusTrusted);
       
   402 	if(aRegDevice->FriendlyName().Length() >0)
       
   403 		{
       
   404     	device->iName = aRegDevice->FriendlyName();
       
   405     	
       
   406     	// set iFriendlyName to remember that friendly name has been set before in registry 
       
   407     	device->iFriendlyName = aRegDevice->FriendlyName();
       
   408 		}
       
   409 	else
       
   410 		{
       
   411 		CleanupStack::PushL(device);
       
   412 		device->iName = BTDeviceNameConverter::ToUnicodeL(aRegDevice->DeviceName());
       
   413 		CleanupStack::Pop(device);
       
   414 		}
       
   415         
       
   416 
       
   417 	device->iDeviceClass=aRegDevice->DeviceClass();
       
   418     TRACE_FUNC_EXIT    	
       
   419     return device;
       
   420     }
       
   421 // --------------------------------------------------------------------------------------------
       
   422 // CBTDevModelBase::AddDeviceL
       
   423 // --------------------------------------------------------------------------------------------                    
       
   424 void CBTDevModelBase::AddDeviceL(const CBTDevice* aRegDevice, 
       
   425         TNameEntry* aNameEntry, const TBTDeviceOp aOperation)
       
   426     {
       
   427     TRACE_FUNC_ENTRY
       
   428     TBTDevice* device = CreateDeviceL(aRegDevice, aNameEntry);
       
   429     device->iOperation = aOperation;
       
   430     // insert it to the RDeviceArray by order
       
   431 	  iDeviceArray.InsertInOrderL(device,*iSortOrder);
       
   432     TRACE_FUNC_EXIT        
       
   433     }
       
   434 // --------------------------------------------------------------------------------------------
       
   435 // CBTDevModelBase::CreateDevices
       
   436 // --------------------------------------------------------------------------------------------                        
       
   437 void CBTDevModelBase::CreateDevicesL(const CBTDeviceArray* aDeviceArray)
       
   438     {
       
   439     TRACE_FUNC_ENTRY
       
   440     // clear the old contents of the array
       
   441     for(TInt i=0;i<iDeviceArray.Count();i++)
       
   442     	delete iDeviceArray[i];
       
   443     iDeviceArray.Reset();
       
   444     
       
   445     TInt count = aDeviceArray->Count();
       
   446     for (TInt i = 0; i < count; i++)
       
   447         {
       
   448         // form a TBTDevice for a CBTDevice
       
   449         CBTDevice* regDevice = aDeviceArray->At(i);
       
   450 		HandleNewDeviceL(regDevice, NULL);
       
   451 		RenumberDeviceArray();
       
   452         }
       
   453     TRACE_FUNC_EXIT    
       
   454     }
       
   455 // --------------------------------------------------------------------------------------------
       
   456 // CBTDevModelBase::IsNameExisting
       
   457 // --------------------------------------------------------------------------------------------                        
       
   458 TBool CBTDevModelBase::IsNameExisting(const TDesC& aName)
       
   459     {
       
   460     TRACE_FUNC_ENTRY
       
   461     for (TInt i = 0; i < iDeviceArray.Count(); i++)
       
   462         {
       
   463         if (iDeviceArray[i]->iName.Compare(aName) == 0)
       
   464         	{
       
   465         	return ETrue;
       
   466         	}
       
   467         }
       
   468     TRACE_FUNC_EXIT    
       
   469     return EFalse;
       
   470     }
       
   471 // --------------------------------------------------------------------------------------------
       
   472 // CBTDevModelBase::RegistryChangedL
       
   473 // --------------------------------------------------------------------------------------------                            
       
   474 void CBTDevModelBase::RegistryChangedL(const CBTDeviceArray* aDeviceArray)
       
   475     {
       
   476     TRACE_FUNC_ENTRY
       
   477 
       
   478 	// Store the device seleted before refresh
       
   479     TInt bSelectedDeviceIndex = KErrNotFound;
       
   480     if (iObserver)
       
   481 	{
       
   482     	bSelectedDeviceIndex=iObserver->CurrentItemIndex();
       
   483 	}
       
   484 	
       
   485     // the selected device before the update
       
   486     TBTDevice currentDevice;
       
   487         
       
   488     if (bSelectedDeviceIndex != KErrNotFound && bSelectedDeviceIndex < iDeviceArray.Count() )
       
   489     	{    	
       
   490     	currentDevice=*iDeviceArray[bSelectedDeviceIndex];    	
       
   491     	}    
       
   492     
       
   493 	CreateDevicesL(aDeviceArray);
       
   494 
       
   495 	TInt newIndex=GetIndexByAddress(currentDevice.iAddr,KErrNotFound);
       
   496 	if (newIndex==KErrNotFound)
       
   497 	{
       
   498 		newIndex= bSelectedDeviceIndex;
       
   499 	}
       
   500 
       
   501 	newIndex=Min(newIndex,iDeviceArray.Count() -1 );
       
   502 
       
   503 	// notify the listener about the new list of devices
       
   504 	SendRefreshIfNoError(KErrNone,newIndex);    
       
   505 	TRACE_FUNC_EXIT
       
   506     }
       
   507 // ----------------------------------------------------------
       
   508 // CBTDevModelBase::RenumberDeviceArray
       
   509 //
       
   510 // ReCalculates the indexes of internal array.
       
   511 // ----------------------------------------------------------
       
   512 void CBTDevModelBase::RenumberDeviceArray()
       
   513 	{
       
   514 	TRACE_FUNC_ENTRY
       
   515 	for(TInt i=0;i<iDeviceArray.Count();i++)
       
   516 		{
       
   517 		iDeviceArray[i]->iIndex=i;
       
   518 		}
       
   519 	TRACE_FUNC_EXIT	
       
   520 	}
       
   521 //---------------------------------------------------------------------------------------------
       
   522 // from MBTEngDevManObserver for call back on adding, modifying, deleting device completion
       
   523 //---------------------------------------------------------------------------------------------
       
   524 void  CBTDevModelBase::HandleDevManComplete(TInt aErr)
       
   525     {    
       
   526     TRACE_FUNC_ENTRY
       
   527     //command has been succesfully completed. If there is no command but something has
       
   528     // completed, something is very wrong.
       
   529 	__ASSERT_DEBUG(iDevice != NULL || aErr != KErrNone, PANIC(EBTPanicDevManQueueIsCorrupt));    
       
   530 	__ASSERT_DEBUG(iQueue.Count()>0, PANIC(EBTPanicDevManQueueIsCorrupt));    
       
   531 	
       
   532     RenumberDeviceArray();
       
   533     
       
   534 	// EOPInternalUntust is untrst before delete. It is not an operation of its own, so no-one is notified about it.
       
   535     if(iDevice && iDevice->iOperation== EOPInternalUntust)
       
   536     	{
       
   537     	delete(iDevice);
       
   538     	iDevice=NULL;
       
   539 		delete iQueue[0];
       
   540 		iQueue.Remove(0);
       
   541 			    	
       
   542 		HandleQueue();
       
   543 		TRACE_FUNC_EXIT
       
   544 		return;
       
   545     	}
       
   546 	// in case of just paired device the refresh does
       
   547 	// not work adequately quickly, so we have not refresh the
       
   548 	// shown devices immediately.
       
   549 	//
       
   550 	// If we would not do it, there might be a small window, for
       
   551 	// answering yes to to question if user wants to trust the
       
   552 	// device. This would fail, since the device would not
       
   553 	// be in the list.
       
   554     if( aErr == KErrNone && (iDevice->iOperation== EOpTrust || iDevice->iOperation== EOpUntrust ))
       
   555     	{
       
   556 		TInt index=GetIndexByAddress(iDevice->iAddr);
       
   557 		if(index != KErrNotFound)
       
   558 			{    	
       
   559 			if(iDevice->iOperation== EOpTrust )			
       
   560 				{
       
   561 				SetStatusFlags(iDeviceArray[index]->iStatus, EStatusTrusted);
       
   562 				}				
       
   563 			else
       
   564 				{
       
   565 				UnsetStatusFlags(iDeviceArray[index]->iStatus, EStatusTrusted);	
       
   566 				}
       
   567 							
       
   568 	    	SendRefreshIfNoError(aErr);
       
   569 			}
       
   570 			
       
   571     	}
       
   572 	// delete the unpaired and blocked devices from the list
       
   573 	if( aErr == KErrNone && iDevice && 
       
   574 			(iDevice->iOperation== EOpBlock || iDevice->iOperation== EOpUnpair ) )
       
   575 		{
       
   576 			TInt index=GetIndexByAddress(iDevice->iAddr);	
       
   577 			if(index != KErrNotFound )
       
   578 				{
       
   579 					delete( iDeviceArray[index] );
       
   580 					iDeviceArray.Remove(index);				
       
   581 				}
       
   582 			// do not send refresh if this and the next are unpair/unblock operations.
       
   583 			// This is meant to hasten the screen refresh, in case of DeleteAll command
       
   584 			// is issued.
       
   585 			if( iQueue.Count()>1 && iQueue[1]->iOperation==iDevice->iOperation )
       
   586 				{
       
   587 				
       
   588 				}
       
   589 			else
       
   590 				{
       
   591 	    		SendRefreshIfNoError();	
       
   592 	    		iRegistryObserver->StartIfNotRunning();				
       
   593 	    		//NOTE:It is ok to attempt starting when allready running.	    		
       
   594 				}
       
   595 				
       
   596 		}
       
   597     if(iObserver && iDevice)    
       
   598     	iObserver->NotifyChangeDeviceComplete(aErr, *iDevice);
       
   599     
       
   600     delete(iDevice);
       
   601     iDevice=NULL;
       
   602     
       
   603     iRegistryObserver->Refresh();
       
   604 
       
   605 	delete iQueue[0];
       
   606 	iQueue.Remove(0);
       
   607 		    
       
   608 	HandleQueue();
       
   609 	TRACE_FUNC_EXIT	
       
   610     }
       
   611     
       
   612 // ---------------------------------------------------------------------
       
   613 // CBTDevModelBase::HandleGetDevicesComplete
       
   614 // From MBTEngDevManObserver
       
   615 //
       
   616 // Devices are received from CBTRegistryObserver, so this is not used.
       
   617 // ----------------------------------------------------------------------
       
   618 void  CBTDevModelBase::HandleGetDevicesComplete(TInt /*aErr*/, CBTDeviceArray* /*aDeviceArray*/)
       
   619     {
       
   620 	TRACE_FUNC_ENTRY
       
   621  
       
   622 	TRACE_FUNC_EXIT    
       
   623     }
       
   624     
       
   625 
       
   626 // ---------------------------------------------------------------------
       
   627 // CBTDevModelBase::SendRefreshIfNoError
       
   628 // ---------------------------------------------------------------------
       
   629 void CBTDevModelBase::SendRefreshIfNoError(TInt aErr,TInt selectedItem)
       
   630 	{
       
   631 	TRACE_FUNC_ENTRY	
       
   632 	
       
   633 	//this shouldn't be reached if iObserver is NULL
       
   634 	__ASSERT_DEBUG(iObserver, PANIC(EBTPanicNullObserver));
       
   635 	
       
   636 	if (selectedItem == KErrNotSupported )
       
   637 		{
       
   638    		iObserver->RefreshDeviceList( &iDeviceArray ,
       
   639    		        Min(iObserver->CurrentItemIndex(),iDeviceArray.Count()-1  ) );    				
       
   640 		}
       
   641 	else
       
   642 		{
       
   643 	   	if (aErr == KErrNone && iObserver)
       
   644 	   	    {
       
   645 	   		iObserver->RefreshDeviceList( &iDeviceArray,
       
   646 	   		        Min(selectedItem,iDeviceArray.Count()-1  ) );
       
   647 	   	    }
       
   648 		}
       
   649 	
       
   650 	TRACE_FUNC_EXIT   		  
       
   651 	}    
       
   652 // ---------------------------------------------------------------------
       
   653 // CBTDevModelBase::ChangeDeviceL
       
   654 //
       
   655 // puts the change device command into Queue
       
   656 // ---------------------------------------------------------------------	
       
   657 void CBTDevModelBase::ChangeDeviceL(const TBTDevice& aDevice)
       
   658 	{
       
   659 	TRACE_FUNC_ENTRY
       
   660 	
       
   661 	TBTDevice* device=new(ELeave) TBTDevice(aDevice);		
       
   662 	CleanupStack::PushL(device);
       
   663 
       
   664 	TInt err = GetDevice(*device);
       
   665 	if(err!=KErrNone)
       
   666 		{
       
   667 		CleanupStack::PopAndDestroy(device);
       
   668 		User::Leave(err);
       
   669 		}
       
   670 
       
   671 	if(aDevice.iOperation==EOpChangeName)
       
   672 		{
       
   673 		device->iName=aDevice.iName;		
       
   674 		}
       
   675 	
       
   676 	iQueue.Append(device);
       
   677 	CleanupStack::Pop(device);	
       
   678 	if(iQueue.Count() ==1 )
       
   679 		{
       
   680 			User::LeaveIfError( DoChangeDeviceL(*iQueue[0]) );
       
   681 		}
       
   682 	TRACE_FUNC_EXIT
       
   683 	}
       
   684 
       
   685 // ---------------------------------------------------------------------
       
   686 // CBTDevModelBase::ChangeDevice
       
   687 //
       
   688 // Calls the ChangeDeviceL and traps leaves and calls error callback,
       
   689 // if they occur.
       
   690 // ---------------------------------------------------------------------	
       
   691 void CBTDevModelBase::ChangeDevice(const TBTDevice& aDevice)
       
   692 	{
       
   693 	TRACE_FUNC_ENTRY		
       
   694 	TRAPD(err,
       
   695 		ChangeDeviceL(aDevice);
       
   696 	);
       
   697 	if(err!=KErrNone)
       
   698 	{
       
   699 		HandleLeave(err,&aDevice);	
       
   700 	}
       
   701 	TRACE_FUNC_EXIT
       
   702 	}
       
   703 
       
   704 // ---------------------------------------------------------------------
       
   705 // CBTDevModelBase::CancelChange
       
   706 //
       
   707 // cancels the change from queue, only calls DoCancelChange,
       
   708 // if the command is actually in progress.
       
   709 // ---------------------------------------------------------------------		
       
   710 void CBTDevModelBase::CancelChange(const TBTDevice& aDevice)	
       
   711 	{
       
   712 	TRACE_FUNC_ENTRY	
       
   713 	// retrieve the device based on index, in
       
   714 	// case the address is not filled in.
       
   715 	TBTDevice device=aDevice;
       
   716 	GetDevice(device);
       
   717 	device.iOperation=aDevice.iOperation;
       
   718 				
       
   719 	// delete any operations to device from queueu
       
   720 	if(iQueue.Count()>0 )
       
   721 		{
       
   722 		// Before calling DoCancelChangeL check if first operation on the 
       
   723 		// queue is the one to be cancelled - otherwise crash may occure 
       
   724 		// as per TSW EMZA-7EUHYE
       
   725 		if(iQueue[0]->iAddr== device.iAddr &&
       
   726 			iQueue[0]->iOperation== device.iOperation )
       
   727 			TRAP_IGNORE(DoCancelChangeL(device));
       
   728 		
       
   729 		for (TInt i = iQueue.Count() - 1; i >= 0; i--)
       
   730 			{
       
   731 			if(iQueue[i]->iAddr== device.iAddr &&
       
   732 				iQueue[i]->iOperation== device.iOperation )
       
   733 				{
       
   734 				delete iQueue[i];
       
   735 				iQueue.Remove(i);
       
   736 				}
       
   737 			}
       
   738 		}
       
   739 	// failed cancel is not reported forward.		
       
   740 	TRACE_FUNC_EXIT			
       
   741 	}
       
   742 	
       
   743 // ---------------------------------------------------------------------
       
   744 // CBTDevModelBase::DeviceChangeInProgress
       
   745 // ---------------------------------------------------------------------
       
   746 TBool CBTDevModelBase::DeviceChangeInProgress()
       
   747 	{
       
   748 	TRACE_FUNC_ENTRY
       
   749 	TRACE_FUNC_EXIT
       
   750 	return iQueue.Count() !=0;
       
   751 	}
       
   752 
       
   753 // ---------------------------------------------------------------------
       
   754 // CBTDevModelBase::HandleQueue
       
   755 //
       
   756 // Starts executing the next devicechange(if any).
       
   757 // Currently Executed command must be deleted from iQueue and iDevice
       
   758 // (and corresponding places in subclasses), before calling this method.
       
   759 // ---------------------------------------------------------------------
       
   760 	
       
   761 void CBTDevModelBase::HandleQueue()
       
   762 	{
       
   763 	TRACE_FUNC_ENTRY
       
   764 	
       
   765 	RenumberDeviceArray();
       
   766 	if(iQueue.Count() >0 )
       
   767 		{
       
   768 		TRAPD(err2,	DoChangeDeviceL(*iQueue[0]); );
       
   769 		if (err2 !=KErrNone)
       
   770 			{
       
   771 			HandleLeave(err2,iQueue[0]);
       
   772 			}
       
   773 		}
       
   774 	TRACE_FUNC_EXIT		
       
   775 	}
       
   776 
       
   777 // ---------------------------------------------------------------------
       
   778 // CBTDevModelBase::HandleLeave
       
   779 // ---------------------------------------------------------------------
       
   780 void CBTDevModelBase::HandleLeave(TInt aErr,const TBTDevice* aDevice )
       
   781 	{
       
   782 	TRACE_FUNC_ENTRY
       
   783 	iRegistryObserver->StartIfNotRunning();
       
   784 	iRegistryObserver->Refresh();
       
   785 	if(aDevice == NULL )
       
   786 		{		
       
   787 		iObserver->NotifyChangeDeviceComplete(aErr,TBTDevice() );	
       
   788 		} 
       
   789 	else
       
   790 		{		
       
   791 		iObserver->NotifyChangeDeviceComplete(aErr, *aDevice );	
       
   792 		} 
       
   793 	delete iDevice;
       
   794 	iDevice=NULL;
       
   795 	iDevMan->Cancel();
       
   796 
       
   797 	if(aDevice != NULL && iQueue.Count() > 0 && 
       
   798 		(iQueue[0]->iAddr == aDevice->iAddr ) && 
       
   799 		(iQueue[0]->iOperation == aDevice->iOperation ) )
       
   800 		{
       
   801 		delete iQueue[0];
       
   802 		iQueue.Remove(0);
       
   803 		}	
       
   804 	
       
   805 	HandleQueue();
       
   806 	TRACE_FUNC_EXIT
       
   807 	}