qthighway/examples/appmgrclient/src/appmgrclient.cpp
branchRCL_3
changeset 9 5d007b20cfd0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qthighway/examples/appmgrclient/src/appmgrclient.cpp	Tue Aug 31 16:02:37 2010 +0300
@@ -0,0 +1,1266 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, version 2.1 of the License.
+* 
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, 
+* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
+*
+* Description:
+*
+*/
+
+#include <QtGlobal>
+#include <QApplication>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QStackedWidget>
+#include <QImageReader>
+#include <QDebug>
+#include <QTimer>
+#include <QPushButton>
+#include <QList>
+#include <QLineEdit>
+#include <QString>
+#include <QCheckBox>
+#include <QAction>
+#include <QListView>
+#include <QUrl>
+#include <QFileInfo>
+#include <math.h>
+#include <QCompleter>
+#include <xqserviceglobal.h>
+#include <QDir>
+#include <QTranslator>
+#include <cntservicescontact.h>
+
+#include <XQSharableFile.h>
+
+// Include declarations to see if any compilation issues
+#include <xqaiwdecl.h>
+#include <xqaiwdeclplat.h>
+
+#include "appmgrservices.h"
+#include "appmgrclient.h"
+
+
+//
+// TODO: Better UI for test cases which allows
+// more test cases.
+//
+AppMgrClient::AppMgrClient(QWidget *parent, Qt::WFlags f)
+    : QWidget(parent, f),
+      actionButton(0),
+      req1(0),
+      req2(0),
+      req3(0),
+      req4(0),
+      req5(0),
+      req6(0),
+      req7(0),
+      req8(0),
+      req9(0),
+      req10(0),
+      anyReq(0),
+      mImplIndex(0)      
+{
+    /* Adjust the palette */
+#if defined(Q_WS_S60)
+    QPalette p = qApp->palette();
+    QColor color(192,192,192);
+    QColor bg(0,128,192);
+    p.setColor(QPalette::Highlight, color.lighter(200));
+    p.setColor(QPalette::Text, Qt::black);
+    p.setColor(QPalette::Base, bg);
+    p.setColor(QPalette::WindowText, Qt::black);
+    p.setColor(QPalette::Window, bg);
+    p.setColor(QPalette::ButtonText, Qt::black);
+    p.setColor(QPalette::Button, color.lighter(150));
+    p.setColor(QPalette::Link, QColor(240,40,40));
+    qApp->setPalette(p);
+#endif
+
+    QPushButton *quitButton = new QPushButton(tr("quit"));
+    connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
+
+    
+    QPushButton *testButton1 = 0;
+    QPushButton *anyTestButton = 0;
+
+    testButton1 = new QPushButton("Tests");
+    mMenu = new QMenu(this);
+    testButton1->setMenu(mMenu);
+    anyTestButton = new QPushButton(tr("Any test"));
+    connect(anyTestButton, SIGNAL(clicked()), this, SLOT(anyTest()));
+
+    QAction *test1 = new QAction("1:Interface", this);
+    connect(test1, SIGNAL(triggered()), this, SLOT(test1()));
+    QAction *test2 = new QAction("2:Descriptor", this);
+    connect(test2, SIGNAL(triggered()), this, SLOT(test2()));
+    QAction *test3 = new QAction("3:Big data", this);
+    connect(test3, SIGNAL(triggered()), this, SLOT(test3()));
+    QAction *test4 = new QAction("4:QAction", this);
+    connect(test4, SIGNAL(triggered()), this, SLOT(test4()));
+    QAction *test5 = new QAction("5:appto:", this);
+    connect(test5, SIGNAL(triggered()), this, SLOT(test5()));
+    QAction *test6 = new QAction("6:testto:", this);
+   connect(test6, SIGNAL(triggered()), this, SLOT(test6()));
+    QAction *test7 = new QAction("7:MIME", this);
+    connect(test7, SIGNAL(triggered()), this, SLOT(test7()));
+    QAction *test8 = new QAction("8:URI", this);
+    connect(test8, SIGNAL(triggered()), this, SLOT(test8()));
+    QAction *test9 = new QAction("9:XQSharableFile", this);
+    connect(test9, SIGNAL(triggered()), this, SLOT(test9()));
+    QAction *test10 = new QAction("10:Select contact", this);
+    connect(test10,  SIGNAL(triggered()), this, SLOT(test10()));
+    QAction *test11 = new QAction("11:getDrmAttr", this);
+    connect(test11, SIGNAL(triggered()), this, SLOT(test11()));
+
+    mMenu = new QMenu(this);
+    mMenu->addAction(test1);
+    mMenu->addAction(test2);
+    mMenu->addAction(test3);
+    mMenu->addAction(test4);
+    mMenu->addAction(test5);
+    mMenu->addAction(test6);
+    mMenu->addAction(test7);
+    mMenu->addAction(test8);
+    mMenu->addAction(test9);
+    mMenu->addAction(test10);
+    mMenu->addAction(test11);
+
+    testButton1->setMenu(mMenu);
+    
+    mCheckEmbedded = new QCheckBox("Embedded");
+    mSynchronous = new QCheckBox("Synchronous");
+    mBackground = new QCheckBox("Background");
+    mForeground = new QCheckBox("Foreground");
+    mCheckDeleteRequest = new QCheckBox("Delete request");
+    mGenericSend = new QCheckBox("Use generic send()");
+    mCheckEmbedded->setCheckState(Qt::Checked);
+    mSynchronous->setCheckState(Qt::Checked);
+    mGenericSend->setCheckState(Qt::Checked);  // Apply one send() for both embedded/non-embedded
+
+
+    QLabel *inputData = new QLabel(tr("Data size"));
+    mDataSpinBox = new QSpinBox;
+    mDataSpinBox->setMinimum(0);
+    mDataSpinBox->setMaximum(1024*1024);
+    mDataSpinBox->setValue(1024);
+    mDataSpinBox->setSingleStep(1024*10);
+       
+    mReqArg = new QLineEdit("0");
+    mTextRetValue = new QLineEdit("no ret value set");
+
+    QFileInfo appinfo (qApp->applicationFilePath());
+    mAppName = "XQTESTER " + appinfo.baseName();
+
+    QLabel *label = new QLabel(mAppName);
+
+    vl = new QVBoxLayout;
+    vl->setMargin(0);
+    vl->setSpacing(0);
+
+    vl->addWidget(label);
+    vl->addWidget(mCheckEmbedded);
+    vl->addWidget(mSynchronous);
+    vl->addWidget(mBackground);
+    vl->addWidget(mForeground);
+    vl->addWidget(mCheckDeleteRequest);
+    vl->addWidget(mGenericSend);
+    vl->addWidget(inputData);
+    vl->addWidget(mDataSpinBox);
+    vl->addWidget(mReqArg);
+    vl->addWidget(mTextRetValue);
+    vl->addWidget(new QLabel(" "));
+    vl->addWidget(testButton1);
+    vl->addWidget(anyTestButton);
+    vl->addWidget(quitButton);
+
+    setLayout(vl);
+
+#if defined(Q_WS_X11) || defined(Q_WS_WIN)
+    setFixedSize(QSize(360,640)); // nHD
+#elif defined(Q_WS_S60)
+    // showMaximized();
+    showFullScreen();
+#endif
+
+}
+
+AppMgrClient::~AppMgrClient()
+{
+    delete req1;
+    delete req2;
+    delete req3;
+    delete req4;
+    delete req5;
+    delete req6;
+    delete req7;
+    delete req8;
+    delete req9;
+    delete req10;
+    delete mMenu;
+    
+}
+
+// Tester helper function
+bool AppMgrClient::test(XQAiwRequest **req, const QString& interface, const QString& operation)
+{
+    bool embed = (mCheckEmbedded->checkState() == Qt::Checked);
+    bool sync = (mSynchronous->checkState() == Qt::Checked);
+    bool background = (mBackground->checkState() == Qt::Checked);
+    
+    qDebug() << mAppName << " test options: embed=" << embed << ",sync=" << sync << "background=" << background;
+    
+    if (!*req)
+    {
+        *req = appmgr.create(interface, operation);
+        assert(mTestCase + ".req != NULL", *req != NULL);
+        if (!*req)
+        {
+            qDebug() <<  mAppName << " AIW-ERROR::NULL request";
+            qDebug() << mAppName << " Last error=" << appmgr.lastError();
+            return false;
+        }
+        connectSignals(*req);        
+    }
+    // Test embedded funcions
+    (*req)->setEmbedded(embed);
+    (*req)->setSynchronous(sync);
+    (*req)->setBackground(background);
+    
+    
+    bool ret=test(req, mReqArg->text());
+
+    return ret;
+    
+}
+
+
+// Tester helper function
+bool AppMgrClient::test(XQAiwRequest **req, XQAiwInterfaceDescriptor &impl, const QString& operation)
+{
+    if (!*req)
+    {
+        *req = appmgr.create(impl, operation);
+        assert(mTestCase + ".req != NULL", *req != NULL);
+        connectSignals(*req);        
+    }
+    bool ret = test(req, mReqArg->text());
+
+    return ret;
+}
+
+
+
+// Tester helper function
+bool AppMgrClient::test(XQAiwRequest **req, const QString &arg)
+{
+
+    if (!req || !*req)
+    {
+        qDebug() <<  mAppName << " AIW-ERROR::NULL request";
+        return false;
+    }
+
+    
+    bool embed = (mCheckEmbedded->checkState() == Qt::Checked);
+    bool sync = (mSynchronous->checkState() == Qt::Checked);
+    bool background = (mBackground->checkState() == Qt::Checked);
+    bool foreground = (mForeground->checkState() == Qt::Checked);
+    qDebug() << mAppName << " test options: embed=" << embed << ",sync=" << sync << "background=" << background;
+    
+    bool ret=true;
+    
+    // Set arguments for request
+    QList<QVariant> args;
+    args << arg;
+    if ((*req)->operation() == OPERATION1)
+    {
+        args << QVariant(!sync);
+    }
+    (*req)->setArguments(args);
+
+    bool genericSend = (mGenericSend->checkState() == Qt::Checked);
+    (*req)->setEmbedded(embed);
+    (*req)->setSynchronous(sync);
+    (*req)->setBackground(background);
+    
+    // Apply additional options
+    XQRequestInfo options;
+    options.setForeground(foreground);
+    // Save the test case to options as tester data. This data is also passed to service app
+    // The test case is utilized in requestOk and requestError signal handlers
+    options.setInfo(TESTCASE_INFO_KEY, mTestCase);
+    (*req)->setInfo(options);
+    
+    // Make the request
+    if (genericSend || !sync)
+    {
+        if (!(*req)->send())
+        {
+            qDebug() << mAppName << " AIW-ERROR:test: Send failed" << (*req)->lastError();;
+            ret=false;
+        }
+    }
+    else if (!genericSend && sync)
+    {
+        QVariant retValue;
+        if (!(*req)->send(retValue))
+        {
+            qDebug() << mAppName <<  " AIW-ERROR: test: Send(retValue) failed" << (*req)->lastError();;
+            ret=false;
+        }
+        else
+        {
+            if (retValue.canConvert<QString>())
+            {
+                qDebug("%s::retValue=%s,%s", qPrintable(mAppName),
+                       retValue.typeName(),
+                       qPrintable(retValue.value<QString>()));
+                mTextRetValue->setText(retValue.value<QString>());
+            }
+            else
+            {
+                qDebug("%s:retValue=%s", qPrintable(mAppName),
+                       retValue.typeName());
+                mTextRetValue->setText("Not displayable");
+            }
+
+        }
+    }
+
+    assert(mTestCase + ".lastError==0", !(*req)->lastError());
+    
+    // Delete request if wanted
+    bool deleteRequest = (mCheckDeleteRequest->checkState() == Qt::Checked);
+    
+    if ((*req)->lastError() == XQService::EMessageNotFound)
+    {
+        // Slot was not found
+        deleteRequest = true;
+    }
+        
+    if (deleteRequest)
+    {
+        qDebug() << mAppName <<  " AIW-NOTE: Request deleted";
+        delete *req;
+        *req = 0;
+    }
+
+    update();
+
+    return ret;
+    
+
+}
+
+
+// Tester helper function
+void AppMgrClient::connectSignals(XQAiwRequest *req)
+{
+    if (req)
+    {
+            // Connect signals once
+        connect(req, SIGNAL(requestOk(const QVariant&)), this, SLOT(handleOk(const QVariant&)));
+        connect(req, SIGNAL(requestError(int,const QString&)), this, SLOT(handleError(int,const QString&)));
+    }
+}
+
+
+// Tester helper function
+void AppMgrClient::createTestFile(const QString &dir, const QString &fileName)
+{
+
+    QDir d(".");
+    d.mkpath(dir);
+    qDebug() << dir;
+
+    QFile file(dir + "/" + fileName);
+    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
+    {
+        qDebug() << mAppName <<  " Creating file failed " << QString(dir + "/" + fileName);
+        return;
+    }
+    QTextStream out(&file);
+    out << "Text in file" << "\n";
+    file.close();
+    
+}
+
+// Tester helper function
+void AppMgrClient::assert(const QString &testName, bool testResult)
+{
+    qDebug("%s,ASSERT,%s,%s", qPrintable(mAppName), qPrintable(testName),testResult?"OK" : "FAILED");
+}
+
+
+// Tester helper function
+bool AppMgrClient::testRunning(const QString & service, const QString & interface)
+{
+
+    QList<XQAiwInterfaceDescriptor> impls = appmgr.list(service, interface, QString(""));
+    if (impls.count() > 0)
+    {
+        bool b = appmgr.isRunning(impls[0]);
+        return b;
+    }
+    else
+    {
+        return false;
+    }
+   
+}
+
+
+/*
+* Test1:
+* - Call the first IDIAL interface found.
+* - Test XQAplicationManager::isRunning
+* See appmgrservices.h
+*/
+void AppMgrClient::test1()
+{
+
+    mTestCase = "Test1";
+    qDebug() << mAppName << " test1 START";
+    assert("Test1",test(&req1, IDIAL, OPERATION1));
+
+    bool embed = (mCheckEmbedded->checkState() == Qt::Checked);
+    if (!embed)
+    {
+        // Works only for non-embedded cases (no point to check embedded case)
+        assert("Test1.isRunning", testRunning("serviceapp", IDIAL));
+    }
+    qDebug() << mAppName << " test1 END";
+  
+}
+
+/*
+* Test2:
+* - List all the IDIAL interfaces
+* - List all the IDIAL interfaces of the old serviceapp service name
+* - List all the IDIAL interfaces of the new serviceapp service name
+* See appmgrservices.h
+*/
+void AppMgrClient::test2()
+{
+    mTestCase = "Test2";
+    
+    qDebug() << mAppName << " test2 START";
+    
+    QList<XQAiwInterfaceDescriptor> list=appmgr.list(IDIAL, "");
+    qDebug() << mAppName << " list implementations: " << list.count();
+    int i=0;
+    assert("Test2.list.count() > 0", list.count() > 0);
+    foreach (XQAiwInterfaceDescriptor d, list)
+    {
+        qDebug("%s::Service[%d]=%s",qPrintable(mAppName),i,qPrintable(d.serviceName()));
+        qDebug("%s::Interface[%d]=%s",qPrintable(mAppName),i,qPrintable(d.interfaceName()));
+        qDebug("%s::Implementation Id[%d]=%x",qPrintable(mAppName),i,d.property(XQAiwInterfaceDescriptor::ImplementationId).toInt());
+        qDebug("%s::isRunning=%d", qPrintable(mAppName), testRunning(d.serviceName(), d.interfaceName()));
+        qDebug("%s::status=%d", qPrintable(mAppName), appmgr.status(d));
+        i++;
+    }
+
+    // Old, deprecated service name
+    QList<XQAiwInterfaceDescriptor> list2=appmgr.list("com.nokia.services.serviceapp", IDIAL, "");
+    qDebug() << mAppName << " list implementations 2: " << list2.count();
+    i=0;
+    assert("Test2.list2.count() > 0",list2.count() > 0);
+    foreach (XQAiwInterfaceDescriptor d, list2)
+    {
+        qDebug("%s::Service[%d]=%s",qPrintable(mAppName),i,qPrintable(d.serviceName()));
+        qDebug("%s::Interface[%d]=%s",qPrintable(mAppName),i,qPrintable(d.interfaceName()));
+        qDebug("%s::Implementation Id[%d]=%x",qPrintable(mAppName),i,d.property(XQAiwInterfaceDescriptor::ImplementationId).toInt());
+        i++;
+    }
+
+    // Service name
+    QList<XQAiwInterfaceDescriptor> list3=appmgr.list("serviceapp", IDIAL, "");
+    qDebug() << mAppName << " New: list implementations: " << list3.count();
+    i=0;
+    assert("Test2.list3.count() > 0", list3.count() > 0);
+    foreach (XQAiwInterfaceDescriptor d, list3)
+    {
+        qDebug("%s::Service[%d]=%s",qPrintable(mAppName),i,qPrintable(d.serviceName()));
+        qDebug("%s::Interface[%d]=%s",qPrintable(mAppName),i,qPrintable(d.interfaceName()));
+        qDebug("%s::Implementation Id[%d]=%x",qPrintable(mAppName),i,d.property(XQAiwInterfaceDescriptor::ImplementationId).toInt());
+        i++;
+    }
+    
+    if (!list.isEmpty())
+    {
+        // Use the first found
+        qDebug() << mAppName << " Using implementation nbr: " << mImplIndex;
+        test(&req2,list[mImplIndex], OPERATION1);
+    }
+
+    qDebug() << mAppName << " test2 END";
+    
+}
+
+/*
+* Test3:
+* - Using serviceapp and IDIAL interface test passing big amount of data.
+    The datasize can be given in the mDataSpinBox field.
+    At least 0.5 MB shall be passed OK
+* See appmgrservices.h
+*/
+void AppMgrClient::test3()
+{
+
+    mTestCase = "Test3";
+    qDebug() << mAppName << " test3 START";
+    
+    QByteArray data;
+    qDebug() << mAppName << "Data size=" << mDataSpinBox->value();
+    data.fill('X', mDataSpinBox->value());
+
+    bool embed = (mCheckEmbedded->checkState() == Qt::Checked);
+    bool sync = (mSynchronous->checkState() == Qt::Checked);
+    bool background = (mBackground->checkState() == Qt::Checked);
+
+    XQAiwRequest *req=0;
+    req = appmgr.create(QLatin1String("serviceapp"), IDIAL, QLatin1String(""));
+    assert("Test3.req != NULL", req != NULL);
+
+    if (!req)
+    {
+        return;
+    }
+
+    // Apply this operation
+    req->setOperation(QLatin1String("testVariant(QVariant)"));
+
+    connectSignals(req);        
+
+    // Set request attributes
+    req->setEmbedded(embed);
+    req->setSynchronous(sync);
+    req->setBackground(background);
+
+    XQRequestInfo info;
+    // Save the test case to options as tester data. This data is also passed to service app
+    // The test case is utilized in requestOk and requestError signal handlers
+    info.setInfo(TESTCASE_INFO_KEY, mTestCase);
+    req->setInfo(info);
+    
+    QList<QVariant> args;
+
+    args.clear();
+    args << qVariantFromValue(data);
+    req->setArguments(args);
+    
+    assert("Test3.send", req->send());
+
+    bool deleteRequest = (mCheckDeleteRequest->checkState() == Qt::Checked);
+    if (deleteRequest)
+    {
+        delete req;
+        req = 0;
+    }
+   
+    qDebug() << mAppName << " test3 END";
+    
+}
+
+/*
+* Test4:
+* - Test QAction creation using the service "com.nokia.services.hbserviceprovider" and IDIAL interface
+    (The com.nokia.services.hbserviceprovider is implemented by the examples/hbserviceprovider
+    which should be built and included in ROM)
+    The successfully created QAction adds a Test button to UI.
+    Pressing the button emits the signal "test4ActionTriggered" to get input args
+    (the actual "send" happens after returning from the signal)
+* See appmgrservices.h
+*/
+void AppMgrClient::test4()
+{
+    mTestCase = "Test4";
+    qDebug() << mAppName << " test4 START";
+
+    bool embed = (mCheckEmbedded->checkState() == Qt::Checked);
+    bool sync = (mSynchronous->checkState() == Qt::Checked);
+    bool foreground = (mForeground->checkState() == Qt::Checked);
+
+    if (req4)
+    {
+        delete req4;  // Previous
+        req4 = 0;
+    }
+
+    // Only hbserviceprovider support localization
+    req4 = appmgr.create("com.nokia.services.hbserviceprovider", IDIAL, OPERATION1, true);
+    assert("Test4.req4 != NULL", req4 != NULL);
+    if (!req4)
+    {
+        return;
+    }
+
+    connectSignals(req4);
+    req4->setSynchronous(sync);
+
+    // In this test case, apply "options" for other options
+    XQRequestInfo options;
+    options.setEmbedded(embed);
+    options.setForeground(foreground);
+    // Save the test case to options as tester data. This data is also passed to service app
+    // The test case is utilized in requestOk and requestError signal handlers
+    options.setInfo(TESTCASE_INFO_KEY, mTestCase);
+    req4->setInfo(options);
+
+    if (actionButton)
+    {
+        // Previous
+        vl->removeWidget(actionButton);
+        delete actionButton;
+        actionButton = 0;
+        update();
+    }
+    
+    QAction *action = req4->createAction();  // Also connects the triggered event to req !!!!
+    assert("Test4.action != NULL", action != NULL);
+    
+    // Create UI
+    if (action)
+    {
+        actionButton = new QPushButton(action->text());
+        actionButton->addAction(action);
+        vl->addWidget(actionButton);
+        setLayout(vl);
+        // For some reason triggered does not come from request
+        // Workaround...
+        connect(actionButton, SIGNAL(clicked()), action, SIGNAL(triggered()));
+        connect(req4, SIGNAL(triggered()), this, SLOT(test4ActionTriggered()));
+        qDebug() << mAppName << " Press Test button";
+    }
+
+    
+}
+
+// Test button pressed from UI
+void AppMgrClient::test4ActionTriggered()
+{
+    XQAiwRequest *r = (XQAiwRequest *)sender();
+    
+    // Set arguments for request
+    bool embed = (mCheckEmbedded->checkState() == Qt::Checked);
+    QList<QVariant> args;
+    args << QVariant(mReqArg->text());
+    args << QVariant(!embed);
+    r->setArguments(args);
+}
+
+/*
+* Test5:
+* - Test launching activity URI for the UID E0022E70 (fire-and-forget launch)
+    (The E0022E70 is the examples/hbserviceclient which should be built and included in ROM)
+* See appmgrservices.h
+*/
+void AppMgrClient::test5()
+{
+    mTestCase = "Test5";
+    qDebug() << mAppName << " test5 START";
+
+    QUrl uri(XQURI_SCHEME_ACTIVITY + "://E0022E70?" + XQURI_KEY_ACTIVITY_NAME + "=MainView&key1=data1&key2=data2"); 
+    qDebug() << mAppName << " Uri=" << uri.toString();
+    qDebug() << mAppName << " isValid=" << uri.isValid();
+    qDebug() << mAppName << " Uri authority=" << uri.authority();
+    QString old=mReqArg->text();
+    if (!req5)
+    {
+        req5 = appmgr.create(uri);
+        assert("Test5.req5 != NULL", req5 != NULL);
+        connectSignals(req5); 
+    }
+    
+    mReqArg->setText(uri.encodedQuery()); 
+    assert("Test5", test(&req5, mReqArg->text()));
+    mReqArg->setText(old);
+    
+    qDebug() << mAppName << " test5 END";
+    
+}
+
+/*
+* Test6:
+* - Test launching URI scheme "testto" implemented by the examples/serviceapp
+*/
+void AppMgrClient::test6()
+{
+
+    mTestCase = "Test5";
+    qDebug() << mAppName << " test6 START";
+
+    // QUrl uri("testto://authority?param1=value1&param1=value2"); 
+    QUrl uri("testto://authority?param1=value1&param1=value2"); 
+    qDebug() << mAppName << " Uri=" << uri.toString();
+    qDebug() << mAppName << " isValid=" << uri.isValid();
+    qDebug() << mAppName << " Uri authority=" << uri.authority();
+
+    QList<XQAiwInterfaceDescriptor> uriHandlers = appmgr.list(uri);
+    assert("Test6.uriHandlers.count() > 0", uriHandlers.count() > 0);
+    
+    // Note : Only services supporting custom property are returned
+    foreach (XQAiwInterfaceDescriptor d, uriHandlers)
+    {
+        qDebug() << mAppName << " Service=" << d.serviceName();
+        qDebug() << mAppName << " Interface=" << d.interfaceName();
+        qDebug("%s::Implementation Id=%x",qPrintable(mAppName),d.property(XQAiwInterfaceDescriptor::ImplementationId).toInt());
+        qDebug("%s::isRunning=%d", qPrintable(mAppName), testRunning(d.serviceName(), d.interfaceName()));
+    }
+
+    if (!req6)
+    {
+        req6 = appmgr.create(uri);
+        assert("Test5.req6 != NULL", req6 != NULL);
+        connectSignals(req6); 
+    }
+
+    assert("Test6",test(&req6, uri.toString()));
+
+    qDebug() << mAppName << " test6 END";
+    
+}
+
+/*
+* Test7:
+* - Test launching com.nokia.symbian.IFileView for non-data-caged text file (MIME type text/plain)
+*   At least the examples/serviceapp implements support for interface
+*/
+void AppMgrClient::test7()
+{
+    mTestCase = "Test7";
+    qDebug() << mAppName << " test7 START";
+    
+    // Create test file  (MIME type text/plain)
+    createTestFile("C:/data/Others", "test.txt");
+
+    
+    QFile file("C:/data/Others/test.txt");
+    qDebug() << mAppName << " File=" << file.fileName();
+    qDebug() << mAppName << " exists=" << file.exists();
+
+    QList<XQAiwInterfaceDescriptor> fileHandlers = appmgr.list(file);
+    assert("Test7.fileHandlers.count() > 0", fileHandlers.count() > 0);
+    foreach (XQAiwInterfaceDescriptor d, fileHandlers)
+    {
+        qDebug() << mAppName << " Service=" << d.serviceName();
+        qDebug() << mAppName << " Interface=" << d.interfaceName();
+        qDebug("%s::Implementation Id=%x",qPrintable(mAppName),d.property(XQAiwInterfaceDescriptor::ImplementationId).toInt());
+    }
+    
+    if (!req7)
+    {
+        req7 = appmgr.create(file);
+        assert("Test5.req7 != NULL", req7 != NULL);
+        connectSignals(req7); 
+    }
+    assert("Test7",test(&req7, file.fileName()));
+
+    qDebug() << mAppName << " test7 END";
+    
+}
+
+
+/*
+* Test8:
+* - Test launching http URI which should be implemented by the Browser
+    Note ! http scheme is handled by the QDesktopServices::openUrl.
+*/
+void AppMgrClient::test8()
+{
+    mTestCase = "Test8";
+    qDebug() << mAppName << " test8 START";
+
+    // E0022E73 == ServiceApp
+    QUrl uri("http://www.nokia.com"); 
+    qDebug() << mAppName << " Uri=" << uri.toString();
+    qDebug() << mAppName << " isValid=" << uri.isValid();
+    qDebug() << mAppName << " Uri authority=" << uri.authority();
+
+    if (!req8)
+    {
+        req8 = appmgr.create(uri);
+        assert("Test8.req8 != NULL", req8 != NULL);
+        connectSignals(req8); 
+    }
+    assert("Test8", test(&req8, uri.toString()));
+
+    qDebug() << mAppName << " test8 END";
+    
+}
+
+/*
+* Test9:
+* - Test launching com.nokia.symbian.IFileView for data-caged text file (MIME type text/plain)
+*   At least the examples/serviceapp implements support for interface
+*/
+void AppMgrClient::test9()
+{
+
+    mTestCase = "Test9";
+    qDebug() << mAppName << " test9 START";    
+
+    bool embed = (mCheckEmbedded->checkState() == Qt::Checked);
+    bool sync = (mSynchronous->checkState() == Qt::Checked);
+    bool deleteRequest = (mCheckDeleteRequest->checkState() == Qt::Checked);
+
+
+    // Access data-caged file 
+    XQSharableFile sf;
+    QString fileDir = "c:/private/e0022e74";
+    
+    if (mAppName == "appmgrclient2")
+    {
+        fileDir = "c:/private/e0022e76";
+    }
+
+    createTestFile(fileDir, "test.txt");
+    if (!sf.open(fileDir + "\\test.txt"))
+    {
+        qDebug() << mAppName << " file open failed " << (fileDir + "/test.txt");
+        return;
+    }
+
+    // Just test listing by sharable file
+    QList<XQAiwInterfaceDescriptor> fileHandlers = appmgr.list(sf);
+    assert("Test9.fileHandlers.count() > 0", fileHandlers.count() > 0);
+    if (fileHandlers.count() > 0)
+    {
+        XQAiwInterfaceDescriptor d = fileHandlers.first();
+        qDebug() << mAppName << " File Service=" << d.serviceName();
+        qDebug() << mAppName << " File Interface=" << d.interfaceName();
+        qDebug("%s::Implementation Id=%x",qPrintable(mAppName),d.property(XQAiwInterfaceDescriptor::ImplementationId).toInt());
+        if (!req9)
+        {
+            // Create by descriptor
+            req9 = appmgr.create(sf, d);
+            assert("Test9.req9 != NULL", req9 != NULL);
+        }
+        if (!req9)
+        {
+            sf.close();
+            return ;
+        }
+    }
+    else
+    {
+        sf.close();
+    }
+
+    connectSignals(req9);        
+    req9->setEmbedded(embed);
+    req9->setSynchronous(sync);
+    
+    QList<QVariant> args;
+    args << qVariantFromValue(sf);
+    req9->setArguments(args);
+
+    XQRequestInfo info;
+    // Save the test case to options as tester data. This data is also passed to service app
+    // The test case is utilized in requestOk and requestError signal handlers
+    info.setInfo(TESTCASE_INFO_KEY, mTestCase);
+    req9->setInfo(info);
+    
+    assert("Test9.send", req9->send());
+    assert(mTestCase + ".lastError==0", !req9->lastError());
+    
+    // Remember to close the file !!!
+    sf.close();
+
+    if (deleteRequest)
+    {
+        delete req9;
+        req9 = 0;
+    }
+
+    qDebug() << mAppName << " test9 END";
+    
+}
+
+/*
+* Test10:
+* - Test fetching contacts via the "com.nokia.services.phonebookservices" interfaces
+    Note ! This is deprecated interface name still used. The official name is "com.nokia.symbian.IContactFetch"
+           once phonebook supports that.
+*/
+void AppMgrClient::test10()
+{
+
+    mTestCase = "Test10";
+    qDebug() << mAppName << " test10 START";
+
+    bool embed = (mCheckEmbedded->checkState() == Qt::Checked);
+    bool sync = (mSynchronous->checkState() == Qt::Checked);
+    bool background = (mBackground->checkState() == Qt::Checked);
+
+    qDebug() << mAppName <<  " test10: embed=" << embed << ",sync=" << sync << "background=" << background;
+
+    if (!req10)
+    {
+        req10 = appmgr.create(QLatin1String("com.nokia.services.phonebookservices"), QLatin1String("Fetch"), QLatin1String(""));
+        assert("Test10.req10 != NULL", req10 != NULL);
+        if (req10)
+        {
+            connect(req10, SIGNAL(requestOk(const QVariant&)), this, SLOT(handleOk(const QVariant&)));
+            connect(req10, SIGNAL(requestError(int,const QString&)), this, SLOT(handleError(int,const QString&)));
+        }
+    }
+
+    if (!req10)
+    {
+        return;
+    }
+
+    // Set request attributes
+    req10->setOperation("fetch(QString,QString,QString)");
+    req10->setEmbedded(embed);
+    req10->setSynchronous(sync);
+    req10->setBackground(background);
+
+    // Set arguments
+    QList<QVariant> args;
+    args << "Contact"; 
+    args << KCntActionAll;   
+    args << KCntFilterDisplayAll;
+    req10->setArguments(args);
+    
+    XQRequestInfo info;
+    // Save the test case to options as tester data. This data is also passed to service app
+    // The test case is utilized in requestOk and requestError signal handlers
+    info.setInfo(TESTCASE_INFO_KEY, mTestCase);
+    req10->setInfo(info);
+
+    // Send the request
+    assert("Test10.send", req10->send());
+    assert(mTestCase + ".lastError==0", !req10->lastError());
+
+    bool deleteRequest = (mCheckDeleteRequest->checkState() == Qt::Checked);
+    if (deleteRequest)
+    {
+        delete req10;
+        req10 = 0;
+    }
+    
+    qDebug() << mAppName << " test10 END";
+
+
+}
+
+
+/*
+* Test10:
+* - Test getting DRM attributes of the files included in the examples\appmgrclient\DrmTestFiles.zip
+    (You need to unzip/transfer these files in correct location)
+*/
+void AppMgrClient::test11()
+{
+    mTestCase = "Test11";
+    qDebug() << mAppName << " test11 START";
+
+    // Copy files from DrmTestFiles.zip into correct location
+    QList<QString> drmFiles;
+    drmFiles.append("C:/data/Others/RoAcqoffer-111-aac-i15m.ort");
+    drmFiles.append("C:/data/Others/SD_Celebration_SP.dcf");
+    drmFiles.append("C:/data/Others/111-test1.odf");
+    drmFiles.append("C:/data/Others/SD_jpg_sun.dcf");
+    drmFiles.append("C:/data/Others/STC1_128_44_16_2_CBR.wma");
+    drmFiles.append("C:/data/Others/test.txt");
+    drmFiles.append("C:/data/Others/some-nonexisting-file.txt");  // Error
+
+    QList<int> attrNames;
+    attrNames.append(XQApplicationManager::MimeType);
+    attrNames.append(XQApplicationManager::IsProtected);
+    attrNames.append(XQApplicationManager::IsForwardable);
+    // See other attributes from epoc32/include/caf/caftypes.h
+
+    // Test with file names
+    foreach (QString f, drmFiles)
+    {
+        QFile file(f);
+        QVariantList attrValues;
+        bool ok = appmgr.getDrmAttributes(file, attrNames, attrValues);
+        assert("Test11.getDrmAttributes.QFile/" + f,
+               f != QString("C:/data/Others/some-nonexisting-file.txt") ? ok : !ok);
+        int i=0;
+        foreach (QVariant v, attrValues)
+        {
+            qDebug() << mAppName << " Attribute " << attrNames[i] << "=" << qPrintable(v.toString());
+            i++;
+        }
+    }
+
+    // Test with file handles
+    foreach (QString f, drmFiles)
+    {
+        XQSharableFile file;
+        file.open(f);  // Create handle manually
+        QVariantList attrValues;
+        bool ok = appmgr.getDrmAttributes(file, attrNames, attrValues);
+        assert("Test11.getDrmAttributes.XQSharableFile/" + f,
+               f != QString("C:/data/Others/some-nonexisting-file.txt") ? ok : !ok);
+        int i=0;
+        foreach (QVariant v, attrValues)
+        {
+            qDebug() << mAppName << " Attribute " << attrNames[i] << "=" << qPrintable(v.toString());
+            i++;
+        }
+        file.close();
+    }
+    
+    qDebug() << mAppName << " test11 END";
+
+}
+
+
+#define TXT_ID QLatin1String("txt_aiw_action_text")
+
+//
+// Miscellanous ad-hoc tests for trying bugs, etc.
+//
+void AppMgrClient::anyTest()
+{
+
+#if 0
+    bool embed = (mCheckEmbedded->checkState() == Qt::Checked);
+    bool sync = (mSynchronous->checkState() == Qt::Checked);
+    bool background = (mBackground->checkState() == Qt::Checked);
+
+    XQAiwRequest *req=0;
+    req = appmgr.create(QLatin1String("serviceapp"), IDIAL, QLatin1String(""));
+
+    if (!req)
+    {
+        qDebug() << mAppName << " AIW-ERROR NULL request";
+        return;
+    }
+
+    // Apply this operation
+    req->setOperation(QLatin1String("testVariant(QVariant)"));
+    
+    connectSignals(req);        
+
+    // Set request attributes
+    req->setEmbedded(embed);
+    req->setSynchronous(sync);
+    req->setBackground(background);
+
+    QList<QVariant> args;
+
+    /*
+    // Just construct dummies
+    MetaDummy1 dummy1;
+    MetaDummy2 dummy2;
+    */
+
+    /*
+    // THIS WORKS
+    CntServicesContact cnt1;
+    cnt1.mDisplayName = "Test1";
+    cnt1.mPhoneNumber = "050-1111111";
+    cnt1.mEmailAddress = "test1.test@nokia.com";
+    
+    CntServicesContact cnt2;
+    cnt2.mDisplayName = "Test2";
+    cnt2.mPhoneNumber = "050-2222222";
+    cnt2.mEmailAddress = "test2.test@nokia.com";
+
+    CntServicesContactList list;
+    list.append(cnt1);
+    list.append(cnt2);
+    */
+
+    QVariant v1;
+    QVariant v2;
+    QVariant v3;
+    v1.setValue((int)-99);
+    v2.setValue((bool)true);
+    v3.setValue(QString("Variant3"));
+    TestServiceData data1(1, v1);
+    TestServiceData data2(2, v2);
+    TestServiceData data3(3, v3);
+    TestServiceDataList list;
+    list.append(data1);
+    list.append(data2);
+    list.append(data3);
+    
+    args.clear();
+    args << qVariantFromValue(list);
+    req->setArguments(args);
+
+    req->send();
+    
+    bool deleteRequest = (mCheckDeleteRequest->checkState() == Qt::Checked);
+    if (deleteRequest)
+    {
+        delete req;
+        req = 0;
+    }
+
+    qDebug() << mAppName << " test END";
+
+    //  ---- OLD TESTS ------
+    
+    /*
+    qDebug() << mAppName << "  name" << qApp->applicationName();
+    qDebug() << mAppName << " dirpath" << qApp->applicationDirPath();
+    qDebug() << mAppName << " filename" << qApp->applicationFilePath();
+    qDebug() << mAppName << " pid" << qApp->applicationPid();
+
+    QFileInfo appinfo (qApp->applicationFilePath());
+    qDebug() << mAppName << " appinfo.applicationFilePath" << qApp->applicationFilePath();
+    qDebug() << mAppName << " appinfo.absolutePath" << appinfo.absolutePath();
+    qDebug() << mAppName << " appinfo.baseName" << appinfo.baseName();
+
+    QString lang = QLocale::system().name();
+    qDebug() << mAppName << " anyTest:" << lang;
+
+    // QString textFile = "z:/resource/qt/translations/hbserviceprovider";
+    QString textFile = "hbserviceprovider";
+    QFileInfo info(textFile);
+    qDebug() << mAppName << " base" << info.baseName();
+    qDebug() << mAppName << " path" << info.filePath();
+    if (info.baseName() == info.filePath())
+    {
+        textFile = qApp->applicationFilePath().left(2) + "/resource/qt/translations/" + textFile;
+        qDebug() << mAppName << " path added" << textFile;
+    }
+
+    textFile += "_"; 
+    textFile += lang;
+    qDebug() << mAppName << " anyTest:" << textFile;
+
+    QTranslator translator;
+    bool res = translator.load(textFile);
+    qDebug() << mAppName << " anyTest:" << res;
+    if (res)
+    {
+        qApp->installTranslator(&translator);
+    }
+
+    QString textId = TXT_ID;
+    QByteArray ba = textId.toLatin1();
+    const char *textPtr = ba.data();
+
+    QString text = qtTrId(textPtr);  // translate
+    qDebug() << mAppName << " translated text:" << text;
+
+    qApp->removeTranslator(&translator);
+
+    Q_ASSERT(0==1);
+
+    QString str("e0022e70");
+    uint ui = str.toUInt();
+    qDebug() << mAppName << " toUInt value=" << ui;
+    bool b=false;
+    ui=str.toUInt(&b,16);
+    qDebug() << mAppName << " toUInt status=" << b <<  ",value=" << ui;
+
+    
+    */
+
+#endif
+}
+
+
+
+
+// Aiw request responses
+void AppMgrClient::handleOk(const QVariant& result)
+{
+    XQAiwRequest *r = static_cast<XQAiwRequest *>(sender());
+    QString testCase = (r->info().info(TESTCASE_INFO_KEY)).toString();
+    
+    int impl=-1;
+    impl = (r->descriptor().property(XQAiwInterfaceDescriptor::ImplementationId)).toInt();
+    QString interface = r->descriptor().interfaceName();
+    QString service = r->descriptor().serviceName();
+
+    qDebug("%s,%s::requestOk,from [%s.%s,%x]",
+           qPrintable(mAppName),
+           qPrintable(testCase),
+           qPrintable(service),
+           qPrintable(interface),
+           impl);
+    qDebug("%s,%s::requestOk,result type=%s",
+           qPrintable(mAppName),
+           qPrintable(testCase),
+           result.typeName());
+    
+    if (result.canConvert<CntServicesContactList>())
+    {
+        CntServicesContactList list;
+        list = qVariantValue<CntServicesContactList>(result);
+        for (int i = 0; i < list.count(); ++i)
+        {
+            qDebug() << mAppName << "," << testCase <<  ",result[" << i << "].mDisplayName=" << list[i].mDisplayName;
+            qDebug() << mAppName << "," << testCase <<  " result[" << i << "].mPhoneNumber=" << list[i].mPhoneNumber;
+            qDebug() << mAppName << "," << testCase <<  ",result[" << i << "].mEmailAddress=" << list[i].mEmailAddress;
+
+        }
+    }
+    else if (result.canConvert<TestServiceDataList>())
+    {
+        TestServiceDataList list = qVariantValue<TestServiceDataList>(result);
+        for (int i = 0; i < list.count(); ++i)
+        {
+            qDebug() << mAppName << "," << testCase << ",result[" << i << "].mType=" << list[i].mType;
+            qDebug() << mAppName << "," << testCase << ",result[" << i << "].mData=" << list[i].mData.toString();
+        }
+        
+    }
+    else if (result.canConvert<QString>())
+    {
+        qDebug("%s,%s,result=%s",
+               qPrintable(mAppName),
+               qPrintable(testCase),
+               qPrintable(result.value<QString>()));
+        mTextRetValue->setText(result.value<QString>());
+    }
+
+    else
+    {
+        mTextRetValue->setText("Not displayable");
+    }
+}
+  
+void AppMgrClient::handleError(int errorCode, const QString& errorMessage)
+{
+    XQAiwRequest *r = static_cast<XQAiwRequest *>(sender());
+    QString interface = r->descriptor().interfaceName();
+    QString service = r->descriptor().serviceName();
+    QString testCase = (r->info().info(TESTCASE_INFO_KEY)).toString();
+    
+    int impl=-1;
+    impl = (r->descriptor().property(XQAiwInterfaceDescriptor::ImplementationId)).toInt();
+
+    qDebug("%s,%s::requestError,from [%s.%s,%x]=(%d,%s)",
+           qPrintable(mAppName),
+           qPrintable(testCase),
+           qPrintable(service),
+           qPrintable(interface),
+           impl, errorCode, qPrintable(errorMessage));
+    
+    mTextRetValue->setText(errorMessage);
+}
+
+
+
+Q_IMPLEMENT_USER_METATYPE(MetaDummy1)
+Q_IMPLEMENT_USER_METATYPE(MetaDummy2)
+Q_IMPLEMENT_USER_METATYPE(CntServicesContact)
+Q_IMPLEMENT_USER_METATYPE_NO_OPERATORS(CntServicesContactList)
+Q_IMPLEMENT_USER_METATYPE(TestServiceData)
+Q_IMPLEMENT_USER_METATYPE_NO_OPERATORS(TestServiceDataList)