/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Mobility Components. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, 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, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "eventloggerengine_maemo_p.h" #include "telepathyengine_maemo_p.h" #include "maemohelpers_p.h" #include "qmessageservice_maemo_p.h" #include QTM_BEGIN_NAMESPACE Q_GLOBAL_STATIC(EventLoggerEngine,eventLoggerEngine); EventLoggerEngine* EventLoggerEngine::instance() { return eventLoggerEngine(); } EventLoggerEngine::EventLoggerEngine(QObject *parent):QObject(parent), _filterId(0) { // qDebug() << "EventLoggerEngine::EventLoggerEngine"; DBusError err=DBUS_ERROR_INIT; active = false; g_type_init(); dbus = dbus_bus_get(DBUS_BUS_SESSION, &err); // Create dummy Dbus object and dbus_connection_setup_with_g_main (dbus, NULL); //add it to g_mainloop because eventlogger library expects that someone alse has added session bus to g_mainloop el=rtcom_el_new (); if(!RTCOM_IS_EL(el)) qDebug() << "EventLoggerEngine::EventLoggerEngine():Could't create RTComEl\n"; queryThread=0; // queryThread.run(); // connect(queryThread, SIGNAL(messagesFound(const QMessageIdList &)),this, SLOT(messagesFound_(const QMessageIdList &))); g_signal_connect(G_OBJECT(el), "new-event", G_CALLBACK(new_event_cb),(void*)this); g_signal_connect(G_OBJECT(el), "event-deleted", G_CALLBACK(event_deleted_cb),(void*)this); g_signal_connect(G_OBJECT(el), "event-updated", G_CALLBACK(event_updated_cb),(void*)this); qRegisterMetaType("QMessageIdList"); } void EventLoggerEngine::new_event_cb(RTComEl *el,int event_id, const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, const char *group_uid,const char *service,EventLoggerEngine *p) { Q_UNUSED(el); p->newEvent(event_id, local_uid,remote_uid ,remote_ebook_uid,group_uid,service); }; void EventLoggerEngine::event_deleted_cb(RTComEl *el,int event_id, const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, const char *group_uid,const char *service,EventLoggerEngine *p) { Q_UNUSED(el); p->deletedEvent(event_id, local_uid,remote_uid ,remote_ebook_uid,group_uid,service); }; void EventLoggerEngine::event_updated_cb(RTComEl *el,int event_id, const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, const char *group_uid,const char *service,EventLoggerEngine *p) { Q_UNUSED(el); p->updatedEvent(event_id, local_uid,remote_uid ,remote_ebook_uid,group_uid,service); }; void EventLoggerEngine::newEvent(int event_id, const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, const char *group_uid,const char *service) { Q_UNUSED(local_uid); Q_UNUSED(remote_uid);Q_UNUSED(remote_ebook_uid); Q_UNUSED(group_uid);Q_UNUSED(service); QString eventIds=QString("el")+QString::number(event_id); QMessageId id(eventIds); qDebug() << "newEvent id=" << eventIds; notification(event_id,service,QMessageStorePrivate::Added); } void EventLoggerEngine::updatedEvent(int event_id, const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, const char *group_uid,const char *service) { Q_UNUSED(local_uid); Q_UNUSED(remote_uid);Q_UNUSED(remote_ebook_uid); Q_UNUSED(group_uid);Q_UNUSED(service); QString eventIds=QString("el")+QString::number(event_id); QMessageId id(eventIds); qDebug() << "updatedEvent id=" << eventIds; notification(event_id,service,QMessageStorePrivate::Updated); } void EventLoggerEngine::deletedEvent(int event_id, const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, const char *group_uid,const char *service) { Q_UNUSED(local_uid); Q_UNUSED(remote_uid);Q_UNUSED(remote_ebook_uid); Q_UNUSED(group_uid);Q_UNUSED(service); QString eventIds=QString("el")+QString::number(event_id); QMessageId id(eventIds); qDebug() << "deletedEvent id=" << eventIds; notification(event_id,service,QMessageStorePrivate::Removed); } QMessageManager::NotificationFilterId EventLoggerEngine::registerNotificationFilter(QMessageStorePrivate& aPrivateStore, const QMessageFilter &filter) { iListenForNotifications = true; ipMessageStorePrivate = &aPrivateStore; int filterId = ++_filterId; _filters.insert(filterId, filter); return filterId; } void EventLoggerEngine::unregisterNotificationFilter(QMessageManager::NotificationFilterId notificationFilterId) { _filters.remove(notificationFilterId); if (_filters.count() == 0) { iListenForNotifications = false; } } QMessage EventLoggerEngine::eventToMessage(RTComElEvent & ev) { QMessage message; if (!strcmp(ev.fld_service, "RTCOM_EL_SERVICE_SMS")) { message.setType(QMessage::Sms); } else if (!strcmp(ev.fld_service,"RTCOM_EL_SERVICE_CHAT")) { message.setType(QMessage::InstantMessage); } else { message.setType(QMessage::NoType); // Other type, as exampele voice Call }; message.setParentAccountId(QMessageAccountId(QString("y/Account/%1").arg(ev.fld_local_uid))); if (!ev.fld_is_read) { message.setStatus(QMessage::Read); }; message.setPriority(QMessage::NormalPriority); message.setDate(QDateTime::fromTime_t(ev.fld_start_time)); message.setReceivedDate(QDateTime::fromTime_t(ev.fld_start_time)); if (ev.fld_outgoing) QMessagePrivate::setStandardFolder(message,QMessage::SentFolder); else QMessagePrivate::setStandardFolder(message,QMessage::InboxFolder); // qDebug() << "event_type:" << ev.fld_event_type << ev.fld_event_type_id << "Outgoing:" << ev.fld_outgoing << " Folder:" << message.standardFolder(); if (ev.fld_outgoing) { // Outgoing message message.setFrom(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_local_uid))); QMessagePrivate::setSenderName(message, QString(ev.fld_local_uid)); message.setTo(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_remote_uid))); } else { // Incoming message message.setFrom(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_remote_uid))); QMessagePrivate::setSenderName(message, QString(ev.fld_remote_uid)); QMessageAddressList messageAddresslist; messageAddresslist.append(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_local_uid))); message.setTo(messageAddresslist); } message.setBody(QString::fromUtf8(ev.fld_free_text)); QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); privateMessage->_id = QMessageId(QString("el")+QString::number(ev.fld_id)); privateMessage->_modified = false; // qDebug() << "id:" << message.id().toString() << "From:" << message.from().addressee() << "Text:" << message.textContent(); return message; } void EventLoggerEngine::addEvent(QMessage &message) { qDebug() << "EventLoggerEngine::addEvent()\n"; RTComElEvent *ev = rtcom_el_event_new(); if (message.type()==QMessage::Sms) { RTCOM_EL_EVENT_SET_FIELD(ev,service,(gchar *)"RTCOM_EL_SERVICE_SMS"); } else if (message.type()==QMessage::InstantMessage) { RTCOM_EL_EVENT_SET_FIELD(ev,service,(gchar *)"RTCOM_EL_SERVICE_CHAT"); RTCOM_EL_EVENT_SET_FIELD(ev,remote_uid,(gchar *)message.from().addressee().toStdString().c_str()); RTCOM_EL_EVENT_SET_FIELD(ev,group_uid,(gchar *)message.from().addressee().toStdString().c_str()); } else return; // Invalid messge type RTCOM_EL_EVENT_SET_FIELD(ev,event_type,(gchar *)"RTCOM_EL_EVENTTYPE_SMS_INBOUND"); RTCOM_EL_EVENT_SET_FIELD(ev,local_uid,(gchar *)"ring/tel/ring"); RTCOM_EL_EVENT_SET_FIELD(ev,local_name,(gchar *)""); RTCOM_EL_EVENT_SET_FIELD(ev,remote_uid,(gchar *)message.from().addressee().toStdString().c_str()); RTCOM_EL_EVENT_SET_FIELD(ev,group_uid,(gchar *)message.from().addressee().toStdString().c_str()); RTCOM_EL_EVENT_SET_FIELD(ev,start_time,time(NULL)); RTCOM_EL_EVENT_SET_FIELD(ev,remote_ebook_uid,(gchar *)"1"); RTCOM_EL_EVENT_SET_FIELD(ev,free_text,(gchar *)message.textContent().toStdString().c_str()); rtcom_el_add_event(el,ev,NULL); rtcom_el_event_free(ev); } bool EventLoggerEngine::deleteMessage(const QMessageId& id) { int status=rtcom_el_delete_event(el,id.toString().remove("el").toInt(),NULL); return status==0; } QMessage EventLoggerEngine::message(const QMessageId& id) { QMessage message; // qDebug() << "EventLoggerEngine::getMessage id=" << id.toString(); RTComElEvent ev; bzero(&ev,sizeof(ev)); RTComElQuery *q=rtcom_el_query_new(el); rtcom_el_query_prepare(q,"id",id.toString().remove("el").toInt(),RTCOM_EL_OP_EQUAL,NULL); RTComElIter *iter=rtcom_el_get_events(el,q); g_object_unref(q); if(iter && rtcom_el_iter_first(iter)) { gboolean res=rtcom_el_iter_get_full(iter,&ev); if(res) { #if 0 printf("got event id=%d service_id=%d event_typ_id=%d\n\ local_uid=%s local_name=%s\n\ remote_uid=%s remote_name=%s remote_ebook_uid=%s\n\ channel=%s free_text=%s group_uid=%s\n\ service=%s event_type=%s\n\ additional_text=%s icon_name=%s pango_markup=%s\n", ev.fld_id,ev.fld_service_id,ev.fld_event_type_id, ev.fld_local_uid,ev.fld_local_name, ev.fld_remote_uid,ev.fld_remote_name,ev.fld_remote_ebook_uid, ev.fld_channel,ev.fld_free_text,ev.fld_group_uid, ev.fld_service,ev.fld_event_type, ev.fld_additional_text,ev.fld_icon_name,ev.fld_pango_markup); #endif if (!strcmp(ev.fld_service, "RTCOM_EL_SERVICE_SMS")) { message.setType(QMessage::Sms); } else if (!strcmp(ev.fld_service,"RTCOM_EL_SERVICE_CHAT")) { message.setType(QMessage::InstantMessage); } else { message.setType(QMessage::NoType); // Other type, as exampele voice Call }; //QMessageAccount account = TelepathyEngine::instance()->account(QMessageAccountId(QString("/y/Account%1").arg(ev.fld_local_uid))); message.setParentAccountId(QMessageAccountId(QString("/y/Account/%1").arg(ev.fld_local_uid))); if (!ev.fld_is_read) { message.setStatus(QMessage::Read); }; message.setPriority(QMessage::NormalPriority); message.setDate(QDateTime::fromTime_t(ev.fld_start_time)); message.setReceivedDate(QDateTime::fromTime_t(ev.fld_start_time)); if (ev.fld_outgoing) QMessagePrivate::setStandardFolder(message,QMessage::SentFolder); else QMessagePrivate::setStandardFolder(message,QMessage::InboxFolder); if (ev.fld_outgoing) { // Outgoing message message.setFrom(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_local_uid))); QMessagePrivate::setSenderName(message, QString(ev.fld_local_uid)); message.setTo(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_remote_uid))); } else { // Incoming message message.setFrom(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_remote_uid))); QMessagePrivate::setSenderName(message, QString(ev.fld_remote_uid)); QMessageAddressList messageAddresslist; messageAddresslist.append(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_local_uid))); message.setTo(messageAddresslist); } message.setBody(QString::fromUtf8(ev.fld_free_text)); QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); privateMessage->_id = id; privateMessage->_modified = false; // qDebug() << "id:" << message.id().toString() << "From:" << message.from().addressee() << "Text:" << message.textContent(); }; }; if(iter) g_object_unref(iter); // debugMessage(message); MessageCache::instance()->insert(message); return message; } void EventLoggerEngine::debugMessage(QMessage &message) { qDebug() << "id:" << message.id().toString() << "type:" << message.type() << "size:" << message.size() << "status:" << message.status() << "priority:" << message.priority(); qDebug() << "AccountId:" << message.parentAccountId().toString() << "StantardFolder" << message.standardFolder() << "parenFolderId:" << message.parentFolderId().toString(); qDebug() << "Date:" << message.date() << "receivedDate:" << message.receivedDate() << "Subject:" << message.subject(); qDebug() << "From:" << message.from().addressee(); qDebug() << "To:" << (message.to().isEmpty() ? "**none**" : message.to().first().addressee()); qDebug() << "Body:" <message(QMessageId(QString("el")+QString::number(eventId))); if (msg.type() == QMessage::NoType) { matchingFilters.clear(); break; } else { messageRetrieved = true; } } if (privateMessageFilter->filter(msg)) { matchingFilters.insert(it.key()); } } } if (notificationType == QMessageStorePrivate::Updated) { // Remove updated message from cache to make sure that message // will be retrieved again from backend MessageCache::instance()->remove(QMessageId(QString("el")+QString::number(eventId))); } else if (notificationType == QMessageStorePrivate::Removed) { // Remove removed message from cache MessageCache::instance()->remove(QMessageId(QString("el")+QString::number(eventId))); } if (matchingFilters.count() > 0) { ipMessageStorePrivate->messageNotification(notificationType, QMessageId(QString("el")+QString::number(eventId)), matchingFilters); } } #if 0 QMessageIdList EventLoggerEngine::filterAndOrderMessages(const QMessageFilter &filter, const QMessageSortOrder& sortOrder, QString body, QMessageDataComparator::MatchFlags matchFlags) { filterAndOrderMessages(filte, sortOrder, body, matchFlags); } #endif bool EventLoggerEngine::filterMessages(QMessageServicePrivate* privateService, const QMessageFilter &filter, const QMessageSortOrder& sortOrder, QString body, QMessageDataComparator::MatchFlags matchFlags) { // qDebug() << "EventLoggerEngine::filterMessages"; if (active) { qWarning() << "EventLoggerEngine::filterMessages::Service is currently busy"; return false; } active = true; state = QMessageService::ActiveState; emit stateChanged(state); if(!queryThread) { queryThread=new QueryThread(); connect(queryThread, SIGNAL(completed()), this, SLOT(reportMatchingIds()), Qt::QueuedConnection); }; queryThread->setArgs(privateService, this, filter, body, matchFlags, sortOrder, 0,0); queryThread->start(); // return queryThread.queryMessages(filter,sortOrder,body,matchFlags); return true; } void EventLoggerEngine::messagesFound_(const QMessageIdList &ids) { // qDebug() << "EventLoggerEngine::messagesFound"; emit messagesFound(ids,true,false); // filtered but not sorted } void EventLoggerEngine::reportMatchingIds() { // qDebug() << "EventLoggerEngine::messagesFound" << m_ids.count(); QMetaObject::invokeMethod(queryThread->_privateService, "messagesFound", Qt::QueuedConnection, Q_ARG(const QMessageIdList, m_ids), Q_ARG(bool, true), Q_ARG(bool, false)); completed(); } void EventLoggerEngine::completed() { active = false; state = QMessageService::FinishedState; emit stateChanged(state); } QMessageIdList EventLoggerEngine::filterAndOrderMessages(const QMessageFilter &filter, const QMessageSortOrder& sortOrder, QString body, QMessageDataComparator::MatchFlags matchFlags) { Q_UNUSED(body); Q_UNUSED(matchFlags); Q_UNUSED(sortOrder); QMessageId fId; // Filtering id // QMessageType fType; QDate fDate; RTComElEvent ev; QMessage message; const char *services[]={"RTCOM_EL_SERVICE_CHAT","RTCOM_EL_SERVICE_SMS", NULL }; QMessageIdList idList; QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(filter); #if 0 if ((filters.count() == 1) && (pf->_field == QMessageFilterPrivate::None) && (pf->_filterList.count() == 0)) { if (pf->_notFilter) { // There is only one filter: empty ~QMessageFilter() // => return empty QMessageIdList return idList; } else { // There is only one filter: empty QMessageFilter() // => return all messages } } // Pre-filtering setup switch (pf->_field) { case QMessageFilterPrivate::Id: case QMessageFilterPrivate::ParentAccountId: { if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessageAccountId iNumberOfHandledFilters++; QMessageDataComparator::EqualityComparator cmp(static_cast(pf->_comparatorValue)); if (cmp == QMessageDataComparator::Equal) { QMessageAccount messageAccount = TelepathyEngine::instance()->account(QMessageAccountId(QString("/y/Account%1").arg(pf->_value.toString()))); } } } } #endif RTComElQuery *q=rtcom_el_query_new(el); rtcom_el_query_prepare(q,"service", services, RTCOM_EL_OP_IN_STRV, NULL); RTComElIter *iter=rtcom_el_get_events(el,q); g_object_unref(q); if(iter && rtcom_el_iter_first(iter)) do { bzero(&ev,sizeof(ev)); if(rtcom_el_iter_get_full(iter,&ev)) { message=eventToMessage(ev); // debugMessage(message); if (pf->filter(message)) { // qDebug() <<"Filter :filtering match" << message.id().toString(); //matchingFilters.insert(it.key()); MessageCache::instance()->insert(message); idList.append(message.id()); }; }; } while( rtcom_el_iter_next(iter)); #if 0 foreach(const QMessageId& id, idList) { qDebug() << "id=" << id.toString(); } #endif return idList; } QueryThread::QueryThread(): QThread() { } void QueryThread::setArgs(QMessageServicePrivate* privateService, EventLoggerEngine *parent, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) { _privateService = privateService; _parent=parent; _filter=filter; _body=body; _matchFlags=matchFlags; _sortOrder=sortOrder; _limit=limit; _offset=offset; } void QueryThread::run() { // qDebug() << "QueryThread::run()"; _parent->m_ids=EventLoggerEngine::instance()->filterAndOrderMessages(_filter,_sortOrder,_body,_matchFlags); // qDebug() << "QueryThread::run() done" << _parent->m_ids.count(); emit completed(); } #include "moc_eventloggerengine_maemo_p.cpp" QTM_END_NAMESPACE