src/hbcore/devicedialogbase/hbdevicedialogsym_p.cpp
changeset 0 16d8024aca5e
child 5 627c4a0fd0e7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbcore/devicedialogbase/hbdevicedialogsym_p.cpp	Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,432 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbCore module of the UI Extensions for Mobile.
+**
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+
+#include "hbdevicedialogsym_p.h"
+#include "hbdevicedialogerrors_p.h"
+#include <QVariant>
+#include <QPointer>
+#include <e32base.h>
+#include <hbdevicedialogserverdefs_p.h>
+#include <hbdevicedialogtrace_p.h>
+
+/*!
+    \class HbDeviceDialogPrivate
+    \internal
+*/
+
+/*!
+    \internal
+*/
+HbDeviceDialogPrivate::HbDeviceDialogPrivate()
+: CActive(EPriorityStandard),
+    iDeviceDialogId(0),
+    iBuffer(NULL),
+    iDataPtr(NULL, 0, 0),
+    mEventLoop(0)
+{
+    TRACE_ENTRY
+    TRACE_EXIT
+}
+
+/*!
+    \internal
+*/
+HbDeviceDialogPrivate::~HbDeviceDialogPrivate()
+{
+    TRACE_ENTRY
+    // If there are no signals connected or waitForClosed() is not executing, inform server
+    // the client is closing. The server will keep device dialogs. Otherwise server closes
+    // device dialogs when client session closes.
+    if (receiverCount() == 0 && mEventLoop == 0) {
+        mHbSession.SendSyncRequest(EHbSrvClientClosing);
+    }
+    Cancel();
+    delete iBuffer;
+    mHbSession.Close();
+    if (mEventLoop && mEventLoop->isRunning()) {
+        mEventLoop->exit(HbDeviceDialog::CancelledError);
+    }
+    TRACE_EXIT
+}
+
+/*!
+    \internal
+    Initialisation step.
+*/
+void HbDeviceDialogPrivate::init(HbDeviceDialog::DeviceDialogFlags f)
+{
+    TRACE_ENTRY
+    mDeviceDialogFlags = f;
+    mLastError = HbDeviceDialogNoError;
+    CActiveScheduler::Add(this);
+    iRequesting = EFalse;
+    if (mDeviceDialogFlags & HbDeviceDialog::ImmediateResourceReservationFlag) {
+        int error = symToDeviceDialogError(initialize());
+        if (error != HbDeviceDialogNoError){
+            setError(error);
+        }
+    }
+    TRACE_EXIT
+}
+
+/*!
+    \internal
+    Initialisation step. Session to server is created.
+*/
+int HbDeviceDialogPrivate::initialize()
+{
+    TRACE_ENTRY
+
+    if (!iBuffer) {
+        iBuffer = HBufC8::NewL(64);
+        if (iBuffer) {
+            iDataPtr.Set(iBuffer->Des());
+        } else {
+          TRACE_EXIT_ARGS("error " << KErrNoMemory)
+            return KErrNoMemory;
+        }
+    }
+    int error = mHbSession.Connect();
+    TRACE_EXIT_ARGS("error" << error)
+    return error;
+}
+
+/*!
+    \internal
+
+    Device dialog plugin identifier and data send to device dialog server. On
+    success received device dialog id is stored.
+*/
+bool HbDeviceDialogPrivate::show(
+    const QString &deviceDialogType,
+    const QVariantMap &parameters)
+{
+    TRACE_ENTRY
+    mLastError = HbDeviceDialogNoError;
+    mDataReceived.clear();
+
+    int error = symToDeviceDialogError(initialize());
+    if (error != HbDeviceDialogNoError){
+        setError(error);
+        TRACE_EXIT_ARGS("error " << error)
+        return false;
+    }
+
+    QByteArray array;
+    QDataStream stream(&array, QIODevice::WriteOnly);
+
+    QVariant var(parameters);
+    stream << deviceDialogType;
+    stream << var;
+
+    TPtrC8 ptr(reinterpret_cast<TUint8*>(array.data()), array.size());
+
+    // Synchronous call to server to show dialog.
+    error = mHbSession.SendSyncRequest(EHbSrvShowDeviceDialog, ptr, &iDeviceDialogId);
+    error = symToDeviceDialogError(error);
+    bool result(true);
+
+    if (error != HbDeviceDialogNoError) {
+        setError(error);
+        result = false;
+    } else {
+        // Start listening for server updates. Device dialog update and closing is
+        // received via this channel. Error status received in RunL method.
+        Start();
+    }
+    TRACE_EXIT_ARGS("result" << result)
+    return result;
+}
+
+/*!
+    \internal
+
+    Send device dialog update.
+*/
+bool HbDeviceDialogPrivate::update(const QVariantMap& parameters)
+{
+    TRACE_ENTRY
+    mLastError = HbDeviceDialogNoError;
+    bool result(true);
+    if (iRequesting) {
+
+        QByteArray array;
+        QDataStream stream(&array, QIODevice::WriteOnly);
+
+        QVariant var(parameters);
+        stream << var;
+
+        TPtrC8 ptr(reinterpret_cast<TUint8*>(array.data()), array.size());
+
+        int error = mHbSession.SendSyncRequest(EHbSrvUpdateDeviceDialog, ptr);
+        error = symToDeviceDialogError(error);
+        if (error != HbDeviceDialogNoError) {
+            setError(error);
+            result = false;
+        }
+    } else {
+        setError(HbDeviceDialogIllegalOperationError);
+        result = false;
+
+    }
+    TRACE_EXIT_ARGS("result" << result)
+    return result;
+}
+
+/*!
+    \internal
+
+    Cancel a scheduled popup on HbDeviceDialogManager. Event buffer is cleared
+    at server.
+*/
+bool HbDeviceDialogPrivate::cancel()
+{
+    TRACE_ENTRY
+    mLastError = HbDeviceDialogNoError;
+    int error = HbDeviceDialogNotFoundError;
+
+    if (iRequesting) {
+        // Ignore other than server errors.
+        error = mHbSession.SendSyncRequest(EHbSrvCancelDeviceDialog, iDeviceDialogId());
+        error = symToDeviceDialogError(error);
+    }
+    if (error != HbDeviceDialogNoError) {
+        setError(error);
+    }
+    bool result = (error == HbDeviceDialogNoError);
+    TRACE_EXIT_ARGS("result" << result)
+    return result;
+}
+
+/*!
+    \internal
+
+    Start wait for the close event sent by server.
+*/
+bool HbDeviceDialogPrivate::waitForClosed(QEventLoop::ProcessEventsFlag flags)
+{
+    TRACE_ENTRY
+    mLastError = HbDeviceDialogNoError;
+    int error = HbDeviceDialogNoError;
+
+    if (iRequesting && !mEventLoop) {
+        QPointer<HbDeviceDialog> guard = q_ptr;
+        QEventLoop eventLoop;
+        mEventLoop = &eventLoop;
+        error = eventLoop.exec(flags);
+        error = symToDeviceDialogError(error);
+        if (guard.isNull()) {
+            return false;
+        }
+        mEventLoop = 0;
+    } else {
+        error = HbDeviceDialogGeneralError;
+    }
+
+    bool result(true);
+
+    if (error != HbDeviceDialogNoError) {
+        setError(error);
+        result = false;
+    }
+    TRACE_EXIT_ARGS("result" << result)
+    return result;
+}
+
+/*!
+    \internal
+
+    Return last received data from device dialog.
+*/
+QVariantMap HbDeviceDialogPrivate::receivedData() const
+{
+    TRACE_ENTRY
+    return mDataReceived;
+}
+
+/*!
+    \internal
+
+    Set and notify error status.
+*/
+void HbDeviceDialogPrivate::setError(int error)
+{
+    TRACE_ENTRY_ARGS("error" << error)
+    mLastError = error;
+    emit q_func()->error(error);
+    TRACE_EXIT
+}
+
+/*!
+    \internal
+
+    Return last error.
+*/
+int HbDeviceDialogPrivate::error() const
+{
+    TRACE_ENTRY
+    return mLastError;
+}
+
+/*!
+    \internal
+    RunL from CActive.
+*/
+void HbDeviceDialogPrivate::RunL()
+{
+    TRACE_ENTRY
+    TInt completionCode = iStatus.Int();
+    int errorCode = symToDeviceDialogError(completionCode);
+
+    if (completionCode < KErrNone) {
+        // Any Symbian error, stop requesting
+        iRequesting = EFalse;
+        setError(errorCode);
+    } else {
+        // Check that event is for latest device dialog. iDeviceDialogId was updated by server
+        // during show()
+        THbDeviceDialogSrvUpdateInfo &updateInfo = iUpdateInfo();
+        if (updateInfo.iDeviceDialogId == iDeviceDialogId()) {
+            switch(updateInfo.iUpdateType) {
+            case EHbDeviceDialogUpdateData: {
+                if (completionCode == HbDeviceDialogNoError &&
+                    updateInfo.iInfo.iDataInfo.iDataSize > 0) {
+                    // Resize buffer and get new data synchronously
+                    delete iBuffer;
+                    iBuffer = NULL;
+                    iBuffer = HBufC8::NewL(updateInfo.iInfo.iDataInfo.iDataSize);
+                    iDataPtr.Set(iBuffer->Des());
+                    completionCode = mHbSession.SendSyncRequest(EHbSrvUpdateData, iDataPtr);
+                    errorCode = symToDeviceDialogError(completionCode);
+                    if (completionCode < KErrNone) {
+                        iRequesting = EFalse;
+                        setError(errorCode);
+                    }
+                }
+                if (completionCode == HbDeviceDialogNoError) {
+                    // Signal data if there are connections. Otherwise keep a copy.
+                    QByteArray resArray((const char*)iDataPtr.Ptr(), iDataPtr.Size());
+                    QDataStream stream(&resArray, QIODevice::ReadOnly);
+
+                    mDataReceived.clear();
+                    QVariant var;
+                    stream >> var;
+
+                    if (q_ptr->receivers(SIGNAL(dataReceived(QVariantMap))) > 0) {
+                        emit q_func()->dataReceived(var.toMap());
+                    } else {
+                        mDataReceived = var.toMap();
+                    }
+                }
+                break;
+            }
+            case EHbDeviceDialogUpdateClosed:
+                // Signal possible cancelled error
+                if (errorCode != HbDeviceDialogNoError) {
+                    setError(errorCode);
+                }
+                emit q_func()->deviceDialogClosed();
+                iRequesting = EFalse;
+                break;
+            default:
+                break;
+            }
+        }
+    }
+    // Make a new request if there was no errors and device dialog wasn't closed
+    if (iRequesting) {
+        Start();
+    } else {
+        if (mEventLoop && mEventLoop->isRunning()) {
+            mEventLoop->exit(errorCode);
+        }
+    }
+    TRACE_EXIT
+}
+
+/*!
+    \internal
+    DoCancel from CActive.
+*/
+void HbDeviceDialogPrivate::DoCancel()
+{
+    TRACE_ENTRY
+    iRequesting = EFalse;
+    mHbSession.SendSyncRequest(EHbSrvCancelUpdateChannel);
+    TRACE_EXIT
+}
+
+/*!
+    \internal
+    RunError from CActive.
+*/
+TInt HbDeviceDialogPrivate::RunError(TInt /*aError*/)
+{
+    TRACE_ENTRY
+    setError(HbDeviceDialogGeneralError);
+    TRACE_EXIT
+    return KErrNone;
+}
+
+/*!
+    \internal
+    Starts asynchronous message to receive update and close events from session.
+*/
+void HbDeviceDialogPrivate::Start()
+{
+    TRACE_ENTRY
+    iDataPtr.Zero();
+
+    if (!IsActive()) {
+        mHbSession.SendASyncRequest(EHbSrvOpenUpdateChannel, iDataPtr, iUpdateInfo, iStatus);
+        SetActive();
+        iRequesting = ETrue;
+    }
+    TRACE_EXIT
+}
+
+int HbDeviceDialogPrivate::receiverCount()
+{
+    int receiverCount(0);
+    receiverCount += q_ptr->receivers(SIGNAL(dataReceived(QVariantMap)));
+    receiverCount += q_ptr->receivers(SIGNAL(deviceDialogClosed()));
+    return receiverCount;
+}
+
+// Convert symbian error code into HbDeviceDialog error code
+int HbDeviceDialogPrivate::symToDeviceDialogError(int errorCode)
+{
+    if (errorCode != HbDeviceDialogNoError) {
+        // Any Symbian error, close session handle. It will be reopened on next show()
+        if (errorCode < KErrNone) {
+            mHbSession.Close();
+        }
+        // All Symbian errors are connected to HbDeviceDialogConnectError
+        if (errorCode < KErrNone) {
+            errorCode = HbDeviceDialogConnectError;
+        }
+    }
+    return errorCode;
+}