bluetoothengine/btui/btuidelegate/btdelegateconnect.cpp
branchRCL_3
changeset 55 613943a21004
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btui/btuidelegate/btdelegateconnect.cpp	Tue Aug 31 15:25:10 2010 +0300
@@ -0,0 +1,288 @@
+/*
+* 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: 
+*
+*/
+
+#include "btdelegateconnect.h"
+#include "btuiutil.h"
+#include "btqtconstants.h"
+#include <QModelIndex>
+#include <hblabel.h>
+#include <btsettingmodel.h>
+#include <btdevicemodel.h>
+#include <hbnotificationdialog.h>
+#include <hbmessagebox.h>
+#include "btuiiconutil.h"
+#include "btdelegatefactory.h"
+#include <bluetoothuitrace.h>
+#include <e32property.h>
+#include <ctsydomainpskeys.h>  
+
+BtDelegateConnect::BtDelegateConnect(
+        BtSettingModel* settingModel, 
+        BtDeviceModel* deviceModel, QObject *parent) :
+    BtAbstractDelegate(settingModel, deviceModel, parent), mBtengConnMan(0),
+    mAbstractDelegate(0), mActiveHandling(false)
+{
+    
+}
+
+BtDelegateConnect::~BtDelegateConnect()
+{
+    delete mBtengConnMan;
+}
+
+/*!
+ * execute connect operation
+ *    first check if power is on
+ */
+void BtDelegateConnect::exec( const QVariant &params )
+{
+    if ( mActiveHandling ) {
+        emit commandCompleted( KErrAlreadyExists );
+        return;
+    }
+    mIndex = params.value<QModelIndex>();
+    mActiveHandling = true;
+    // save needed values from model
+    mDeviceName = (mIndex.data(BtDeviceModel::NameAliasRole)).toString();
+    QString addrStr = (mIndex.data(BtDeviceModel::ReadableBdaddrRole)).toString(); 
+    addrReadbleStringToSymbian( addrStr, mAddr );  
+    
+    mCod = (mIndex.data(BtDeviceModel::CoDRole)).toInt();
+    mMajorProperty = (mIndex.data(BtDeviceModel::MajorPropertyRole)).toInt();
+    
+    // first turn on power if needed
+    if (!isBtPowerOn()) {
+        if (!mAbstractDelegate) //if there is no other delegate running
+        { 
+            mAbstractDelegate = BtDelegateFactory::newDelegate(BtDelegate::ManagePower, 
+                    getSettingModel(), getDeviceModel() ); 
+            connect( mAbstractDelegate, SIGNAL(commandCompleted(int)), this, SLOT(powerDelegateCompleted(int)) );
+            mAbstractDelegate->exec(QVariant(BtPowerOn));
+        }
+    } 
+    else {
+        // power is already on
+        exec_connect();
+    }
+}
+
+/*!
+ * power delegate has completed, continue processing
+ */
+void BtDelegateConnect::powerDelegateCompleted(int status)
+{
+    if (mAbstractDelegate)
+    {
+        disconnect(mAbstractDelegate);
+        delete mAbstractDelegate;
+        mAbstractDelegate = 0;
+    }
+    if ( status == KErrNone ) {
+        // continue connecting
+        exec_connect();
+    } 
+    else {
+        // error
+        emitCommandComplete(status);
+    }
+}
+
+/*!
+ * execute connect operation
+ */
+void BtDelegateConnect::exec_connect()
+{
+    int error = KErrNone;
+    
+    if ( ! mBtengConnMan ){
+        TRAP( error, mBtengConnMan = CBTEngConnMan::NewL(this) );
+    }
+
+    if ( !error ) {
+        TBTDeviceClass btEngDeviceClass(mCod);
+        error = mBtengConnMan->Connect(mAddr, btEngDeviceClass);
+    }
+    
+    if( error ) {
+        emitCommandComplete(error);
+    }
+}
+
+/*!
+ * connect callback from CBTengConnMan
+ */
+void BtDelegateConnect::ConnectComplete( TBTDevAddr& aAddr, TInt aErr, 
+                                   RBTDevAddrArray* aConflicts )
+{
+    // It is possible that another audio device has just connected to phone when we are
+    // connecting to this audio device. Or a device is connected while this command
+    // is idle. No handling for these cases.
+    if ( mAddr != aAddr || !mActiveHandling ) {  
+        return;
+    }
+    
+    // conflict could occur as well if another audio device is already connected
+    // since currently we don't support multiple audio device connections.
+    if ( aErr && aConflicts && aConflicts->Count() ) {
+        // get the display name of the device that is 
+        // causing the conflict 
+        QString conflictDevAddr;
+        addrSymbianToReadbleString(conflictDevAddr, (*aConflicts)[0] );
+        QModelIndex start = getDeviceModel()->index(0,0);
+        QModelIndexList indexList = getDeviceModel()->match(start, BtDeviceModel::ReadableBdaddrRole, conflictDevAddr);
+        BTUI_ASSERT_X(indexList.count(), "BtDelegateConnect::ConnectComplete()", "device missing from model!");
+        mConflictDevIndex = indexList.at(0);
+      
+        // check if conflict device is being used in a call
+        // Note:  actually only checking if *any* audio device is involved in a call, not necessarily the
+        // one we are concerned with here.  Btaudioman does not currently support finding out the actual 
+        // device involved in a call. 
+        if (callOngoing()) {
+            HbMessageBox::warning(hbTrId("txt_bt_info_not_possible_during_a_call"));
+            emitCommandComplete(KErrCancel);
+        }
+        else {
+            // no call, check if user wants to disconnect conflict device 
+            QString conflictDevName = (mConflictDevIndex.data(BtDeviceModel::NameAliasRole)).toString();    
+    
+            QString questionText(hbTrId("txt_bt_info_to_connect_1_2_needs_to_be_disconnec")
+                    .arg(mDeviceName).arg(conflictDevName));
+            
+            HbMessageBox::question( questionText, this, SLOT(handleUserAnswer(int)), 
+                    HbMessageBox::Continue | HbMessageBox::Cancel );       
+        }
+    }
+    else {
+        // command is finished
+        emitCommandComplete(aErr);
+    }
+}
+
+/*!
+ * handle user response to query about disconnecting conflict device
+ */
+void BtDelegateConnect::handleUserAnswer( int answer )
+{
+    if( answer == HbMessageBox::Continue ) { 
+        // Continue, ie. disconnect conflict device and then try reconnecting again
+        if (!mAbstractDelegate) //if there is no other delegate running
+        { 
+            QList<QVariant>list;
+            QVariant paramFirst;
+            paramFirst.setValue(mConflictDevIndex);    
+            QVariant paramSecond(ServiceLevel);
+            list.append(paramFirst);
+            list.append(paramSecond);
+            QVariant paramsList(list);
+            mAbstractDelegate = BtDelegateFactory::newDelegate(BtDelegate::Disconnect, 
+                    getSettingModel(), getDeviceModel() ); 
+            connect( mAbstractDelegate, SIGNAL(commandCompleted(int)), this, SLOT(disconnectDelegateCompleted(int)) );
+            mAbstractDelegate->exec(paramsList);
+        }
+    }
+    else {
+        // Cancel connect operation
+        emitCommandComplete(KErrCancel);
+    }
+}
+
+/*!
+ * returns true if phone call is ongoing
+ */
+bool BtDelegateConnect::callOngoing()
+{
+    // ToDo:  check if there exists Qt PS key for ongoing call
+    int callState;
+    int err = RProperty::Get(KPSUidCtsyCallInformation, KCTsyCallState, callState);
+    if (!err && (callState == EPSCTsyCallStateNone || callState == EPSCTsyCallStateUninitialized)) {
+        return false;
+    }
+    else {
+        return true;
+    }
+}
+
+/*!
+ * disconnecting conflict device has completed, continue connecting
+ */
+void BtDelegateConnect::disconnectDelegateCompleted(int status)
+{
+    if (mAbstractDelegate)
+    {
+        disconnect(mAbstractDelegate);
+        delete mAbstractDelegate;
+        mAbstractDelegate = 0;
+    }
+    // finished disconnecting conflict device, now reconnect to original device
+    if ( status == KErrNone ) {
+        exec_connect();
+    }
+    else {
+        // disconnect failed, abort
+        emitCommandComplete( status );
+    }
+}
+
+/*!
+ * not used here
+ */
+void BtDelegateConnect::DisconnectComplete( TBTDevAddr& aAddr, TInt aErr )
+{
+    Q_UNUSED(aAddr);
+    Q_UNUSED(aErr);    
+}
+
+/*!
+ * cancel connect operation
+ *   ConnectComplete() callback will be called upon completion of cancel with KErrCancel
+ */
+void BtDelegateConnect::cancel()
+{
+    if ( mBtengConnMan ) {
+        mBtengConnMan->CancelConnect(mAddr);
+    }
+}
+
+/*!
+ * shows user notes with connection success/failure information
+ *    cancel operation is handled without a user note
+ */
+void BtDelegateConnect::emitCommandComplete(int error)
+{
+    if ( error == KErrNone ) {
+        // success, show indicator with connection status
+        
+        HbIcon icon = getBadgedDeviceTypeIcon( mCod, mMajorProperty, BtuiNoCorners); 
+        QString str(hbTrId("txt_bt_dpopinfo_connected_to_1"));
+        HbNotificationDialog::launchDialog( icon, hbTrId("txt_bt_dpophead_connected"), 
+            str.arg(mDeviceName) );  
+    }
+    else if ( error == KErrCancel ) {
+        // no user note, return success since cancel operation completed successfully
+        error = KErrNone;
+    }
+    else {
+        // failure to connect, show user note
+        QString err(hbTrId("txt_bt_info_unable_to_connect_with_bluetooth"));
+        HbMessageBox::warning(err.arg(mDeviceName));
+    }
+    mActiveHandling = false;
+    
+    emit commandCompleted(error);
+}
+
+