File indexing completed on 2024-04-14 04:51:43

0001 /**
0002  * SPDX-FileCopyrightText: 2018 Simon Redman <simon@ergotech.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #ifndef PLUGINS_TELEPHONY_CONVERSATIONMESSAGE_H_
0008 #define PLUGINS_TELEPHONY_CONVERSATIONMESSAGE_H_
0009 
0010 #include <QDBusMetaType>
0011 
0012 #include "kdeconnectinterfaces_export.h"
0013 
0014 class ConversationAddress;
0015 class Attachment;
0016 
0017 class KDECONNECTINTERFACES_EXPORT ConversationMessage
0018 {
0019 public:
0020     // TYPE field values from Android
0021     enum Types {
0022         MessageTypeAll = 0,
0023         MessageTypeInbox = 1,
0024         MessageTypeSent = 2,
0025         MessageTypeDraft = 3,
0026         MessageTypeOutbox = 4,
0027         MessageTypeFailed = 5,
0028         MessageTypeQueued = 6,
0029     };
0030 
0031     /**
0032      * Values describing the possible type of events contained in a message
0033      * A message's eventField is constructed as a bitwise-OR of events
0034      * Any events which are unsupported should be ignored
0035      */
0036     enum Events {
0037         EventTextMessage = 0x1, // This message has a body field which contains pure, human-readable text
0038         EventMultiTarget = 0x2, // This is a multitarget (group) message which has an "addresses" field which is a list of participants in the group
0039     };
0040 
0041     /**
0042      * Build a new message from a keyword argument dictionary
0043      *
0044      * @param args mapping of field names to values as might be contained in a network packet containing a message
0045      */
0046     ConversationMessage(const QVariantMap &args = QVariantMap());
0047 
0048     ConversationMessage(const qint32 &eventField,
0049                         const QString &body,
0050                         const QList<ConversationAddress> &addresses,
0051                         const qint64 &date,
0052                         const qint32 &type,
0053                         const qint32 &read,
0054                         const qint64 &threadID,
0055                         const qint32 &uID,
0056                         const qint64 &subID,
0057                         const QList<Attachment> &attachments);
0058 
0059     static ConversationMessage fromDBus(const QDBusVariant &);
0060     static void registerDbusType();
0061 
0062     qint32 eventField() const
0063     {
0064         return m_eventField;
0065     }
0066     QString body() const
0067     {
0068         return m_body;
0069     }
0070     QList<ConversationAddress> addresses() const
0071     {
0072         return m_addresses;
0073     }
0074     qint64 date() const
0075     {
0076         return m_date;
0077     }
0078     qint32 type() const
0079     {
0080         return m_type;
0081     }
0082     qint32 read() const
0083     {
0084         return m_read;
0085     }
0086     qint64 threadID() const
0087     {
0088         return m_threadID;
0089     }
0090     qint32 uID() const
0091     {
0092         return m_uID;
0093     }
0094     qint64 subID() const
0095     {
0096         return m_subID;
0097     }
0098     QList<Attachment> attachments() const
0099     {
0100         return m_attachments;
0101     }
0102 
0103     bool containsTextBody() const
0104     {
0105         return (eventField() & ConversationMessage::EventTextMessage);
0106     }
0107     bool isMultitarget() const
0108     {
0109         return (eventField() & ConversationMessage::EventMultiTarget);
0110     }
0111 
0112     bool isIncoming() const
0113     {
0114         return type() == MessageTypeInbox;
0115     }
0116     bool isOutgoing() const;
0117     bool containsAttachment() const
0118     {
0119         return !attachments().isEmpty();
0120     }
0121 
0122     /**
0123      * Return the address of the other party of a single-target conversation
0124      * Calling this method with a multi-target conversation is ill-defined
0125      */
0126     QString getOtherPartyAddress() const;
0127 
0128 protected:
0129     /**
0130      * Bitwise OR of event flags
0131      * Unsupported flags shall cause the message to be ignored
0132      */
0133     qint32 m_eventField;
0134 
0135     /**
0136      * Body of the message
0137      */
0138     QString m_body;
0139 
0140     /**
0141      * List of all addresses involved in this conversation
0142      * An address is most likely a phone number, but may be something else like an email address
0143      */
0144     QList<ConversationAddress> m_addresses;
0145 
0146     /**
0147      * Date stamp (Unix epoch millis) associated with the message
0148      */
0149     qint64 m_date;
0150 
0151     /**
0152      * Type of the message. See the message.type enum
0153      */
0154     qint32 m_type;
0155 
0156     /**
0157      * Whether we have a read report for this message
0158      */
0159     qint32 m_read;
0160 
0161     /**
0162      * Tag which binds individual messages into a thread
0163      */
0164     qint64 m_threadID;
0165 
0166     /**
0167      * Value which uniquely identifies a message
0168      */
0169     qint32 m_uID;
0170 
0171     /**
0172      * Value which determines SIM id (optional)
0173      */
0174     qint64 m_subID;
0175 
0176     /**
0177      * Contains attachment related info of a MMS message (optional)
0178      */
0179     QList<Attachment> m_attachments;
0180 };
0181 
0182 class KDECONNECTINTERFACES_EXPORT ConversationAddress
0183 {
0184 public:
0185     ConversationAddress(QString address = QString());
0186 
0187     QString address() const
0188     {
0189         return m_address;
0190     }
0191 
0192 private:
0193     QString m_address;
0194 };
0195 
0196 class KDECONNECTINTERFACES_EXPORT Attachment
0197 {
0198 public:
0199     Attachment()
0200     {
0201     }
0202     Attachment(qint64 prtID, QString mimeType, QString base64EncodedFile, QString uniqueIdentifier);
0203 
0204     qint64 partID() const
0205     {
0206         return m_partID;
0207     }
0208     QString mimeType() const
0209     {
0210         return m_mimeType;
0211     }
0212     QString base64EncodedFile() const
0213     {
0214         return m_base64EncodedFile;
0215     }
0216     QString uniqueIdentifier() const
0217     {
0218         return m_uniqueIdentifier;
0219     }
0220 
0221 private:
0222     qint64 m_partID; // Part ID of the attachment of the message
0223     QString m_mimeType; // Type of attachment (image, video, audio etc.)
0224     QString m_base64EncodedFile; // Base64 encoded string of a file
0225     QString m_uniqueIdentifier; // unique name of the attachment
0226 };
0227 
0228 inline QDBusArgument &operator<<(QDBusArgument &argument, const ConversationMessage &message)
0229 {
0230     argument.beginStructure();
0231     argument << message.eventField() << message.body() << message.addresses() << message.date() << message.type() << message.read() << message.threadID()
0232              << message.uID() << message.subID() << message.attachments();
0233     argument.endStructure();
0234     return argument;
0235 }
0236 
0237 inline const QDBusArgument &operator>>(const QDBusArgument &argument, ConversationMessage &message)
0238 {
0239     qint32 event;
0240     QString body;
0241     QList<ConversationAddress> addresses;
0242     qint64 date;
0243     qint32 type;
0244     qint32 read;
0245     qint64 threadID;
0246     qint32 uID;
0247     qint64 m_subID;
0248     QList<Attachment> attachments;
0249 
0250     argument.beginStructure();
0251     argument >> event;
0252     argument >> body;
0253     argument >> addresses;
0254     argument >> date;
0255     argument >> type;
0256     argument >> read;
0257     argument >> threadID;
0258     argument >> uID;
0259     argument >> m_subID;
0260     argument >> attachments;
0261     argument.endStructure();
0262 
0263     message = ConversationMessage(event, body, addresses, date, type, read, threadID, uID, m_subID, attachments);
0264 
0265     return argument;
0266 }
0267 
0268 inline QDBusArgument &operator<<(QDBusArgument &argument, const ConversationAddress &address)
0269 {
0270     argument.beginStructure();
0271     argument << address.address();
0272     argument.endStructure();
0273     return argument;
0274 }
0275 
0276 inline const QDBusArgument &operator>>(const QDBusArgument &argument, ConversationAddress &address)
0277 {
0278     QString addressField;
0279 
0280     argument.beginStructure();
0281     argument >> addressField;
0282     argument.endStructure();
0283 
0284     address = ConversationAddress(addressField);
0285 
0286     return argument;
0287 }
0288 
0289 inline QDBusArgument &operator<<(QDBusArgument &argument, const Attachment &attachment)
0290 {
0291     argument.beginStructure();
0292     argument << attachment.partID() << attachment.mimeType() << attachment.base64EncodedFile() << attachment.uniqueIdentifier();
0293     argument.endStructure();
0294     return argument;
0295 }
0296 
0297 inline const QDBusArgument &operator>>(const QDBusArgument &argument, Attachment &attachment)
0298 {
0299     qint64 partID;
0300     QString mimeType;
0301     QString encodedFile;
0302     QString uniqueIdentifier;
0303 
0304     argument.beginStructure();
0305     argument >> partID;
0306     argument >> mimeType;
0307     argument >> encodedFile;
0308     argument >> uniqueIdentifier;
0309     argument.endStructure();
0310 
0311     attachment = Attachment(partID, mimeType, encodedFile, uniqueIdentifier);
0312 
0313     return argument;
0314 }
0315 
0316 Q_DECLARE_METATYPE(ConversationMessage)
0317 Q_DECLARE_METATYPE(ConversationAddress)
0318 Q_DECLARE_METATYPE(Attachment)
0319 
0320 #endif /* PLUGINS_TELEPHONY_CONVERSATIONMESSAGE_H_ */