--- a/qtmobility/tests/auto/qcontactasync/maliciousplugin/maliciousplugin.cpp Fri Jun 11 14:26:25 2010 +0300
+++ b/qtmobility/tests/auto/qcontactasync/maliciousplugin/maliciousplugin.cpp Wed Jun 23 19:08:38 2010 +0300
@@ -53,9 +53,112 @@
#include "maliciousplugin_p.h"
#include "qcontactmanager.h"
+#include <QThread>
+#include <QMutex>
+#include <QSet>
+#include <QDebug>
+
+class MaliciousThreadObject : public QObject
+{
+ Q_OBJECT
+public:
+ MaliciousThreadObject() {}
+
+public slots:
+ void activateRequest(QContactAbstractRequest* req)
+ {
+ mutex.lock();
+ if (activeRequests.contains(req)) {
+ QContactManagerEngine::updateRequestState(req, QContactAbstractRequest::ActiveState);
+ }
+ mutex.unlock();
+ }
+
+ void finishRequest(QContactAbstractRequest* req)
+ {
+ QContactManager::Error errorResult = QContactManager::NoError;
+ QMap<int, QContactManager::Error> errorsResult;
+ QList<QContactLocalId> idResult;
+ QList<QContact> contactResult;
+ QList<QContactDetailDefinition> defResult;
+ QMap<QString, QContactDetailDefinition> defMapResult;
+ QList<QContactRelationship> relResult;
+
+ mutex.lock();
+ if (activeRequests.contains(req)) {
+ switch(req->type()) {
+ case QContactAbstractRequest::ContactLocalIdFetchRequest:
+ QContactManagerEngine::updateContactLocalIdFetchRequest(static_cast<QContactLocalIdFetchRequest*>(req), idResult, errorResult, QContactAbstractRequest::FinishedState);
+ break;
+
+ case QContactAbstractRequest::ContactFetchRequest:
+ QContactManagerEngine::updateContactFetchRequest(static_cast<QContactFetchRequest*>(req), contactResult, errorResult, QContactAbstractRequest::FinishedState);
+ break;
+
+ case QContactAbstractRequest::DetailDefinitionSaveRequest:
+ QContactManagerEngine::updateDefinitionSaveRequest(static_cast<QContactDetailDefinitionSaveRequest*>(req), defResult, errorResult, errorsResult, QContactAbstractRequest::FinishedState);
+ break;
+
+ case QContactAbstractRequest::DetailDefinitionFetchRequest:
+ QContactManagerEngine::updateDefinitionFetchRequest(static_cast<QContactDetailDefinitionFetchRequest*>(req), defMapResult, errorResult, errorsResult, QContactAbstractRequest::FinishedState);
+ break;
+
+ case QContactAbstractRequest::DetailDefinitionRemoveRequest:
+ QContactManagerEngine::updateDefinitionRemoveRequest(static_cast<QContactDetailDefinitionRemoveRequest*>(req), errorResult, errorsResult, QContactAbstractRequest::FinishedState);
+ break;
+ default:
+ QContactManagerEngine::updateRequestState(req, QContactAbstractRequest::FinishedState);
+ break;
+ }
+ }
+ activeRequests.remove(req);
+ mutex.unlock();
+ }
+public:
+ QMutex mutex;
+
+ QSet<QContactAbstractRequest*> activeRequests;
+};
+
+class MaliciousThread : public QThread
+{
+ Q_OBJECT;
+public:
+ MaliciousThread();
+ ~MaliciousThread();
+ QObject* eventLoopQuitHack;
+};
+
+MaliciousThread::MaliciousThread()
+{
+ eventLoopQuitHack = new QObject;
+ eventLoopQuitHack->moveToThread(this);
+ connect(eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection);
+}
+
+MaliciousThread::~MaliciousThread()
+{
+ eventLoopQuitHack->deleteLater();
+ wait();
+}
+
MaliciousAsyncManagerEngine::MaliciousAsyncManagerEngine()
: QContactManagerEngine()
{
+ thread = new MaliciousThread();
+ threadObject = new MaliciousThreadObject();
+ threadObject->moveToThread(thread);
+
+ connect(this, SIGNAL(doStartRequest(QContactAbstractRequest*)), threadObject, SLOT(activateRequest(QContactAbstractRequest*)));
+ connect(this, SIGNAL(doFinishRequest(QContactAbstractRequest*)), threadObject, SLOT(finishRequest(QContactAbstractRequest*)));
+
+ thread->start();
+}
+
+MaliciousAsyncManagerEngine::~MaliciousAsyncManagerEngine()
+{
+ delete thread;
+ delete threadObject;
}
QString MaliciousAsyncManagerEngine::synthesizedDisplayLabel(const QContact& contact, QContactManager::Error* error) const
@@ -72,25 +175,14 @@
bool MaliciousAsyncManagerEngine::startRequest(QContactAbstractRequest* req)
{
- // maliciously attempt to update the request with every result type
- updateRequestState(req, QContactAbstractRequest::ActiveState);
- // XXX TODO: call the request-type specific update functions
-/*
- //QContactManager::Error errorResult = QContactManager::NoError;
- QList<QContactManager::Error> errorsResult;
- QList<QContactLocalId> idResult;
- QList<QContact> contactResult;
- QList<QContactDetailDefinition> defResult;
- QMap<QString, QContactDetailDefinition> defMapResult;
- QList<QContactRelationship> relResult;
+ threadObject->mutex.lock();
+ threadObject->activeRequests.insert(req);
+ threadObject->mutex.unlock();
- updateContactLocalIdFetchRequest(req, idResult, errorResult, errorsResult, QContactAbstractRequest::ActiveState, false);
- updateContactFetchRequest(req, contactResult, errorResult, errorsResult, QContactAbstractRequest::ActiveState, false);
- updateDefinitionSaveRequest(req, defResult, errorResult, errorsResult, QContactAbstractRequest::ActiveState);
- updateDefinitionFetchRequest(req, defMapResult, errorResult, errorsResult, QContactAbstractRequest::ActiveState, false);
- updateRequest(req, relResult, errorResult, errorsResult, QContactAbstractRequest::ActiveState, false);
-*/
- QContactManagerEngine::startRequest(req);
+ // Spawn a thread to do stuff on another thread
+ emit doStartRequest(req);
+ emit doFinishRequest(req);
+
return true;
}
@@ -101,6 +193,13 @@
return true;
}
+void MaliciousAsyncManagerEngine::requestDestroyed(QContactAbstractRequest *req)
+{
+ threadObject->mutex.lock();
+ threadObject->activeRequests.remove(req);
+ threadObject->mutex.unlock();
+ QContactManagerEngine::requestDestroyed(req);
+}
QString MaliciousEngineFactory::managerName() const
{
@@ -114,3 +213,5 @@
*error = QContactManager::NoError;
return new MaliciousAsyncManagerEngine();
}
+
+#include "maliciousplugin.moc"