bluetoothengine/btui/btuidelegate/btdelegateconnect.cpp
branchRCL_3
changeset 23 9386f31cc85b
parent 22 613943a21004
child 24 269724087bed
equal deleted inserted replaced
22:613943a21004 23:9386f31cc85b
     1 /*
       
     2 * Copyright (c) 2010 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: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include "btdelegateconnect.h"
       
    19 #include "btuiutil.h"
       
    20 #include "btqtconstants.h"
       
    21 #include <QModelIndex>
       
    22 #include <hblabel.h>
       
    23 #include <btsettingmodel.h>
       
    24 #include <btdevicemodel.h>
       
    25 #include <hbnotificationdialog.h>
       
    26 #include <hbmessagebox.h>
       
    27 #include "btuiiconutil.h"
       
    28 #include "btdelegatefactory.h"
       
    29 #include <bluetoothuitrace.h>
       
    30 #include <e32property.h>
       
    31 #include <ctsydomainpskeys.h>  
       
    32 
       
    33 BtDelegateConnect::BtDelegateConnect(
       
    34         BtSettingModel* settingModel, 
       
    35         BtDeviceModel* deviceModel, QObject *parent) :
       
    36     BtAbstractDelegate(settingModel, deviceModel, parent), mBtengConnMan(0),
       
    37     mAbstractDelegate(0), mActiveHandling(false)
       
    38 {
       
    39     
       
    40 }
       
    41 
       
    42 BtDelegateConnect::~BtDelegateConnect()
       
    43 {
       
    44     delete mBtengConnMan;
       
    45 }
       
    46 
       
    47 /*!
       
    48  * execute connect operation
       
    49  *    first check if power is on
       
    50  */
       
    51 void BtDelegateConnect::exec( const QVariant &params )
       
    52 {
       
    53     if ( mActiveHandling ) {
       
    54         emit commandCompleted( KErrAlreadyExists );
       
    55         return;
       
    56     }
       
    57     mIndex = params.value<QModelIndex>();
       
    58     mActiveHandling = true;
       
    59     // save needed values from model
       
    60     mDeviceName = (mIndex.data(BtDeviceModel::NameAliasRole)).toString();
       
    61     QString addrStr = (mIndex.data(BtDeviceModel::ReadableBdaddrRole)).toString(); 
       
    62     addrReadbleStringToSymbian( addrStr, mAddr );  
       
    63     
       
    64     mCod = (mIndex.data(BtDeviceModel::CoDRole)).toInt();
       
    65     mMajorProperty = (mIndex.data(BtDeviceModel::MajorPropertyRole)).toInt();
       
    66     
       
    67     // first turn on power if needed
       
    68     if (!isBtPowerOn()) {
       
    69         if (!mAbstractDelegate) //if there is no other delegate running
       
    70         { 
       
    71             mAbstractDelegate = BtDelegateFactory::newDelegate(BtDelegate::ManagePower, 
       
    72                     getSettingModel(), getDeviceModel() ); 
       
    73             connect( mAbstractDelegate, SIGNAL(commandCompleted(int)), this, SLOT(powerDelegateCompleted(int)) );
       
    74             mAbstractDelegate->exec(QVariant(BtPowerOn));
       
    75         }
       
    76     } 
       
    77     else {
       
    78         // power is already on
       
    79         exec_connect();
       
    80     }
       
    81 }
       
    82 
       
    83 /*!
       
    84  * power delegate has completed, continue processing
       
    85  */
       
    86 void BtDelegateConnect::powerDelegateCompleted(int status)
       
    87 {
       
    88     if (mAbstractDelegate)
       
    89     {
       
    90         disconnect(mAbstractDelegate);
       
    91         delete mAbstractDelegate;
       
    92         mAbstractDelegate = 0;
       
    93     }
       
    94     if ( status == KErrNone ) {
       
    95         // continue connecting
       
    96         exec_connect();
       
    97     } 
       
    98     else {
       
    99         // error
       
   100         emitCommandComplete(status);
       
   101     }
       
   102 }
       
   103 
       
   104 /*!
       
   105  * execute connect operation
       
   106  */
       
   107 void BtDelegateConnect::exec_connect()
       
   108 {
       
   109     int error = KErrNone;
       
   110     
       
   111     if ( ! mBtengConnMan ){
       
   112         TRAP( error, mBtengConnMan = CBTEngConnMan::NewL(this) );
       
   113     }
       
   114 
       
   115     if ( !error ) {
       
   116         TBTDeviceClass btEngDeviceClass(mCod);
       
   117         error = mBtengConnMan->Connect(mAddr, btEngDeviceClass);
       
   118     }
       
   119     
       
   120     if( error ) {
       
   121         emitCommandComplete(error);
       
   122     }
       
   123 }
       
   124 
       
   125 /*!
       
   126  * connect callback from CBTengConnMan
       
   127  */
       
   128 void BtDelegateConnect::ConnectComplete( TBTDevAddr& aAddr, TInt aErr, 
       
   129                                    RBTDevAddrArray* aConflicts )
       
   130 {
       
   131     // It is possible that another audio device has just connected to phone when we are
       
   132     // connecting to this audio device. Or a device is connected while this command
       
   133     // is idle. No handling for these cases.
       
   134     if ( mAddr != aAddr || !mActiveHandling ) {  
       
   135         return;
       
   136     }
       
   137     
       
   138     // conflict could occur as well if another audio device is already connected
       
   139     // since currently we don't support multiple audio device connections.
       
   140     if ( aErr && aConflicts && aConflicts->Count() ) {
       
   141         // get the display name of the device that is 
       
   142         // causing the conflict 
       
   143         QString conflictDevAddr;
       
   144         addrSymbianToReadbleString(conflictDevAddr, (*aConflicts)[0] );
       
   145         QModelIndex start = getDeviceModel()->index(0,0);
       
   146         QModelIndexList indexList = getDeviceModel()->match(start, BtDeviceModel::ReadableBdaddrRole, conflictDevAddr);
       
   147         BTUI_ASSERT_X(indexList.count(), "BtDelegateConnect::ConnectComplete()", "device missing from model!");
       
   148         mConflictDevIndex = indexList.at(0);
       
   149       
       
   150         // check if conflict device is being used in a call
       
   151         // Note:  actually only checking if *any* audio device is involved in a call, not necessarily the
       
   152         // one we are concerned with here.  Btaudioman does not currently support finding out the actual 
       
   153         // device involved in a call. 
       
   154         if (callOngoing()) {
       
   155             HbMessageBox::warning(hbTrId("txt_bt_info_not_possible_during_a_call"));
       
   156             emitCommandComplete(KErrCancel);
       
   157         }
       
   158         else {
       
   159             // no call, check if user wants to disconnect conflict device 
       
   160             QString conflictDevName = (mConflictDevIndex.data(BtDeviceModel::NameAliasRole)).toString();    
       
   161     
       
   162             QString questionText(hbTrId("txt_bt_info_to_connect_1_2_needs_to_be_disconnec")
       
   163                     .arg(mDeviceName).arg(conflictDevName));
       
   164             
       
   165             HbMessageBox::question( questionText, this, SLOT(handleUserAnswer(int)), 
       
   166                     HbMessageBox::Continue | HbMessageBox::Cancel );       
       
   167         }
       
   168     }
       
   169     else {
       
   170         // command is finished
       
   171         emitCommandComplete(aErr);
       
   172     }
       
   173 }
       
   174 
       
   175 /*!
       
   176  * handle user response to query about disconnecting conflict device
       
   177  */
       
   178 void BtDelegateConnect::handleUserAnswer( int answer )
       
   179 {
       
   180     if( answer == HbMessageBox::Continue ) { 
       
   181         // Continue, ie. disconnect conflict device and then try reconnecting again
       
   182         if (!mAbstractDelegate) //if there is no other delegate running
       
   183         { 
       
   184             QList<QVariant>list;
       
   185             QVariant paramFirst;
       
   186             paramFirst.setValue(mConflictDevIndex);    
       
   187             QVariant paramSecond(ServiceLevel);
       
   188             list.append(paramFirst);
       
   189             list.append(paramSecond);
       
   190             QVariant paramsList(list);
       
   191             mAbstractDelegate = BtDelegateFactory::newDelegate(BtDelegate::Disconnect, 
       
   192                     getSettingModel(), getDeviceModel() ); 
       
   193             connect( mAbstractDelegate, SIGNAL(commandCompleted(int)), this, SLOT(disconnectDelegateCompleted(int)) );
       
   194             mAbstractDelegate->exec(paramsList);
       
   195         }
       
   196     }
       
   197     else {
       
   198         // Cancel connect operation
       
   199         emitCommandComplete(KErrCancel);
       
   200     }
       
   201 }
       
   202 
       
   203 /*!
       
   204  * returns true if phone call is ongoing
       
   205  */
       
   206 bool BtDelegateConnect::callOngoing()
       
   207 {
       
   208     // ToDo:  check if there exists Qt PS key for ongoing call
       
   209     int callState;
       
   210     int err = RProperty::Get(KPSUidCtsyCallInformation, KCTsyCallState, callState);
       
   211     if (!err && (callState == EPSCTsyCallStateNone || callState == EPSCTsyCallStateUninitialized)) {
       
   212         return false;
       
   213     }
       
   214     else {
       
   215         return true;
       
   216     }
       
   217 }
       
   218 
       
   219 /*!
       
   220  * disconnecting conflict device has completed, continue connecting
       
   221  */
       
   222 void BtDelegateConnect::disconnectDelegateCompleted(int status)
       
   223 {
       
   224     if (mAbstractDelegate)
       
   225     {
       
   226         disconnect(mAbstractDelegate);
       
   227         delete mAbstractDelegate;
       
   228         mAbstractDelegate = 0;
       
   229     }
       
   230     // finished disconnecting conflict device, now reconnect to original device
       
   231     if ( status == KErrNone ) {
       
   232         exec_connect();
       
   233     }
       
   234     else {
       
   235         // disconnect failed, abort
       
   236         emitCommandComplete( status );
       
   237     }
       
   238 }
       
   239 
       
   240 /*!
       
   241  * not used here
       
   242  */
       
   243 void BtDelegateConnect::DisconnectComplete( TBTDevAddr& aAddr, TInt aErr )
       
   244 {
       
   245     Q_UNUSED(aAddr);
       
   246     Q_UNUSED(aErr);    
       
   247 }
       
   248 
       
   249 /*!
       
   250  * cancel connect operation
       
   251  *   ConnectComplete() callback will be called upon completion of cancel with KErrCancel
       
   252  */
       
   253 void BtDelegateConnect::cancel()
       
   254 {
       
   255     if ( mBtengConnMan ) {
       
   256         mBtengConnMan->CancelConnect(mAddr);
       
   257     }
       
   258 }
       
   259 
       
   260 /*!
       
   261  * shows user notes with connection success/failure information
       
   262  *    cancel operation is handled without a user note
       
   263  */
       
   264 void BtDelegateConnect::emitCommandComplete(int error)
       
   265 {
       
   266     if ( error == KErrNone ) {
       
   267         // success, show indicator with connection status
       
   268         
       
   269         HbIcon icon = getBadgedDeviceTypeIcon( mCod, mMajorProperty, BtuiNoCorners); 
       
   270         QString str(hbTrId("txt_bt_dpopinfo_connected_to_1"));
       
   271         HbNotificationDialog::launchDialog( icon, hbTrId("txt_bt_dpophead_connected"), 
       
   272             str.arg(mDeviceName) );  
       
   273     }
       
   274     else if ( error == KErrCancel ) {
       
   275         // no user note, return success since cancel operation completed successfully
       
   276         error = KErrNone;
       
   277     }
       
   278     else {
       
   279         // failure to connect, show user note
       
   280         QString err(hbTrId("txt_bt_info_unable_to_connect_with_bluetooth"));
       
   281         HbMessageBox::warning(err.arg(mDeviceName));
       
   282     }
       
   283     mActiveHandling = false;
       
   284     
       
   285     emit commandCompleted(error);
       
   286 }
       
   287 
       
   288