src/hbcore/devicedialogbase/devicedialogserver/hbdevicedialogsession.cpp
changeset 0 16d8024aca5e
child 3 11d3954df52a
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 <QByteArray>
       
    27 #include <qlist.h>
       
    28 #include <qdatastream.h>
       
    29 #include <hbdevicedialogtrace_p.h>
       
    30 #include <hbdevicedialogerrors_p.h>
       
    31 #include "hbdevicedialogsession_p.h"
       
    32 #include "hbdevicedialogserver_p.h"
       
    33 #include "hbdevicedialogserversym_p_p.h"
       
    34 #include "hbdevicedialogserverdefs_p.h"
       
    35 #include "hbindicatorsessionhandler_p.h"
       
    36 #include <e32base.h>
       
    37 
       
    38 /*!
       
    39     HbDeviceDialogSession
       
    40     \internal
       
    41 */
       
    42 
       
    43 /*!
       
    44     \internal
       
    45 */
       
    46 HbDeviceDialogSession* HbDeviceDialogSession::NewL()
       
    47 {
       
    48     TRACE_STATIC_ENTRY
       
    49     HbDeviceDialogSession* session = new (ELeave) HbDeviceDialogSession;
       
    50     TRACE_EXIT
       
    51     return session;
       
    52 }
       
    53 
       
    54 /*!
       
    55     \internal
       
    56 */
       
    57 HbDeviceDialogSession::~HbDeviceDialogSession()
       
    58 {
       
    59     TRACE_ENTRY
       
    60     Server().deviceDialogClientClosing(reinterpret_cast<quintptr>(this));
       
    61     // Session has closed
       
    62     Server().RemoveSessionFromList( this );
       
    63     mEventList.clear();
       
    64     if (!iKeepAfterClose) {
       
    65         for (int i(0); i < mIdList.count(); i++ ) {
       
    66             Server().closeDeviceDialog( mIdList[i] );
       
    67         }
       
    68         mIdList.clear();
       
    69         if (!iUpdateChannel.IsNull()) {
       
    70             iUpdateChannel.Complete(KErrBadHandle);
       
    71         }
       
    72     }
       
    73     delete iIndicatorSessionHandler;
       
    74     Server().RemoveSession();
       
    75     TRACE_EXIT
       
    76 }
       
    77 
       
    78 /*!
       
    79     \internal
       
    80     Update server session counter.
       
    81 */
       
    82 void HbDeviceDialogSession::CreateL()
       
    83 {
       
    84     TRACE_ENTRY
       
    85     Server().AddSession();
       
    86     TRACE_EXIT
       
    87 }
       
    88 
       
    89 /*!
       
    90     \internal
       
    91     Handles the servicing of a client request that has been passed
       
    92     to the server.
       
    93 */
       
    94 void HbDeviceDialogSession::ServiceL(const RMessage2& aMessage)
       
    95 {
       
    96     TRACE_ENTRY
       
    97     // If ServiceL leaves, default implementation in server framework
       
    98     // completes the RMessage2 with the leave code.
       
    99     DispatchMessageL( aMessage );
       
   100     TRACE_EXIT
       
   101 }
       
   102 
       
   103 /*!
       
   104     \internal
       
   105     Handles the servicing of a client request that has been passed
       
   106     to the server.
       
   107 */
       
   108 void HbDeviceDialogSession::DispatchMessageL( const RMessage2 &aMessage )
       
   109 {
       
   110     TRACE_ENTRY
       
   111     TInt function = aMessage.Function();
       
   112     if (function > EHbSrvIndicatorCommandsStart
       
   113         && function < EHbSrvIndicatorCommandsEnd) {
       
   114         if (!iIndicatorSessionHandler) {
       
   115             iIndicatorSessionHandler = HbIndicatorSessionHandler::NewL(this);
       
   116         }
       
   117         iIndicatorSessionHandler->HandleMessageL(aMessage);
       
   118         return;
       
   119 
       
   120     }
       
   121     switch( function ) {
       
   122 
       
   123     case EHbSrvShowDeviceDialog: {
       
   124         ShowDeviceDialogL( aMessage );
       
   125         break;
       
   126     }
       
   127 
       
   128     case EHbSrvUpdateDeviceDialog: {
       
   129         UpdateDeviceDialogL( aMessage );
       
   130         break;
       
   131     }
       
   132 
       
   133     case EHbSrvClientClosing: {
       
   134         ClientClosing( aMessage );
       
   135         break;
       
   136     }
       
   137 
       
   138     case EHbSrvCancelUpdateChannel: {
       
   139         CancelUpdateChannel(aMessage);
       
   140         break;
       
   141     }
       
   142 
       
   143     case EHbSrvCancelDeviceDialog: {
       
   144         CancelDeviceDialog( aMessage );
       
   145         break;
       
   146     }
       
   147 
       
   148     case EHbSrvOpenUpdateChannel: {
       
   149         UpdateChannelRequestL( aMessage );
       
   150         break;
       
   151     }
       
   152 
       
   153     case EHbSrvUpdateData: {
       
   154         UpdateDataRequestL( aMessage );
       
   155         break;
       
   156     }
       
   157 
       
   158     default: {
       
   159         break;
       
   160     }
       
   161 
       
   162     }; // end switch
       
   163     TRACE_EXIT
       
   164 }
       
   165 
       
   166 /*!
       
   167     \internal
       
   168     Returns device dialog identifier stored to this session. Used to identify correct
       
   169     client.
       
   170 */
       
   171 int HbDeviceDialogSession::DeviceDialogIdentifier() const
       
   172 {
       
   173     TRACE_ENTRY
       
   174     int identifier(0);
       
   175 
       
   176     if ( !mIdList.isEmpty() ) {
       
   177         identifier = mIdList.first();
       
   178     }
       
   179     TRACE_EXIT_ARGS("identifier" << identifier)
       
   180     return identifier;
       
   181 }
       
   182 
       
   183 /*!
       
   184     \internal
       
   185     Handle device dialog update event.
       
   186 */
       
   187 void HbDeviceDialogSession::DeviceDialogUpdate( const QVariantMap& parameters )
       
   188 {
       
   189     TRACE_ENTRY
       
   190     int id = DeviceDialogIdentifier();
       
   191     if (id) {
       
   192         WriteUpdateData(parameters, id);
       
   193     }
       
   194     TRACE_EXIT
       
   195 }
       
   196 
       
   197 /*!
       
   198     \internal
       
   199     Handle device dialog close event.
       
   200 */
       
   201 void HbDeviceDialogSession::DeviceDialogClosed( TInt identifier, TInt closeReason )
       
   202 {
       
   203     TRACE_ENTRY
       
   204     Q_ASSERT(identifier != 0);
       
   205     if (mIdList.startsWith(identifier)) {
       
   206         if (iUpdateChannelOpen && mEventList.count() == 0) {
       
   207             WriteCloseData(identifier, closeReason);
       
   208         } else {
       
   209             iWriteCloseId = identifier;
       
   210             iWriteCloseReason = closeReason;
       
   211         }
       
   212     }
       
   213     mIdList.removeOne( identifier );
       
   214     TRACE_EXIT
       
   215 }
       
   216 
       
   217 /*!
       
   218     \internal
       
   219 */
       
   220 HbDeviceDialogServerPrivate& HbDeviceDialogSession::Server()
       
   221 {
       
   222     return *static_cast<HbDeviceDialogServerPrivate*>(const_cast<CServer2*>(CSession2::Server()));
       
   223 }
       
   224 
       
   225 /*!
       
   226     \internal
       
   227     Client has closed session.
       
   228 */
       
   229 void HbDeviceDialogSession::Disconnect( const RMessage2& aMessage )
       
   230 {
       
   231     TRACE_ENTRY
       
   232     CSession2::Disconnect( aMessage );
       
   233     TRACE_EXIT
       
   234 }
       
   235 
       
   236 /*!
       
   237     \internal
       
   238     Forward call to HbDeviceDialogManager. Store dialog id if call is successful.
       
   239 */
       
   240 void HbDeviceDialogSession::ShowDeviceDialogL( const RMessage2 &aMessage )
       
   241 {
       
   242     TRACE_ENTRY
       
   243     mEventList.clear();
       
   244     iKeepAfterClose = EFalse;
       
   245     iWriteCloseId = 0;
       
   246     TInt dataSize = aMessage.GetDesLength( KSlot0 );
       
   247 
       
   248     if (dataSize < 0) {
       
   249         User::Leave(KErrBadDescriptor);
       
   250     }
       
   251 
       
   252     HBufC8* data = HBufC8::NewLC( dataSize );
       
   253     TPtr8 ptr( data->Des() );
       
   254     aMessage.ReadL( KSlot0, ptr );
       
   255 
       
   256     QByteArray resArray( (const char*) ptr.Ptr(), ptr.Size() );
       
   257     QDataStream outStream( &resArray, QIODevice::ReadOnly );
       
   258     QString title;
       
   259 
       
   260     QVariant var;
       
   261     outStream >> title;
       
   262     outStream >> var;
       
   263 
       
   264     QVariantMap mapdata = var.toMap();
       
   265 
       
   266     CleanupStack::PopAndDestroy( data );
       
   267 
       
   268     int identifier = 0;
       
   269     int error = Server().AddSessionToList(this);
       
   270     if (error == HbDeviceDialogNoError) {
       
   271         HbDeviceDialogServer::DialogParameters showParameters(title, aMessage, mapdata,
       
   272             reinterpret_cast<quintptr>(this));
       
   273         identifier = Server().showDeviceDialog(showParameters);
       
   274         error = showParameters.mError;
       
   275         if (error != HbDeviceDialogNoError) {
       
   276             Server().RemoveSessionFromList(this);
       
   277         }
       
   278     }
       
   279 
       
   280     if (error == HbDeviceDialogNoError) {
       
   281         TPckgBuf<int> deviceDialogId(identifier);
       
   282         error = aMessage.Write(KSlot1, deviceDialogId);
       
   283         aMessage.Complete(error);
       
   284         mIdList.insert(0, identifier);
       
   285     } else {
       
   286         aMessage.Complete(error);
       
   287     }
       
   288     TRACE_EXIT_ARGS("identifier " << identifier)
       
   289 }
       
   290 
       
   291 /*!
       
   292     \internal
       
   293     Forward call to HbDeviceDialogManager. Return result.
       
   294 */
       
   295 void HbDeviceDialogSession::UpdateDeviceDialogL( const RMessage2 &aMessage )
       
   296 {
       
   297     TRACE_ENTRY
       
   298     TInt dataSize = aMessage.GetDesLength( KSlot0 );
       
   299 
       
   300     if (dataSize < 0) {
       
   301         User::Leave(KErrBadDescriptor);
       
   302     }
       
   303 
       
   304     HBufC8* data = HBufC8::NewLC( dataSize );
       
   305     TPtr8 ptr( data->Des() );
       
   306     aMessage.ReadL( KSlot0, ptr );
       
   307 
       
   308     QByteArray resArray( (const char*) ptr.Ptr(), ptr.Size() );
       
   309     QDataStream outStream( &resArray, QIODevice::ReadOnly );
       
   310 
       
   311     QVariant var;
       
   312     outStream >> var;
       
   313 
       
   314     QVariantMap mapdata = var.toMap();
       
   315 
       
   316     CleanupStack::PopAndDestroy( data );
       
   317 
       
   318     TInt result = Server().updateDeviceDialog( DeviceDialogIdentifier(), mapdata );
       
   319     aMessage.Complete( result );
       
   320     TRACE_EXIT_ARGS("result " << result)
       
   321 }
       
   322 
       
   323 /*!
       
   324     \internal
       
   325     Forward call to HbDeviceDialogManager. Return result.
       
   326 */
       
   327 void HbDeviceDialogSession::CancelDeviceDialog( const RMessage2 &aMessage )
       
   328 {
       
   329     TRACE_ENTRY
       
   330     TInt result = KErrNone;
       
   331     // Check that cancel is for most recent device dialog from this session
       
   332     int id = DeviceDialogIdentifier();
       
   333     if (id == aMessage.Int0()) {
       
   334         result = Server().closeDeviceDialog(id);
       
   335     }
       
   336 
       
   337     aMessage.Complete(result);
       
   338     TRACE_EXIT_ARGS("result " << result)
       
   339 }
       
   340 
       
   341 /*!
       
   342     \internal
       
   343     Client is about to be deleted and requests to keep device dialogs alive
       
   344     after session closes.
       
   345 */
       
   346 void HbDeviceDialogSession::ClientClosing( const RMessage2 &aMessage )
       
   347     {
       
   348     TRACE_ENTRY
       
   349     iKeepAfterClose = true;
       
   350     aMessage.Complete(KErrNone);
       
   351     TRACE_EXIT
       
   352     }
       
   353 
       
   354 /*!
       
   355     \internal
       
   356     Store asynchronous request from client.
       
   357 */
       
   358 void HbDeviceDialogSession::UpdateChannelRequestL( const RMessage2 &aMessage )
       
   359 {
       
   360     TRACE_ENTRY
       
   361     // We have a pending request
       
   362     iUpdateChannelOpen = ETrue;
       
   363 
       
   364     // Store message for later completion
       
   365     iUpdateChannel = aMessage;
       
   366 
       
   367     // Check if we have buffered data and complete right away.
       
   368     // Data is buffered if client is to be notified, but has
       
   369     // not made a new request for device dialog (processing the
       
   370     // previous message).
       
   371     if ( mEventList.count() > 0 ) {
       
   372         QVariantMap data = mEventList[0];
       
   373 
       
   374         WriteUpdateData(data, mIdList.isEmpty() ? 0 : mIdList.first());
       
   375         mEventList.removeFirst();
       
   376     } else if (iWriteCloseId) {
       
   377         WriteCloseData(iWriteCloseId, iWriteCloseReason);
       
   378     } else {
       
   379         iUpdateChannelOpen = ETrue;
       
   380     }
       
   381     TRACE_EXIT
       
   382 }
       
   383 
       
   384 /*!
       
   385     \internal
       
   386     Complete client synchronous request in device dialog initiated events. Called
       
   387     if client buffer has been too small to receive data.
       
   388 */
       
   389 void HbDeviceDialogSession::UpdateDataRequestL( const RMessage2 &aMessage )
       
   390 {
       
   391     TRACE_ENTRY
       
   392 
       
   393     TInt error = KErrNotFound;
       
   394     if (mEventList.count()) {
       
   395 
       
   396         QVariantMap data = mEventList[0];
       
   397 
       
   398         QByteArray array;
       
   399         QDataStream stream( &array, QIODevice::WriteOnly );
       
   400 
       
   401         QVariant var(data);
       
   402         stream << var;
       
   403 
       
   404         TPtr8 ptr( reinterpret_cast<TUint8*>(array.data()), array.size(), array.size());
       
   405 
       
   406         error = aMessage.Write( KSlot0, ptr );
       
   407 
       
   408         if ( error == KErrNone) {
       
   409             mEventList.removeFirst();
       
   410         }
       
   411     }
       
   412     aMessage.Complete( error );
       
   413     TRACE_EXIT_ARGS("error " << error)
       
   414 }
       
   415 
       
   416 /*!
       
   417     \internal
       
   418     Cancel update channel request.
       
   419 */
       
   420 void HbDeviceDialogSession::CancelUpdateChannel(const RMessage2 aMessage)
       
   421 {
       
   422     if (iUpdateChannelOpen) {
       
   423         // Complete update request
       
   424         iUpdateChannelOpen = EFalse;
       
   425 
       
   426         THbDeviceDialogSrvUpdateInfo updateInfo;
       
   427         TPckgBuf<THbDeviceDialogSrvUpdateInfo> updateInfoBuf(updateInfo);
       
   428         int error = iUpdateChannel.Write(KSlot1, updateInfoBuf);
       
   429         iUpdateChannel.Complete(error);
       
   430     }
       
   431     aMessage.Complete(KErrNone);
       
   432 }
       
   433 
       
   434 /*!
       
   435     \internal
       
   436     Complete client synchronous request in device dialog initiated events.
       
   437 */
       
   438 void HbDeviceDialogSession::WriteUpdateData(const QVariantMap &parameters, int deviceDialogId)
       
   439 {
       
   440     TRACE_ENTRY
       
   441     if ( iUpdateChannelOpen ) {
       
   442         // Client is listening and ready to receive data
       
   443         iUpdateChannelOpen = EFalse;
       
   444 
       
   445         // Get client data buffer size.
       
   446         TInt size = iUpdateChannel.GetDesMaxLength( KSlot0 );
       
   447 
       
   448         QByteArray array;
       
   449         QDataStream stream( &array, QIODevice::WriteOnly );
       
   450 
       
   451         QVariant var(parameters);
       
   452         stream << var;
       
   453 
       
   454         THbDeviceDialogSrvUpdateInfo updateInfo(EHbDeviceDialogUpdateData, deviceDialogId);
       
   455         updateInfo.iInfo.iDataInfo.iDataSize = 0;
       
   456         TPckgBuf<THbDeviceDialogSrvUpdateInfo> updateInfoBuf(updateInfo);
       
   457 
       
   458         if ( size >= array.size() ) {
       
   459             // Buffer size ok. Write data.
       
   460             TPtr8 ptr( reinterpret_cast<TUint8*>(array.data()), array.size(), array.size());
       
   461             TInt error = iUpdateChannel.Write( KSlot0, ptr );
       
   462 
       
   463             if (error == KErrNone) {
       
   464                 error = iUpdateChannel.Write(KSlot1, updateInfoBuf);
       
   465             }
       
   466             iUpdateChannel.Complete( error );
       
   467         } else {
       
   468             // Client buffer size too small. Buffer data and complete request later
       
   469             // with correct data size after client has resized it's data buffer.
       
   470             // Complete message with correct data size. Client asks data synchronously.
       
   471             mEventList.append( parameters );
       
   472             updateInfoBuf().iInfo.iDataInfo.iDataSize = array.size();
       
   473             TInt error = iUpdateChannel.Write( KSlot1, updateInfoBuf );
       
   474             iUpdateChannel.Complete(error);
       
   475         }
       
   476     } else {
       
   477         // Client busy. Buffer message for next request.
       
   478         mEventList.append( parameters );
       
   479     }
       
   480     TRACE_EXIT
       
   481 }
       
   482 
       
   483 /*!
       
   484     \internal
       
   485     Complete client synchronous request in device dialog initiated events.
       
   486 */
       
   487 int HbDeviceDialogSession::WriteCloseData(int deviceDialogId, int closeReason)
       
   488 {
       
   489     TRACE_ENTRY
       
   490     iUpdateChannelOpen = EFalse;
       
   491 
       
   492     THbDeviceDialogSrvUpdateInfo updateInfo(EHbDeviceDialogUpdateClosed, deviceDialogId);
       
   493 
       
   494     TPckgBuf<THbDeviceDialogSrvUpdateInfo> updateInfoBuf(updateInfo);
       
   495     TInt error = iUpdateChannel.Write(KSlot1, updateInfoBuf);
       
   496     iUpdateChannel.Complete(error != HbDeviceDialogNoError ? error : closeReason);
       
   497     TRACE_EXIT_ARGS("error" << error)
       
   498     return error;
       
   499 }
       
   500 
       
   501 /*!
       
   502     \internal
       
   503 */
       
   504 HbDeviceDialogSession::HbDeviceDialogSession()
       
   505 {
       
   506     TRACE_ENTRY
       
   507     iKeepAfterClose = false;
       
   508     iWriteCloseId = 0;
       
   509     iWriteCloseReason = HbDeviceDialogNoError;
       
   510     iUpdateChannelOpen = false;
       
   511     iIndicatorSessionHandler = 0;
       
   512     TRACE_EXIT
       
   513 }