src/hbcore/devicedialogbase/hbsymbiandevicedialog.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbCore module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include <QVariant>
       
    27 
       
    28 #include "hbdevicedialogserverdefs_p.h"
       
    29 #include "hbdevicedialogerrors_p.h"
       
    30 #include "hbdevicedialogclientsession_p.h"
       
    31 #include <e32cmn.h>
       
    32 
       
    33 #include "hbsymbiandevicedialog.h"
       
    34 #include "hbsymbianvariant.h"
       
    35 #include "hbsymbianvariantconverter_p.h"
       
    36 
       
    37 /*!
       
    38  \class CHbDeviceDialog
       
    39  \brief CHbDeviceDialog is a Symbian implementation of HbDeviceDialog.
       
    40 
       
    41  CHbDeviceDialog displays dialogs on top of applications. It is a client interface for Symbian applications to
       
    42  Hb device dialogs.
       
    43  \deprecated this class is deprecated, use CHbDeviceDialogSymbian instead.
       
    44 
       
    45  \sa HbDeviceDialog
       
    46 
       
    47  Data given to this API in s60 format is packed to QVariantMap. See
       
    48  CHbSymbianVariant to see which Qt datatypes are supported.
       
    49  \sa CHbSymbianVariant
       
    50  \sa CHbSymbianVariantMap
       
    51 
       
    52  When plugin returns data in Qt format, the data is converted, if possible,
       
    53  to CHbSymbianVariantMap.
       
    54 
       
    55  \proto
       
    56 
       
    57  \hbcore
       
    58  */
       
    59 
       
    60 /*!
       
    61     \enum CHbDeviceDialog::TDeviceDialogError
       
    62     Defines device dialog error codes and ranges.
       
    63 */
       
    64 /*!
       
    65     \var TDeviceDialogError::DeviceDialogError HbDeviceDialog::FrameworkErrors
       
    66     Start of an error range for errors originating from device dialog framework (client or server).
       
    67 */
       
    68 /*!
       
    69     \var TDeviceDialogError::DeviceDialogError HbDeviceDialog::PluginErrors
       
    70     Start of an error range for errors originating from device dialog plugins. The framework passes
       
    71     these from the plugin unmodified.
       
    72 */
       
    73 /*!
       
    74     \var TDeviceDialogError::DeviceDialogError HbDeviceDialog::ErrorTypeMask
       
    75     Mask for error type part of the error code.
       
    76 */
       
    77 /*!
       
    78     \var TDeviceDialogError::DeviceDialogError HbDeviceDialog::CancelledError
       
    79     Operation was cancelled by Cancel().
       
    80 */
       
    81 /*!
       
    82     \var DeviceDialogs60Error::DeviceDialogError HbDeviceDialog::SystemCancelledError
       
    83     Operation was cancelled by device dialog framework.
       
    84 */
       
    85 
       
    86 /*!
       
    87    \fn void MHbDeviceDialogObserver::DataReceived(CHbSymbianVariantMap& aData)
       
    88 
       
    89     This callback is called when data is received from a device dialog.
       
    90     \a aData contains data from the dialog plugin.
       
    91     The structure and meaning of the data is a contract between the dialog and
       
    92     a client. Structure should be aligned with the data types supported by
       
    93 	CHbSymbianVariantMap.
       
    94 
       
    95     \sa CHbSymbianVariantMap.
       
    96 */
       
    97 
       
    98 /*!
       
    99     \fn void MHbDeviceDialogObserver::DeviceDialogClosed(TInt aCompletionCode)
       
   100 
       
   101     This callback is called when a device dialog is closed. Any data sent by
       
   102     the dialog is indicated by the dataReceived() callback. If no observer is
       
   103     set in CHbDeviceDialog::Show the latest data can be retrieved with
       
   104     CHbDeviceDialog::receivedData()
       
   105 
       
   106     \a aCompletionCode gives the result of the dialog completion. Code can be
       
   107     either Symbian error code or device dialog error code
       
   108     device dialog error code
       
   109 
       
   110     \sa DataReceived() ReceivedData()
       
   111 */
       
   112 
       
   113 // Device dialogs are implemented only for Symbian/S60 OS.
       
   114 
       
   115 class CHbDeviceDialogPrivate : public CActive
       
   116 {
       
   117 public:
       
   118         CHbDeviceDialogPrivate();
       
   119         ~CHbDeviceDialogPrivate();
       
   120         TInt Show( const QByteArray& aArray );
       
   121         TInt Update( const QByteArray& aArray );
       
   122         void CancelDialog();
       
   123         TInt Error() const;
       
   124         void SetObserver( MHbDeviceDialogObserver* aObserver );
       
   125 
       
   126         // CActive
       
   127         void RunL();
       
   128         void DoCancel();
       
   129         TInt RunError( TInt aError );
       
   130 
       
   131         void Start();
       
   132         TInt SymToDeviceDialogError( TInt errorCode );
       
   133         void SetError(TInt aError);
       
   134 
       
   135 public:
       
   136     TInt iFlags;
       
   137     RHbDeviceDialogClientSession iHbSession;
       
   138     TInt iLastError;
       
   139     TPckgBuf<THbDeviceDialogSrvUpdateInfo> iUpdateInfo;
       
   140     TPckgBuf<int> iDeviceDialogId;
       
   141     HBufC8* iBuffer;
       
   142     TPtr8 iDataPtr;
       
   143     TBool iRequesting;
       
   144     QVariantMap iDataReceived;
       
   145     CActiveSchedulerWait* iWait;
       
   146     MHbDeviceDialogObserver* iObserver;
       
   147 
       
   148 };
       
   149 
       
   150 CHbDeviceDialogPrivate::CHbDeviceDialogPrivate():
       
   151 CActive( EPriorityStandard ),
       
   152 iFlags(0),
       
   153 iLastError(0),
       
   154 iDeviceDialogId(0),
       
   155 iBuffer(NULL),
       
   156 iDataPtr(NULL, 0, 0),
       
   157 iRequesting(EFalse),
       
   158 iWait(NULL),
       
   159 iObserver(NULL)
       
   160 {
       
   161     if (!iBuffer) {
       
   162         iBuffer = HBufC8::NewL(64);
       
   163         if (iBuffer) {
       
   164             iDataPtr.Set(iBuffer->Des());
       
   165         }
       
   166     }
       
   167 }
       
   168 
       
   169 CHbDeviceDialogPrivate::~CHbDeviceDialogPrivate()
       
   170 {
       
   171     // Inform the server to finish the dialog session and not to cancel it
       
   172     if(!iObserver) {
       
   173         iHbSession.SendSyncRequest(EHbSrvClientClosing);
       
   174     }
       
   175 
       
   176     Cancel();
       
   177     iHbSession.Close();
       
   178 
       
   179     delete iBuffer;
       
   180     iBuffer = NULL;
       
   181 
       
   182     iObserver= NULL;
       
   183     // stop synchorous calls
       
   184     if(iWait) {
       
   185         if( iWait->IsStarted() ) {
       
   186             iWait->AsyncStop();
       
   187         }
       
   188         delete iWait;
       
   189         iWait = NULL;
       
   190     }
       
   191 }
       
   192 
       
   193 TInt CHbDeviceDialogPrivate::Show(const QByteArray& aArray )
       
   194 {
       
   195     TInt error = iLastError = KErrNone;
       
   196 
       
   197     TPtrC8 ptr( reinterpret_cast<const TUint8*>(aArray.data()), aArray.size() );
       
   198     // Synchronous call to server to show dialog.
       
   199     error = iHbSession.SendSyncRequest( EHbSrvShowDeviceDialog, ptr, &iDeviceDialogId );
       
   200     //error = SymToDeviceDialogError(error);
       
   201 
       
   202     if (error == KErrNone) {
       
   203         // Start listening for server updates. Device dialog update and closing is
       
   204         // received via this channel. Error status received in RunL method.
       
   205         Start();
       
   206     }
       
   207     // Error, just return the error code
       
   208     else {
       
   209         SetError(error);
       
   210     }
       
   211     return error;
       
   212 }
       
   213 
       
   214 /*!
       
   215     \internal
       
   216 
       
   217     Send device dialog update.
       
   218 */
       
   219 TInt CHbDeviceDialogPrivate::Update( const QByteArray& aArray )
       
   220 {
       
   221     TInt error = iLastError = KErrNone;
       
   222     if (iRequesting) {
       
   223 
       
   224         TPtrC8 ptr( reinterpret_cast<const TUint8*>(aArray.data()), aArray.size() );
       
   225 
       
   226         error = iHbSession.SendSyncRequest( EHbSrvUpdateDeviceDialog, ptr );
       
   227         //error = SymToDeviceDialogError(error);
       
   228         if (error != KErrNone) {
       
   229             SetError(error);
       
   230         }
       
   231     }
       
   232     else {
       
   233         SetError(KErrBadHandle);
       
   234         error = KErrBadHandle;
       
   235     }
       
   236     return error;
       
   237 }
       
   238 
       
   239 /*!
       
   240     \internal
       
   241 
       
   242     Cancel a scheduled popup on HbDeviceDialogManager. Event buffer is cleared
       
   243     at server.
       
   244 */
       
   245 void CHbDeviceDialogPrivate::CancelDialog()
       
   246 {
       
   247     iLastError = KErrNone;
       
   248     int error = KErrNotFound;
       
   249 
       
   250     if (iRequesting) {
       
   251         // Ignore other than server errors.
       
   252         error = iHbSession.SendSyncRequest(EHbSrvCancelDeviceDialog, iDeviceDialogId());
       
   253         // error = SymToDeviceDialogError(error);
       
   254     }
       
   255     if (error != KErrNone) {
       
   256         SetError(error);
       
   257     }
       
   258 }
       
   259 
       
   260 /*!
       
   261     \internal
       
   262 
       
   263     Return last error.
       
   264 */
       
   265 TInt CHbDeviceDialogPrivate::Error() const
       
   266 {
       
   267     return iLastError;
       
   268 }
       
   269 
       
   270 void CHbDeviceDialogPrivate::SetObserver( MHbDeviceDialogObserver* aObserver )
       
   271 {
       
   272     iObserver = aObserver;
       
   273 }
       
   274 /*!
       
   275     \internal
       
   276     RunL from CActive.
       
   277 */
       
   278 void CHbDeviceDialogPrivate::RunL()
       
   279 {
       
   280     TInt completionCode = iStatus.Int();
       
   281     //int errorCode = SymToDeviceDialogError(completionCode);
       
   282 
       
   283     if (completionCode < KErrNone) {
       
   284         // Any Symbian error, stop requesting, sycnhoronous requests are stopped
       
   285         // in the end of the RunL
       
   286         iRequesting = EFalse;
       
   287         SetError(completionCode);
       
   288         if(iObserver) {
       
   289             iObserver->DeviceDialogClosed(completionCode);
       
   290         }
       
   291     }
       
   292     else {
       
   293         // Check that event is for latest device dialog. iDeviceDialogId was updated by server
       
   294         // during show()
       
   295         THbDeviceDialogSrvUpdateInfo &updateInfo = iUpdateInfo();
       
   296         if (updateInfo.iDeviceDialogId == iDeviceDialogId()) {
       
   297             switch(updateInfo.iUpdateType) {
       
   298             case EHbDeviceDialogUpdateData: {
       
   299                 if (completionCode == KErrNone &&
       
   300                     updateInfo.iInfo.iDataInfo.iDataSize > 0) {
       
   301                     // Resize buffer and get new data synchronously
       
   302                     delete iBuffer;
       
   303                     iBuffer = NULL;
       
   304                     iBuffer = HBufC8::NewL(updateInfo.iInfo.iDataInfo.iDataSize);
       
   305                     iDataPtr.Set(iBuffer->Des());
       
   306                     completionCode = iHbSession.SendSyncRequest(EHbSrvUpdateData, iDataPtr);
       
   307                     //errorCode = SymToDeviceDialogError(completionCode);
       
   308 
       
   309                     // data request failed
       
   310                     if (completionCode < KErrNone) {
       
   311                         iRequesting = EFalse;
       
   312                         SetError(completionCode);
       
   313                         if(iObserver) {
       
   314                             iObserver->DeviceDialogClosed(completionCode);
       
   315                         }
       
   316                     }
       
   317                 }
       
   318                 if (completionCode == KErrNone) {
       
   319                     // Signal data if there are connections. Otherwise keep a copy.
       
   320                     QByteArray resArray((const char*)iDataPtr.Ptr(), iDataPtr.Size());
       
   321                     QDataStream stream(&resArray, QIODevice::ReadOnly);
       
   322 
       
   323                     iDataReceived.clear();
       
   324 
       
   325                     QVariant var;
       
   326                     stream >> var;
       
   327                     QVariantMap varMap = var.toMap();
       
   328 
       
   329                     if(iObserver) {
       
   330                         CHbSymbianVariantMap* symbianMap =
       
   331                             HbSymbianVariantConverter::fromQVariantMapL(varMap);
       
   332                         iObserver->DataReceived(*symbianMap);
       
   333                         delete symbianMap;
       
   334                         symbianMap = 0;
       
   335                     }
       
   336                     else {
       
   337                         iDataReceived = varMap;
       
   338                     }
       
   339                 }
       
   340                 break;
       
   341             }
       
   342             case EHbDeviceDialogUpdateClosed:
       
   343                 // Signal possible cancelled error
       
   344                 if (completionCode != KErrNone) {
       
   345                     SetError(completionCode);
       
   346                 }
       
   347                 iRequesting = EFalse;
       
   348                 if(iObserver) {
       
   349                     iObserver->DeviceDialogClosed(completionCode);
       
   350                 }
       
   351                 break;
       
   352             default:
       
   353                 break;
       
   354             }
       
   355         }
       
   356     }
       
   357     // Make a new request if there was no errors and device dialog wasn't closed
       
   358     if (iRequesting) {
       
   359         Start();
       
   360     }
       
   361     else if (iWait && iWait->IsStarted()){
       
   362         // No requests going so stop
       
   363         iWait->AsyncStop();
       
   364     }
       
   365 }
       
   366 
       
   367 /*!
       
   368     \internal
       
   369     DoCancel from CActive.
       
   370 */
       
   371 void CHbDeviceDialogPrivate::DoCancel()
       
   372 {
       
   373     SetError(KErrCancel);
       
   374     iRequesting = EFalse;
       
   375     iHbSession.SendSyncRequest(EHbSrvCancelUpdateChannel);
       
   376     if(iObserver) {
       
   377         iObserver->DeviceDialogClosed(KErrCancel);
       
   378     }
       
   379 }
       
   380 
       
   381 /*!
       
   382     \internal
       
   383     RunError from CActive.
       
   384 */
       
   385 TInt CHbDeviceDialogPrivate::RunError( TInt /*aError*/ )
       
   386 {
       
   387     SetError( KErrGeneral );
       
   388     return KErrNone;
       
   389 }
       
   390 
       
   391 /*!
       
   392     \internal
       
   393     Starts asynchronous message to receive update and close events from session.
       
   394 */
       
   395 void CHbDeviceDialogPrivate::Start()
       
   396 {
       
   397     iDataPtr.Zero();
       
   398 
       
   399     if ( !IsActive() ) {
       
   400         iHbSession.SendASyncRequest( EHbSrvOpenUpdateChannel, iDataPtr, iUpdateInfo, iStatus );
       
   401         SetActive();
       
   402         iRequesting = ETrue;
       
   403     }
       
   404 }
       
   405 
       
   406 // Convert symbian error code into HbDeviceDialog error code
       
   407 int CHbDeviceDialogPrivate::SymToDeviceDialogError( TInt errorCode )
       
   408 {
       
   409     if (errorCode != HbDeviceDialogNoError) {
       
   410         // Any Symbian error, close session handle. It will be reopened on next show()
       
   411         if (errorCode < KErrNone) {
       
   412             iHbSession.Close();
       
   413         }
       
   414         // All Symbian errors are connected to HbDeviceDialogConnectError
       
   415         if (errorCode < KErrNone) {
       
   416             errorCode = HbDeviceDialogConnectError;
       
   417         }
       
   418     }
       
   419     return errorCode;
       
   420 }
       
   421 
       
   422 void CHbDeviceDialogPrivate::SetError( TInt aError )
       
   423 {
       
   424     iLastError = aError;
       
   425 }
       
   426 
       
   427 /*!
       
   428     Constructs CHbDeviceDialog object. \a f contains construct flags. Device
       
   429     dialog service will clean all dialogs launched when the instance is deleted.
       
   430 */
       
   431 
       
   432 EXPORT_C CHbDeviceDialog* CHbDeviceDialog::NewL( TInt aFlags )
       
   433 {
       
   434      CHbDeviceDialog* s60DeviceDialog = new CHbDeviceDialog(aFlags);
       
   435      int error = KErrNone;
       
   436      if(s60DeviceDialog->d) {
       
   437          error = s60DeviceDialog->d->iHbSession.Connect();
       
   438      }
       
   439      if(error != KErrNone) {
       
   440          CleanupStack::PushL(s60DeviceDialog);
       
   441          User::Leave(error);
       
   442          delete s60DeviceDialog;
       
   443          s60DeviceDialog = 0;
       
   444      }
       
   445      return s60DeviceDialog;
       
   446 }
       
   447 
       
   448 EXPORT_C CHbDeviceDialog::~CHbDeviceDialog()
       
   449 {
       
   450     delete d;
       
   451 }
       
   452 
       
   453 /*!
       
   454   Show of device dialog. aParameter data is sent to
       
   455   device dialog in Qt's QVariantMap object. The method call is synchronous if
       
   456   no observer is set. When aObserver is set, the call is asynchronous. Deleting
       
   457   the CHbDeviceDialog object does not cancel the call but leaves the plugin on the
       
   458   server to complete the session. Use  CHbDeviceDialog::Cancel to cancel the device
       
   459   dialog.
       
   460 
       
   461   \a aDeviceDialogType is name of the device dialog. Identifies the device
       
   462   dialog plugin. \a aParameters is a buffer containing data for the device dialog.
       
   463 
       
   464   \a aObserver is used to observe the session. If set, the call is asynchronous.
       
   465 
       
   466   Return value informs if the call was successful.
       
   467  */
       
   468 EXPORT_C TInt CHbDeviceDialog::Show(const TDesC& aDeviceDialogType, const CHbSymbianVariantMap& aParameters, MHbDeviceDialogObserver* aObserver)
       
   469 {
       
   470     d->SetObserver(aObserver);
       
   471 
       
   472     QString deviceDialogType = QString::fromUtf16(aDeviceDialogType.Ptr(), aDeviceDialogType.Length());
       
   473 
       
   474     QVariantMap parameters;
       
   475     HbSymbianVariantConverter::toQtVariantMap(aParameters, parameters);
       
   476 
       
   477     QByteArray array;
       
   478     QDataStream stream( &array, QIODevice::WriteOnly );
       
   479 
       
   480     QVariant var( parameters );
       
   481     stream << deviceDialogType;
       
   482     stream << var;
       
   483 
       
   484     return d->Show(array);
       
   485 }
       
   486 
       
   487 /*!
       
   488     Updates device dialog parameters by a set of new values. Show() must be called before an
       
   489     Update() can be called. Returns true on success and false
       
   490     if error occurred.
       
   491 
       
   492     \sa Show()
       
   493 */
       
   494 EXPORT_C TInt CHbDeviceDialog::Update(const CHbSymbianVariantMap& aParameters)
       
   495 {
       
   496     if(!d) {
       
   497         return KErrNotReady;
       
   498     }
       
   499     QVariantMap parameters;
       
   500 
       
   501     HbSymbianVariantConverter::toQtVariantMap(aParameters, parameters);
       
   502 
       
   503     QByteArray array;
       
   504     QDataStream stream( &array, QIODevice::WriteOnly );
       
   505 
       
   506     QVariant var( parameters );
       
   507     stream << var;
       
   508 
       
   509     return d->Update(array);
       
   510 }
       
   511 
       
   512 /*!
       
   513     Get the data received from device dialog if using synchronous Show
       
   514     in s60 data types. Caller gets the ownership.
       
   515 */
       
   516 EXPORT_C CHbSymbianVariantMap* CHbDeviceDialog::ReceivedDataL() const
       
   517 {
       
   518     CHbSymbianVariantMap* map = HbSymbianVariantConverter::fromQVariantMapL(d->iDataReceived);
       
   519     return map;
       
   520 }
       
   521 
       
   522 /*!
       
   523     Cancel device dialog session. Visible dialog is removed from the screen.
       
   524     Waiting dialogs are canceled and no effect if dialog already dismissed
       
   525 */
       
   526 EXPORT_C void CHbDeviceDialog::Cancel()
       
   527 {
       
   528     d->CancelDialog();
       
   529 }
       
   530 
       
   531 /*!
       
   532     Set observer for device dialog events. \aObserver is pointer to the
       
   533     observer. Null disables observing.
       
   534 */
       
   535 EXPORT_C void CHbDeviceDialog::SetObserver(MHbDeviceDialogObserver* aObserver)
       
   536 {
       
   537     d->SetObserver(aObserver);
       
   538 }
       
   539 
       
   540 CHbDeviceDialog::CHbDeviceDialog(TInt aFlags) : d(NULL)
       
   541 {
       
   542   d = new CHbDeviceDialogPrivate;
       
   543   d->iFlags = aFlags;
       
   544   CActiveScheduler::Add(d);
       
   545 
       
   546   // Is needed to implement?
       
   547   //if (mDeviceDialogFlags & HbDeviceDialog::ImmediateResourceReservationFlag)
       
   548 }