Merge lp:~tiagosh/telephony-service/flag-mms into lp:telephony-service
- flag-mms
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Gustavo Pichorim Boiko | ||||
Approved revision: | 986 | ||||
Merged at revision: | 1012 | ||||
Proposed branch: | lp:~tiagosh/telephony-service/flag-mms | ||||
Merge into: | lp:telephony-service | ||||
Diff against target: |
1154 lines (+288/-135) 14 files modified
handler/TelephonyServiceHandler.client (+4/-0) handler/texthandler.cpp (+2/-5) indicator/TelephonyServiceIndicator.client (+4/-0) indicator/callchannelobserver.cpp (+1/-1) indicator/messagingmenu.cpp (+60/-26) indicator/messagingmenu.h (+6/-5) indicator/textchannelobserver.cpp (+96/-47) indicator/textchannelobserver.h (+6/-5) libtelephonyservice/accountentry.cpp (+23/-0) libtelephonyservice/accountentry.h (+4/-0) libtelephonyservice/chatmanager.cpp (+39/-30) libtelephonyservice/chatmanager.h (+8/-8) libtelephonyservice/telepathyhelper.cpp (+27/-7) libtelephonyservice/telepathyhelper.h (+8/-1) |
||||
To merge this branch: | bzr merge lp:~tiagosh/telephony-service/flag-mms | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gustavo Pichorim Boiko (community) | Approve | ||
PS Jenkins bot | continuous-integration | Needs Fixing | |
Review via email:
|
Commit message
Add initial MMS group chat support.
Description of the change
Add initial MMS group chat support.
--Checklist--
Are there any related MPs required for this MP to build/function as expected? Please list.
https:/
Is your branch in sync with latest trunk (e.g. bzr pull lp:trunk -> no changes)
Yes
Did you perform an exploratory manual test run of your code change and any related functionality on device or emulator?
Yes
Did you successfully run all tests found in your component's Test Plan (https:/
Yes
If you changed the UI, was the change specified/approved by design?
N/A
If you changed UI labels, did you update the pot file?
N/A
If you changed the packaging (debian), did you add a core-dev as a reviewer to this MP?
N/A
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
- 979. By Tiago Salem Herrmann
-
merge trunk
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:979
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 980. By Tiago Salem Herrmann
-
merge trunk
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:980
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 981. By Tiago Salem Herrmann
-
update property name
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:981
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Gustavo Pichorim Boiko (boiko) wrote : | # |
2 --- assets/
3 +++ assets/
This icon is already part of Suru icon theme, would you mind removing it from this MR?
/usr/share/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Gustavo Pichorim Boiko (boiko) wrote : | # |
280 + QUrl groupIconPath = QUrl::fromLocal
And as the icon is not local anymore, I think you can pass the icon name directly.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Gustavo Pichorim Boiko (boiko) wrote : | # |
Can you also revert the pot file changes?
- 982. By Tiago Salem Herrmann
-
use icon from theme
- 983. By Tiago Salem Herrmann
-
revert pot changes
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:983
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Gustavo Pichorim Boiko (boiko) wrote : | # |
195 + QString senderId = mMessages[
196 + QString accountId = mMessages[
197 + QStringList participantIds = mMessages[
Instead of looking up for the mMessages[
- 984. By Tiago Salem Herrmann
-
cache QVariantMap when using it multiple times
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Gustavo Pichorim Boiko (boiko) wrote : | # |
818 void ChatManager:
Would you mind also renaming phoneNumbers to recipients here too?
- 985. By Tiago Salem Herrmann
-
rename phoneNumber(s) to recipient(s)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:985
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 986. By Tiago Salem Herrmann
-
merge trunk
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:986
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Gustavo Pichorim Boiko (boiko) wrote : | # |
Did you perform an exploratory manual test run of the code change and any related functionality on device or emulator?
Yes
Did CI run pass? If not, please explain why.
No, but not related to the changes
Have you checked that submitter has accurately filled out the submitter checklist and has taken no shortcut?
Yes
Code looks good and works as expected!
Preview Diff
1 | === modified file 'handler/TelephonyServiceHandler.client' |
2 | --- handler/TelephonyServiceHandler.client 2014-02-11 20:55:19 +0000 |
3 | +++ handler/TelephonyServiceHandler.client 2015-02-05 12:16:44 +0000 |
4 | @@ -6,4 +6,8 @@ |
5 | org.freedesktop.Telepathy.Channel.TargetHandleType u=1 |
6 | |
7 | [org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 1] |
8 | +org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text |
9 | +org.freedesktop.Telepathy.Channel.TargetHandleType u=0 |
10 | + |
11 | +[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 2] |
12 | org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Call1 |
13 | |
14 | === modified file 'handler/texthandler.cpp' |
15 | --- handler/texthandler.cpp 2015-01-06 18:50:18 +0000 |
16 | +++ handler/texthandler.cpp 2015-02-05 12:16:44 +0000 |
17 | @@ -50,11 +50,6 @@ |
18 | </body>\ |
19 | </smil>" |
20 | |
21 | -template<> bool qMapLessThanKey<QStringList>(const QStringList &key1, const QStringList &key2) |
22 | -{ |
23 | - return key1.size() > key2.size(); // sort by operator> ! |
24 | -} |
25 | - |
26 | TextHandler::TextHandler(QObject *parent) |
27 | : QObject(parent) |
28 | { |
29 | @@ -146,6 +141,8 @@ |
30 | bool hasImage = false, hasText = false; |
31 | |
32 | header["message-type"] = QDBusVariant(0); |
33 | + // FIXME: make this conditional once we add support for other IM protocols |
34 | + header["mms"] = QDBusVariant(true); |
35 | message << header; |
36 | Q_FOREACH(const AttachmentStruct &attachment, attachments) { |
37 | QByteArray fileData; |
38 | |
39 | === modified file 'indicator/TelephonyServiceIndicator.client' |
40 | --- indicator/TelephonyServiceIndicator.client 2014-05-14 21:49:27 +0000 |
41 | +++ indicator/TelephonyServiceIndicator.client 2015-02-05 12:16:44 +0000 |
42 | @@ -10,6 +10,10 @@ |
43 | org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text |
44 | org.freedesktop.Telepathy.Channel.TargetHandleType u=1 |
45 | |
46 | +[org.freedesktop.Telepathy.Client.Observer.ObserverChannelFilter 2] |
47 | +org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text |
48 | +org.freedesktop.Telepathy.Channel.TargetHandleType u=0 |
49 | + |
50 | [org.freedesktop.Telepathy.Client.Observer.Capabilities] |
51 | org.freedesktop.Telepathy.Channel.Type.Call1/audio=true |
52 | org.freedesktop.Telepathy.Channel.Type.Call1/audio/speex=true |
53 | |
54 | === modified file 'indicator/callchannelobserver.cpp' |
55 | --- indicator/callchannelobserver.cpp 2014-07-22 03:17:01 +0000 |
56 | +++ indicator/callchannelobserver.cpp 2015-02-05 12:16:44 +0000 |
57 | @@ -73,7 +73,7 @@ |
58 | // add the missed call to the messaging menu |
59 | if (missed) { |
60 | // FIXME: handle conf call |
61 | - MessagingMenu::instance()->addCall(channel->targetContact()->id(), QDateTime::currentDateTime()); |
62 | + MessagingMenu::instance()->addCall(channel->targetContact()->id(), accountEntry->accountId(), QDateTime::currentDateTime()); |
63 | } else { |
64 | // and show a notification |
65 | // FIXME: handle conf call |
66 | |
67 | === modified file 'indicator/messagingmenu.cpp' |
68 | --- indicator/messagingmenu.cpp 2014-11-04 20:47:36 +0000 |
69 | +++ indicator/messagingmenu.cpp 2015-02-05 12:16:44 +0000 |
70 | @@ -61,9 +61,9 @@ |
71 | g_object_unref(icon); |
72 | } |
73 | |
74 | -void MessagingMenu::addFlashMessage(const QString &phoneNumber, const QString &messageId, const QDateTime ×tamp, const QString &text) { |
75 | +void MessagingMenu::addFlashMessage(const QString &senderId, const QString &accountId, const QString &messageId, const QDateTime ×tamp, const QString &text) { |
76 | QUrl iconPath = QUrl::fromLocalFile(telephonyServiceDir() + "/assets/avatar-default@18.png"); |
77 | - QString contactAlias = phoneNumber; |
78 | + QString contactAlias = senderId; |
79 | GFile *file = g_file_new_for_uri(iconPath.toString().toUtf8().data()); |
80 | GIcon *icon = g_file_icon_new(file); |
81 | |
82 | @@ -90,7 +90,8 @@ |
83 | |
84 | g_signal_connect(message, "activate", G_CALLBACK(&MessagingMenu::flashMessageActivateCallback), this); |
85 | QVariantMap details; |
86 | - details["phoneNumber"] = phoneNumber; |
87 | + details["senderId"] = senderId; |
88 | + details["accountId"] = accountId; |
89 | details["messageId"] = messageId; |
90 | details["timestamp"] = timestamp; |
91 | details["text"] = text; |
92 | @@ -103,25 +104,30 @@ |
93 | |
94 | } |
95 | |
96 | -void MessagingMenu::addMessage(const QString &phoneNumber, const QString &messageId, const QDateTime ×tamp, const QString &text) |
97 | +void MessagingMenu::addMessage(const QString &senderId, const QStringList &participantIds, const QString &accountId, const QString &messageId, const QDateTime ×tamp, const QString &text) |
98 | { |
99 | // try to get a contact for that phone number |
100 | QUrl iconPath = QUrl::fromLocalFile(telephonyServiceDir() + "/assets/avatar-default@18.png"); |
101 | - QString contactAlias = phoneNumber; |
102 | + QString contactAlias = senderId; |
103 | |
104 | // try to match the contact info |
105 | QContactFetchRequest *request = new QContactFetchRequest(this); |
106 | - request->setFilter(QContactPhoneNumber::match(phoneNumber)); |
107 | + request->setFilter(QContactPhoneNumber::match(senderId)); |
108 | |
109 | // place the messaging-menu item only after the contact fetch request is finished, as we can´t simply update |
110 | QObject::connect(request, &QContactAbstractRequest::stateChanged, |
111 | - [request, phoneNumber, messageId, text, timestamp, iconPath, contactAlias, this]() { |
112 | + [request, senderId, participantIds, accountId, messageId, text, timestamp, iconPath, contactAlias, this]() { |
113 | + |
114 | + GFile *file = NULL; |
115 | + GIcon *icon = NULL; |
116 | + |
117 | // only process the results after the finished state is reached |
118 | if (request->state() != QContactAbstractRequest::FinishedState) { |
119 | return; |
120 | } |
121 | |
122 | QString displayLabel; |
123 | + QString subTitle; |
124 | QUrl avatar; |
125 | |
126 | if (request->contacts().size() > 0) { |
127 | @@ -134,16 +140,22 @@ |
128 | displayLabel = contactAlias; |
129 | } |
130 | |
131 | + if (participantIds.size() > 1) { |
132 | + icon = g_themed_icon_new("contact-group"); |
133 | + } |
134 | + |
135 | if (avatar.isEmpty()) { |
136 | avatar = iconPath; |
137 | } |
138 | |
139 | - GFile *file = g_file_new_for_uri(avatar.toString().toUtf8().data()); |
140 | - GIcon *icon = g_file_icon_new(file); |
141 | + if (!icon) { |
142 | + file = g_file_new_for_uri(avatar.toString().toUtf8().data()); |
143 | + icon = g_file_icon_new(file); |
144 | + } |
145 | MessagingMenuMessage *message = messaging_menu_message_new(messageId.toUtf8().data(), |
146 | icon, |
147 | displayLabel.toUtf8().data(), |
148 | - NULL, |
149 | + subTitle.toUtf8().data(), |
150 | text.toUtf8().data(), |
151 | timestamp.toMSecsSinceEpoch() * 1000); // the value is expected to be in microseconds |
152 | messaging_menu_message_add_action(message, |
153 | @@ -156,12 +168,16 @@ |
154 | |
155 | // save the phone number to use in the actions |
156 | QVariantMap details; |
157 | - details["phoneNumber"] = phoneNumber; |
158 | + details["senderId"] = senderId; |
159 | + details["accountId"] = accountId; |
160 | + details["participantIds"] = participantIds; |
161 | |
162 | mMessages[messageId] = details; |
163 | messaging_menu_app_append_message(mMessagesApp, message, SOURCE_ID, true); |
164 | |
165 | - g_object_unref(file); |
166 | + if (file) { |
167 | + g_object_unref(file); |
168 | + } |
169 | g_object_unref(icon); |
170 | g_object_unref(message); |
171 | }); |
172 | @@ -226,7 +242,7 @@ |
173 | g_object_unref(message); |
174 | } |
175 | |
176 | -void MessagingMenu::addCall(const QString &phoneNumber, const QDateTime ×tamp) |
177 | +void MessagingMenu::addCall(const QString &phoneNumber, const QString &accountId, const QDateTime ×tamp) |
178 | { |
179 | Call call; |
180 | bool found = false; |
181 | @@ -244,6 +260,7 @@ |
182 | |
183 | if (!found) { |
184 | call.contactAlias = phoneNumber; |
185 | + call.accountId = accountId; |
186 | call.contactIcon = QUrl::fromLocalFile(telephonyServiceDir() + "/assets/avatar-default@18.png"); |
187 | call.number = phoneNumber; |
188 | call.count = 0; |
189 | @@ -376,25 +393,33 @@ |
190 | |
191 | void MessagingMenu::sendMessageReply(const QString &messageId, const QString &reply) |
192 | { |
193 | - QString phoneNumber = mMessages[messageId]["phoneNumber"].toString(); |
194 | - Q_EMIT replyReceived(phoneNumber, reply); |
195 | + QVariantMap message = mMessages[messageId]; |
196 | + QString senderId = message["senderId"].toString(); |
197 | + QString accountId = message["accountId"].toString(); |
198 | + QStringList participantIds = message["participantIds"].toStringList(); |
199 | + QStringList recipients; |
200 | + if (!senderId.isEmpty()) { |
201 | + recipients << senderId; |
202 | + } |
203 | + recipients << participantIds; |
204 | + recipients.removeDuplicates(); |
205 | + Q_EMIT replyReceived(recipients, accountId, reply); |
206 | |
207 | - Q_EMIT messageRead(phoneNumber, messageId); |
208 | + Q_EMIT messageRead(recipients, accountId, messageId); |
209 | } |
210 | |
211 | void MessagingMenu::saveFlashMessage(const QString &messageId) |
212 | { |
213 | QVariantMap details = mMessages[messageId]; |
214 | - // TODO: handle dual sim |
215 | - History::Thread thread = History::Manager::instance()->threadForParticipants(TelepathyHelper::instance()->accountIds()[0], |
216 | + History::Thread thread = History::Manager::instance()->threadForParticipants(details["accountId"].toString(), |
217 | History::EventTypeText, |
218 | - QStringList() << details["phoneNumber"].toString(), |
219 | + QStringList() << details["senderId"].toString(), |
220 | History::MatchPhoneNumber, |
221 | true); |
222 | - History::TextEvent textEvent(TelepathyHelper::instance()->accountIds()[0], |
223 | + History::TextEvent textEvent(details["accountId"].toString(), |
224 | thread.threadId(), |
225 | details["messageId"].toString(), |
226 | - details["phoneNumber"].toString(), |
227 | + details["senderId"].toString(), |
228 | details["timestamp"].toDateTime(), |
229 | false, |
230 | details["text"].toString(), |
231 | @@ -407,8 +432,17 @@ |
232 | |
233 | void MessagingMenu::showMessage(const QString &messageId) |
234 | { |
235 | - QString phoneNumber = mMessages[messageId]["phoneNumber"].toString(); |
236 | - ApplicationUtils::openUrl(QString("message:///%1").arg(QString(QUrl::toPercentEncoding(phoneNumber)))); |
237 | + QVariantMap message = mMessages[messageId]; |
238 | + QString senderId = message["senderId"].toString(); |
239 | + QStringList participantIds = message["participantIds"].toStringList(); |
240 | + QStringList recipients; |
241 | + if (!senderId.isEmpty()) { |
242 | + recipients << senderId; |
243 | + } |
244 | + recipients << participantIds; |
245 | + recipients.removeDuplicates(); |
246 | + |
247 | + ApplicationUtils::openUrl(QString("message:///%1").arg(QString(QUrl::toPercentEncoding(recipients.join(";"))))); |
248 | } |
249 | |
250 | void MessagingMenu::callBack(const QString &messageId) |
251 | @@ -420,9 +454,9 @@ |
252 | |
253 | void MessagingMenu::replyWithMessage(const QString &messageId, const QString &reply) |
254 | { |
255 | - QString phoneNumber = callFromMessageId(messageId).number; |
256 | - qDebug() << "TelephonyService/MessagingMenu: Replying to call" << phoneNumber << "with text" << reply; |
257 | - Q_EMIT replyReceived(phoneNumber, reply); |
258 | + Call call = callFromMessageId(messageId); |
259 | + qDebug() << "TelephonyService/MessagingMenu: Replying to call" << call.number << "with text" << reply; |
260 | + Q_EMIT replyReceived(QStringList() << call.number, call.accountId, reply); |
261 | } |
262 | |
263 | void MessagingMenu::callVoicemail(const QString &messageId) |
264 | |
265 | === modified file 'indicator/messagingmenu.h' |
266 | --- indicator/messagingmenu.h 2014-09-16 10:45:43 +0000 |
267 | +++ indicator/messagingmenu.h 2015-02-05 12:16:44 +0000 |
268 | @@ -37,6 +37,7 @@ |
269 | QString contactAlias; |
270 | QUrl contactIcon; |
271 | QString messageId; |
272 | + QString accountId; |
273 | QDateTime timestamp; |
274 | |
275 | bool operator==(const Call &other) { |
276 | @@ -51,11 +52,11 @@ |
277 | static MessagingMenu *instance(); |
278 | virtual ~MessagingMenu(); |
279 | |
280 | - void addMessage(const QString &phoneNumber, const QString &messageId, const QDateTime ×tamp, const QString &text); |
281 | - void addFlashMessage(const QString &phoneNumber, const QString &messageId, const QDateTime ×tamp, const QString &text); |
282 | + void addMessage(const QString &senderId, const QStringList &participantIds, const QString &accountId, const QString &messageId, const QDateTime ×tamp, const QString &text); |
283 | + void addFlashMessage(const QString &senderId, const QString &accountId, const QString &messageId, const QDateTime ×tamp, const QString &text); |
284 | void removeMessage(const QString &messageId); |
285 | |
286 | - void addCall(const QString &phoneNumber, const QDateTime ×tamp); |
287 | + void addCall(const QString &phoneNumber, const QString &accountId, const QDateTime ×tamp); |
288 | void addCallToMessagingMenu(Call call, const QString &text); |
289 | |
290 | static void flashMessageActivateCallback(MessagingMenuMessage *message, const char *actionId, GVariant *param, MessagingMenu *instance); |
291 | @@ -66,8 +67,8 @@ |
292 | void hideVoicemailEntry(AccountEntry *account); |
293 | |
294 | Q_SIGNALS: |
295 | - void replyReceived(const QString &phoneNumber, const QString &reply); |
296 | - void messageRead(const QString &phoneNumber, const QString &messageId); |
297 | + void replyReceived(const QStringList &recipients, const QString &accountId, const QString &reply); |
298 | + void messageRead(const QStringList &phoneNumber, const QString &accountId, const QString &messageId); |
299 | |
300 | private Q_SLOTS: |
301 | void sendMessageReply(const QString &messageId, const QString &reply); |
302 | |
303 | === modified file 'indicator/textchannelobserver.cpp' |
304 | --- indicator/textchannelobserver.cpp 2014-11-21 17:29:36 +0000 |
305 | +++ indicator/textchannelobserver.cpp 2015-02-05 12:16:44 +0000 |
306 | @@ -52,7 +52,9 @@ |
307 | |
308 | class NotificationData { |
309 | public: |
310 | - QString phoneNumber; |
311 | + QString senderId; |
312 | + QStringList participantIds; |
313 | + QString accountId; |
314 | QDateTime timestamp; |
315 | QString text; |
316 | QString eventId; |
317 | @@ -68,10 +70,12 @@ |
318 | { |
319 | GError *error = NULL; |
320 | QString accountId = action; |
321 | - qDebug() << accountId << data; |
322 | NotificationData *notificationData = (NotificationData*) data; |
323 | if (notificationData != NULL) { |
324 | - notificationData->observer->sendMessage(QStringList() << notificationData->phoneNumber, notificationData->text, accountId); |
325 | + QStringList recipients; |
326 | + recipients << notificationData->participantIds; |
327 | + recipients.removeDuplicates(); |
328 | + notificationData->observer->sendMessage(recipients, notificationData->text, accountId); |
329 | } |
330 | |
331 | notify_notification_close(notification, &error); |
332 | @@ -84,26 +88,26 @@ |
333 | if (action == QLatin1String("notification_save_action")) { |
334 | NotificationData *notificationData = (NotificationData*) data; |
335 | if (notificationData != NULL) { |
336 | - // FIXME: handle multiple accounts |
337 | - History::Thread thread = History::Manager::instance()->threadForParticipants(TelepathyHelper::instance()->accountIds()[0], |
338 | + QStringList recipients; |
339 | + recipients << notificationData->senderId << notificationData->participantIds; |
340 | + History::Thread thread = History::Manager::instance()->threadForParticipants(notificationData->accountId, |
341 | History::EventTypeText, |
342 | - QStringList() << notificationData->phoneNumber, |
343 | + recipients, |
344 | History::MatchPhoneNumber, |
345 | true); |
346 | - History::TextEvent textEvent(TelepathyHelper::instance()->accountIds()[0], |
347 | + History::TextEvent textEvent(notificationData->accountId, |
348 | thread.threadId(), |
349 | notificationData->eventId, |
350 | - notificationData->phoneNumber, |
351 | + notificationData->senderId, |
352 | notificationData->timestamp, |
353 | false, |
354 | notificationData->text, |
355 | History::MessageTypeText); |
356 | History::Events events; |
357 | events.append(textEvent); |
358 | - |
359 | + |
360 | History::Manager::instance()->writeEvents(events); |
361 | } |
362 | - |
363 | } |
364 | notify_notification_close(notification, &error); |
365 | |
366 | @@ -119,7 +123,13 @@ |
367 | NotificationData *notificationData = (NotificationData*) data; |
368 | if (notificationData != NULL) { |
369 | // launch the messaging-app to show the message |
370 | - ApplicationUtils::openUrl(QString("message:///%1").arg(QString(QUrl::toPercentEncoding(notificationData->phoneNumber)))); |
371 | + QStringList recipients; |
372 | + if (!notificationData->senderId.isEmpty()) { |
373 | + recipients << notificationData->senderId; |
374 | + } |
375 | + recipients << notificationData->participantIds; |
376 | + recipients.removeDuplicates(); |
377 | + ApplicationUtils::openUrl(QString("message:///%1").arg(QString(QUrl::toPercentEncoding(recipients.join(";"))))); |
378 | notification_closed(notification, notificationData->notificationList); |
379 | } |
380 | g_object_unref(notification); |
381 | @@ -137,11 +147,11 @@ |
382 | QObject(parent) |
383 | { |
384 | connect(MessagingMenu::instance(), |
385 | - SIGNAL(replyReceived(QString,QString)), |
386 | - SLOT(onReplyReceived(QString,QString))); |
387 | + SIGNAL(replyReceived(QStringList,QString,QString)), |
388 | + SLOT(onReplyReceived(QStringList,QString,QString))); |
389 | connect(MessagingMenu::instance(), |
390 | - SIGNAL(messageRead(QString,QString)), |
391 | - SLOT(onMessageRead(QString,QString))); |
392 | + SIGNAL(messageRead(QStringList,QString,QString)), |
393 | + SLOT(onMessageRead(QStringList,QString,QString))); |
394 | |
395 | if (GreeterContacts::isGreeterMode()) { |
396 | connect(GreeterContacts::instance(), SIGNAL(contactUpdated(QtContacts::QContact)), |
397 | @@ -162,7 +172,7 @@ |
398 | mNotifications.clear(); |
399 | } |
400 | |
401 | -void TextChannelObserver::sendMessage(const QStringList &phoneNumbers, const QString &text, const QString &accountId) |
402 | +void TextChannelObserver::sendMessage(const QStringList &recipients, const QString &text, const QString &accountId) |
403 | { |
404 | AccountEntry *account = TelepathyHelper::instance()->accountForId(accountId); |
405 | if (!account || accountId.isEmpty()) { |
406 | @@ -183,7 +193,7 @@ |
407 | if (!account->connected()) { |
408 | History::Thread thread = History::Manager::instance()->threadForParticipants(account->accountId(), |
409 | History::EventTypeText, |
410 | - phoneNumbers, |
411 | + recipients, |
412 | History::MatchPhoneNumber, |
413 | true); |
414 | History::TextEvent textEvent(account->accountId(), |
415 | @@ -212,11 +222,15 @@ |
416 | |
417 | // notify user about the failure |
418 | GIcon *icon = g_themed_icon_new("cancel"); |
419 | + gchar *iconPath = g_icon_to_string(icon); |
420 | NotifyNotification *notification = notify_notification_new(C::gettext("The message could not be sent"), |
421 | failureMessage.toStdString().c_str(), |
422 | - g_icon_to_string(icon)); |
423 | + iconPath); |
424 | + g_object_unref(icon); |
425 | + g_free(iconPath); |
426 | NotificationData *data = new NotificationData(); |
427 | - data->phoneNumber = phoneNumbers[0]; |
428 | + data->participantIds = recipients; |
429 | + data->accountId = account->accountId(); |
430 | data->message = text; |
431 | data->notificationList = &mNotifications; |
432 | mNotifications.insert(notification, data); |
433 | @@ -244,14 +258,14 @@ |
434 | return; |
435 | } |
436 | |
437 | - ChatManager::instance()->sendMessage(phoneNumbers, text, accountId); |
438 | + ChatManager::instance()->sendMessage(recipients, text, accountId); |
439 | } |
440 | |
441 | -void TextChannelObserver::showNotificationForFlashMessage(const Tp::ReceivedMessage &message) |
442 | +void TextChannelObserver::showNotificationForFlashMessage(const Tp::ReceivedMessage &message, const QString &accountId) |
443 | { |
444 | Tp::ContactPtr contact = message.sender(); |
445 | QByteArray token(message.messageToken().toUtf8()); |
446 | - MessagingMenu::instance()->addFlashMessage(contact->id(), token.toHex(), message.received(), message.text()); |
447 | + MessagingMenu::instance()->addFlashMessage(contact->id(), accountId, token.toHex(), message.received(), message.text()); |
448 | |
449 | |
450 | // show the notification |
451 | @@ -259,7 +273,8 @@ |
452 | message.text().toStdString().c_str(), |
453 | ""); |
454 | NotificationData *data = new NotificationData(); |
455 | - data->phoneNumber = contact->id(); |
456 | + data->senderId = contact->id(); |
457 | + data->accountId = accountId; |
458 | data->timestamp = message.received(); |
459 | data->text = message.text(); |
460 | data->eventId = message.messageToken().toUtf8(); |
461 | @@ -296,19 +311,19 @@ |
462 | Ringtone::instance()->playIncomingMessageSound(); |
463 | } |
464 | |
465 | -void TextChannelObserver::triggerNotificationForMessage(const Tp::ReceivedMessage &message) |
466 | +void TextChannelObserver::triggerNotificationForMessage(const Tp::ReceivedMessage &message, const QString &accountId, const QStringList &participantIds) |
467 | { |
468 | Tp::ContactPtr contact = message.sender(); |
469 | if (GreeterContacts::isGreeterMode()) { // we're in the greeter's session |
470 | GreeterContacts::instance()->setContactFilter(QContactPhoneNumber::match(contact->id())); |
471 | // in greeter mode we show the notification right away as the contact data might not be received |
472 | - showNotificationForMessage(message); |
473 | + showNotificationForMessage(message, accountId, participantIds); |
474 | } else { |
475 | // try to match the contact info |
476 | QContactFetchRequest *request = new QContactFetchRequest(this); |
477 | request->setFilter(QContactPhoneNumber::match(contact->id())); |
478 | |
479 | - QObject::connect(request, &QContactAbstractRequest::stateChanged, [this, request, message]() { |
480 | + QObject::connect(request, &QContactAbstractRequest::stateChanged, [this, request, accountId, participantIds, message]() { |
481 | // only process the results after the finished state is reached |
482 | if (request->state() != QContactAbstractRequest::FinishedState) { |
483 | return; |
484 | @@ -323,7 +338,7 @@ |
485 | GreeterContacts::emitContact(contact); |
486 | } |
487 | // wait for the contact match request to finish before showing the notification |
488 | - showNotificationForMessage(message, contact); |
489 | + showNotificationForMessage(message, accountId, participantIds, contact); |
490 | }); |
491 | |
492 | request->setManager(ContactUtils::sharedManager()); |
493 | @@ -332,14 +347,14 @@ |
494 | |
495 | } |
496 | |
497 | -void TextChannelObserver::showNotificationForMessage(const Tp::ReceivedMessage &message, const QContact &contact) |
498 | +void TextChannelObserver::showNotificationForMessage(const Tp::ReceivedMessage &message, const QString &accountId, const QStringList &participantIds, const QContact &contact) |
499 | { |
500 | Tp::ContactPtr telepathyContact = message.sender(); |
501 | QString messageText = message.text(); |
502 | |
503 | Tp::MessagePartList messageParts = message.parts(); |
504 | - // check if this is an mms |
505 | - if (messageParts.size() > 2) { |
506 | + bool mms = message.header()["mms"].variant().toBool(); |
507 | + if (mms) { |
508 | // remove header |
509 | messageParts.pop_front(); |
510 | Q_FOREACH(const Tp::MessagePart &part, messageParts) { |
511 | @@ -373,7 +388,7 @@ |
512 | return; |
513 | } |
514 | |
515 | - MessagingMenu::instance()->addMessage(telepathyContact->id(), token.toHex(), message.received(), messageText); |
516 | + MessagingMenu::instance()->addMessage(telepathyContact->id(), participantIds, accountId, token.toHex(), message.received(), messageText); |
517 | |
518 | QString alias; |
519 | QString avatar; |
520 | @@ -390,8 +405,15 @@ |
521 | avatar = QUrl(telephonyServiceDir() + "assets/avatar-default@18.png").toEncoded(); |
522 | } |
523 | |
524 | - QString title = QString::fromUtf8(C::gettext("Message from %1")).arg(alias); |
525 | - |
526 | + QString title; |
527 | + if (participantIds.size() > 1) { |
528 | + title = QString::fromUtf8(C::gettext("Message to group from %1")).arg(alias); |
529 | + GIcon *icon = g_themed_icon_new("contact-group"); |
530 | + avatar = g_icon_to_string(icon); |
531 | + g_object_unref(icon); |
532 | + } else { |
533 | + title = QString::fromUtf8(C::gettext("Message from %1")).arg(alias); |
534 | + } |
535 | // show the notification |
536 | NotifyNotification *notification = notify_notification_new(title.toStdString().c_str(), |
537 | messageText.toStdString().c_str(), |
538 | @@ -399,7 +421,9 @@ |
539 | |
540 | // Bundle the data we need for later updating |
541 | NotificationData *data = new NotificationData(); |
542 | - data->phoneNumber = telepathyContact->id(); |
543 | + data->accountId = accountId; |
544 | + data->senderId = telepathyContact->id(); |
545 | + data->participantIds = participantIds; |
546 | data->alias = alias; |
547 | data->message = messageText; |
548 | data->notificationList = &mNotifications; |
549 | @@ -435,7 +459,7 @@ |
550 | NotifyNotification *notification = i.key(); |
551 | NotificationData *data = i.value(); |
552 | Q_FOREACH(const QContactPhoneNumber phoneNumber, contact.details(QContactDetail::TypePhoneNumber)) { |
553 | - if (PhoneUtils::comparePhoneNumbers(data->phoneNumber, phoneNumber.number())) { |
554 | + if (PhoneUtils::comparePhoneNumbers(data->senderId, phoneNumber.number())) { |
555 | QString displayLabel = contact.detail<QContactDisplayLabel>().label(); |
556 | QString title = QString::fromUtf8(C::gettext("Message from %1")).arg(displayLabel.isEmpty() ? data->alias : displayLabel); |
557 | QString avatar = contact.detail<QContactAvatar>().imageUrl().toEncoded(); |
558 | @@ -478,11 +502,14 @@ |
559 | |
560 | if (textChannel->immutableProperties().contains(TP_QT_IFACE_CHANNEL_INTERFACE_SMS + QLatin1String(".Flash")) && |
561 | textChannel->immutableProperties()[TP_QT_IFACE_CHANNEL_INTERFACE_SMS + QLatin1String(".Flash")].toBool()) { |
562 | - |
563 | + AccountEntry *account = TelepathyHelper::instance()->accountForConnection(textChannel->connection()); |
564 | + if (!account) { |
565 | + return; |
566 | + } |
567 | // class 0 sms |
568 | mFlashChannels.append(textChannel); |
569 | Q_FOREACH(Tp::ReceivedMessage message, textChannel->messageQueue()) { |
570 | - showNotificationForFlashMessage(message); |
571 | + showNotificationForFlashMessage(message, account->accountId()); |
572 | } |
573 | return; |
574 | } else { |
575 | @@ -490,7 +517,7 @@ |
576 | } |
577 | // notify all the messages from the channel |
578 | Q_FOREACH(Tp::ReceivedMessage message, textChannel->messageQueue()) { |
579 | - onMessageReceived(message); |
580 | + processMessageReceived(message, textChannel); |
581 | } |
582 | } |
583 | |
584 | @@ -501,15 +528,29 @@ |
585 | mFlashChannels.removeAll(textChannel); |
586 | } |
587 | |
588 | -void TextChannelObserver::onMessageReceived(const Tp::ReceivedMessage &message) |
589 | +void TextChannelObserver::processMessageReceived(const Tp::ReceivedMessage &message, const Tp::TextChannelPtr &textChannel) |
590 | { |
591 | - Tp::TextChannelPtr textChannel(qobject_cast<Tp::TextChannel*>(sender())); |
592 | + if (textChannel.isNull()) { |
593 | + qDebug() << "TextChannelObserver::processMessageReceived: no text channel"; |
594 | + return; |
595 | + } |
596 | + |
597 | + AccountEntry *account = TelepathyHelper::instance()->accountForConnection(textChannel->connection()); |
598 | + if (!account) { |
599 | + return; |
600 | + } |
601 | + |
602 | // do not place notification items for scrollback messages |
603 | if (mFlashChannels.contains(textChannel) && !message.isScrollback() && !message.isDeliveryReport() && !message.isRescued()) { |
604 | - showNotificationForFlashMessage(message); |
605 | + showNotificationForFlashMessage(message, account->accountId()); |
606 | return; |
607 | } |
608 | |
609 | + QStringList participantIds; |
610 | + Q_FOREACH(const Tp::ContactPtr &contact, textChannel->groupContacts(false)) { |
611 | + participantIds << contact->id(); |
612 | + } |
613 | + |
614 | if (!message.isScrollback() && !message.isDeliveryReport() && !message.isRescued()) { |
615 | QTimer *timer = new QTimer(this); |
616 | timer->setInterval(1500); |
617 | @@ -517,7 +558,7 @@ |
618 | QByteArray token(message.messageToken().toUtf8()); |
619 | mUnreadMessages.append(token); |
620 | QObject::connect(timer, &QTimer::timeout, [=]() { |
621 | - triggerNotificationForMessage(message); |
622 | + triggerNotificationForMessage(message, account->accountId(), participantIds); |
623 | Metrics::instance()->increment(Metrics::ReceivedMessages); |
624 | timer->deleteLater(); |
625 | }); |
626 | @@ -525,6 +566,12 @@ |
627 | } |
628 | } |
629 | |
630 | +void TextChannelObserver::onMessageReceived(const Tp::ReceivedMessage &message) |
631 | +{ |
632 | + Tp::TextChannelPtr textChannel(qobject_cast<Tp::TextChannel*>(sender())); |
633 | + processMessageReceived(message, textChannel); |
634 | +} |
635 | + |
636 | void TextChannelObserver::onPendingMessageRemoved(const Tp::ReceivedMessage &message) |
637 | { |
638 | QByteArray token(message.messageToken().toUtf8()); |
639 | @@ -532,7 +579,7 @@ |
640 | MessagingMenu::instance()->removeMessage(token.toHex()); |
641 | } |
642 | |
643 | -void TextChannelObserver::onReplyReceived(const QString &phoneNumber, const QString &reply) |
644 | +void TextChannelObserver::onReplyReceived(const QStringList &recipients, const QString &accountId, const QString &reply) |
645 | { |
646 | // FIXME - we need to find a better way to deal with dual sim in the messaging-menu |
647 | if (!TelepathyHelper::instance()->defaultMessagingAccount() && TelepathyHelper::instance()->activeAccounts().size() > 1) { |
648 | @@ -540,7 +587,8 @@ |
649 | reply.toStdString().c_str(), |
650 | ""); |
651 | NotificationData *data = new NotificationData(); |
652 | - data->phoneNumber = phoneNumber; |
653 | + data->participantIds = recipients; |
654 | + data->accountId = accountId; |
655 | data->text = reply; |
656 | data->observer = this; |
657 | mNotifications.insert(notification, data); |
658 | @@ -567,13 +615,14 @@ |
659 | return; |
660 | } |
661 | |
662 | - sendMessage(QStringList() << phoneNumber, reply, ""); |
663 | + // FIXME: for now we dont specify any accountId |
664 | + sendMessage(recipients, reply, ""); |
665 | } |
666 | |
667 | -void TextChannelObserver::onMessageRead(const QString &phoneNumber, const QString &encodedMessageId) |
668 | +void TextChannelObserver::onMessageRead(const QStringList &recipients, const QString &accountId, const QString &encodedMessageId) |
669 | { |
670 | QString messageId(QByteArray::fromHex(encodedMessageId.toUtf8())); |
671 | - ChatManager::instance()->acknowledgeMessage(phoneNumber, messageId); |
672 | + ChatManager::instance()->acknowledgeMessage(recipients, messageId, accountId); |
673 | } |
674 | |
675 | void TextChannelObserver::onMessageSent(Tp::Message, Tp::MessageSendingFlags, QString) |
676 | |
677 | === modified file 'indicator/textchannelobserver.h' |
678 | --- indicator/textchannelobserver.h 2014-11-04 13:23:09 +0000 |
679 | +++ indicator/textchannelobserver.h 2015-02-05 12:16:44 +0000 |
680 | @@ -44,20 +44,21 @@ |
681 | void sendMessage(const QStringList &phoneNumbers, const QString &text, const QString &accountId); |
682 | |
683 | protected: |
684 | - void triggerNotificationForMessage(const Tp::ReceivedMessage &message); |
685 | - void showNotificationForMessage(const Tp::ReceivedMessage &message, const QContact &contact = QContact()); |
686 | - void showNotificationForFlashMessage(const Tp::ReceivedMessage &message); |
687 | + void showNotificationForFlashMessage(const Tp::ReceivedMessage &message, const QString &accountId); |
688 | + void triggerNotificationForMessage(const Tp::ReceivedMessage &message, const QString &accountId, const QStringList &participantIds = QStringList()); |
689 | + void showNotificationForMessage(const Tp::ReceivedMessage &message, const QString &accountId, const QStringList &participantIds = QStringList(), const QContact &contact = QContact()); |
690 | |
691 | protected Q_SLOTS: |
692 | void onTextChannelInvalidated(); |
693 | void onMessageReceived(const Tp::ReceivedMessage &message); |
694 | void onPendingMessageRemoved(const Tp::ReceivedMessage &message); |
695 | - void onReplyReceived(const QString &phoneNumber, const QString &reply); |
696 | - void onMessageRead(const QString &phoneNumber, const QString &encodedMessageId); |
697 | + void onReplyReceived(const QStringList &recipients, const QString &accountId, const QString &reply); |
698 | + void onMessageRead(const QStringList &recipients, const QString &accountId, const QString &encodedMessageId); |
699 | void onMessageSent(Tp::Message, Tp::MessageSendingFlags, QString); |
700 | void updateNotifications(const QtContacts::QContact &contact); |
701 | |
702 | private: |
703 | + void processMessageReceived(const Tp::ReceivedMessage &message, const Tp::TextChannelPtr &textChannel); |
704 | QList<Tp::TextChannelPtr> mChannels; |
705 | QList<Tp::TextChannelPtr> mFlashChannels; |
706 | QMap<NotifyNotification*, NotificationData*> mNotifications; |
707 | |
708 | === modified file 'libtelephonyservice/accountentry.cpp' |
709 | --- libtelephonyservice/accountentry.cpp 2015-02-03 17:30:41 +0000 |
710 | +++ libtelephonyservice/accountentry.cpp 2015-02-05 12:16:44 +0000 |
711 | @@ -48,6 +48,15 @@ |
712 | return mAccount->displayName(); |
713 | } |
714 | |
715 | +QString AccountEntry::selfContactId() const |
716 | +{ |
717 | + if (!mAccount.isNull() && !mAccount->connection().isNull() && |
718 | + !mAccount->connection()->selfContact().isNull()) { |
719 | + return mAccount->connection()->selfContact()->id(); |
720 | + } |
721 | + return QString(); |
722 | +} |
723 | + |
724 | QString AccountEntry::networkName() const |
725 | { |
726 | if (mAccount.isNull() || mAccount->connection().isNull() || mAccount->connection()->selfContact().isNull()) { |
727 | @@ -201,6 +210,16 @@ |
728 | SIGNAL(simLockedChanged())); |
729 | } |
730 | |
731 | +void AccountEntry::onSelfHandleChanged(uint handle) |
732 | +{ |
733 | + watchSelfContactPresence(); |
734 | + |
735 | + Q_EMIT networkNameChanged(); |
736 | + Q_EMIT connectedChanged(); |
737 | + Q_EMIT simLockedChanged(); |
738 | + Q_EMIT selfContactIdChanged(); |
739 | +} |
740 | + |
741 | void AccountEntry::onConnectionChanged() |
742 | { |
743 | QDBusConnection dbusConnection = QDBusConnection::sessionBus(); |
744 | @@ -265,6 +284,9 @@ |
745 | Q_EMIT voicemailIndicatorChanged(); |
746 | } |
747 | |
748 | + connect(mAccount->connection().data(), |
749 | + SIGNAL(selfHandleChanged(uint)), |
750 | + SLOT(onSelfHandleChanged(uint))); |
751 | // and get the serial |
752 | QDBusInterface ussdIface(mConnectionInfo.busName, mConnectionInfo.objectPath, CANONICAL_TELEPHONY_USSD_IFACE); |
753 | mSerial = ussdIface.property("Serial").toString(); |
754 | @@ -275,6 +297,7 @@ |
755 | Q_EMIT networkNameChanged(); |
756 | Q_EMIT connectedChanged(); |
757 | Q_EMIT simLockedChanged(); |
758 | + Q_EMIT selfContactIdChanged(); |
759 | Q_EMIT serialChanged(); |
760 | } |
761 | |
762 | |
763 | === modified file 'libtelephonyservice/accountentry.h' |
764 | --- libtelephonyservice/accountentry.h 2015-02-03 17:30:41 +0000 |
765 | +++ libtelephonyservice/accountentry.h 2015-02-05 12:16:44 +0000 |
766 | @@ -36,6 +36,7 @@ |
767 | Q_OBJECT |
768 | Q_PROPERTY(QString accountId READ accountId NOTIFY accountIdChanged) |
769 | Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName NOTIFY displayNameChanged) |
770 | + Q_PROPERTY(QString selfContactId READ selfContactId NOTIFY selfContactIdChanged) |
771 | Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged) |
772 | Q_PROPERTY(QStringList emergencyNumbers READ emergencyNumbers NOTIFY emergencyNumbersChanged) |
773 | Q_PROPERTY(QString voicemailNumber READ voicemailNumber NOTIFY voicemailNumberChanged) |
774 | @@ -50,6 +51,7 @@ |
775 | explicit AccountEntry(const Tp::AccountPtr &account, QObject *parent = 0); |
776 | QString accountId() const; |
777 | QString displayName() const; |
778 | + QString selfContactId() const; |
779 | QString networkName() const; |
780 | bool simLocked() const; |
781 | void setDisplayName(const QString &name); |
782 | @@ -66,6 +68,7 @@ |
783 | void accountReady(); |
784 | void accountIdChanged(); |
785 | void displayNameChanged(); |
786 | + void selfContactIdChanged(); |
787 | void networkNameChanged(); |
788 | void simLockedChanged(); |
789 | void connectedChanged(); |
790 | @@ -89,6 +92,7 @@ |
791 | void onVoicemailNumberChanged(const QString &number); |
792 | void onVoicemailCountChanged(uint count); |
793 | void onVoicemailIndicatorChanged(bool visible); |
794 | + void onSelfHandleChanged(uint handle); |
795 | |
796 | private: |
797 | Tp::AccountPtr mAccount; |
798 | |
799 | === modified file 'libtelephonyservice/chatmanager.cpp' |
800 | --- libtelephonyservice/chatmanager.cpp 2014-10-07 16:28:50 +0000 |
801 | +++ libtelephonyservice/chatmanager.cpp 2015-02-05 12:16:44 +0000 |
802 | @@ -70,14 +70,14 @@ |
803 | return manager; |
804 | } |
805 | |
806 | -void ChatManager::sendMMS(const QStringList &phoneNumbers, const QString &message, const QVariant &attachments, const QString &accountId) |
807 | +void ChatManager::sendMMS(const QStringList &recipients, const QString &message, const QVariant &attachments, const QString &accountId) |
808 | { |
809 | AttachmentList newAttachments; |
810 | - AccountEntry *account; |
811 | - if (accountId.isNull()) { |
812 | + AccountEntry *account = NULL; |
813 | + if (accountId.isNull() || accountId.isEmpty()) { |
814 | account = TelepathyHelper::instance()->defaultMessagingAccount(); |
815 | - if (!account) { |
816 | - account = TelepathyHelper::instance()->accounts()[0]; |
817 | + if (!account && !TelepathyHelper::instance()->activeAccounts().isEmpty()) { |
818 | + account = TelepathyHelper::instance()->activeAccounts()[0]; |
819 | } |
820 | } else { |
821 | account = TelepathyHelper::instance()->accountForId(accountId); |
822 | @@ -109,16 +109,20 @@ |
823 | } |
824 | |
825 | QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); |
826 | - phoneAppHandler->call("SendMMS", phoneNumbers, QVariant::fromValue(newAttachments), account->accountId()); |
827 | + phoneAppHandler->call("SendMMS", recipients, QVariant::fromValue(newAttachments), account->accountId()); |
828 | } |
829 | |
830 | -void ChatManager::sendMessage(const QStringList &phoneNumbers, const QString &message, const QString &accountId) |
831 | +void ChatManager::sendMessage(const QStringList &recipients, const QString &message, const QString &accountId) |
832 | { |
833 | - AccountEntry *account; |
834 | + if (recipients.size() > 1 && TelepathyHelper::instance()->mmsGroupChat()) { |
835 | + sendMMS(recipients, message, QVariant(), accountId); |
836 | + return; |
837 | + } |
838 | + AccountEntry *account = NULL; |
839 | if (accountId.isNull() || accountId.isEmpty()) { |
840 | account = TelepathyHelper::instance()->defaultMessagingAccount(); |
841 | - if (!account) { |
842 | - account = TelepathyHelper::instance()->accounts()[0]; |
843 | + if (!account && !TelepathyHelper::instance()->activeAccounts().isEmpty()) { |
844 | + account = TelepathyHelper::instance()->activeAccounts()[0]; |
845 | } |
846 | } else { |
847 | account = TelepathyHelper::instance()->accountForId(accountId); |
848 | @@ -129,12 +133,11 @@ |
849 | } |
850 | |
851 | QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); |
852 | - phoneAppHandler->call("SendMessage", phoneNumbers, message, account->accountId()); |
853 | + phoneAppHandler->call("SendMessage", recipients, message, account->accountId()); |
854 | } |
855 | |
856 | void ChatManager::onTextChannelAvailable(Tp::TextChannelPtr channel) |
857 | { |
858 | - QString id = channel->targetContact()->id(); |
859 | mChannels.append(channel); |
860 | |
861 | connect(channel.data(), |
862 | @@ -147,8 +150,9 @@ |
863 | SIGNAL(pendingMessageRemoved(const Tp::ReceivedMessage&)), |
864 | SLOT(onPendingMessageRemoved(const Tp::ReceivedMessage&))); |
865 | |
866 | - Q_EMIT unreadMessagesChanged(id); |
867 | - |
868 | + if (!channel->targetContact().isNull()){ |
869 | + Q_EMIT unreadMessagesChanged(channel->targetContact()->id()); |
870 | + } |
871 | Q_FOREACH(const Tp::ReceivedMessage &message, channel->messageQueue()) { |
872 | onMessageReceived(message); |
873 | } |
874 | @@ -182,10 +186,12 @@ |
875 | return; |
876 | } |
877 | |
878 | - Q_EMIT messageSent(channel->targetContact()->id(), sentMessage.text()); |
879 | + if (!channel->targetContact().isNull()) { |
880 | + Q_EMIT messageSent(channel->targetContact()->id(), sentMessage.text()); |
881 | + } |
882 | } |
883 | |
884 | -Tp::TextChannelPtr ChatManager::existingChat(const QStringList &phoneNumbers, const QString &accountId) |
885 | +Tp::TextChannelPtr ChatManager::existingChat(const QStringList &recipients, const QString &accountId) |
886 | { |
887 | Tp::TextChannelPtr channel; |
888 | |
889 | @@ -193,17 +199,17 @@ |
890 | AccountEntry *channelAccount = TelepathyHelper::instance()->accountForConnection(channel->connection()); |
891 | int count = 0; |
892 | if (!channelAccount || channelAccount->accountId() != accountId |
893 | - || channel->groupContacts(false).size() != phoneNumbers.size()) { |
894 | + || channel->groupContacts(false).size() != recipients.size()) { |
895 | continue; |
896 | } |
897 | - Q_FOREACH(const QString &phoneNumberNew, phoneNumbers) { |
898 | - Q_FOREACH(const Tp::ContactPtr &phoneNumberOld, channel->groupContacts(false)) { |
899 | - if (PhoneUtils::comparePhoneNumbers(phoneNumberOld->id(), phoneNumberNew)) { |
900 | + Q_FOREACH(const QString &recipientNew, recipients) { |
901 | + Q_FOREACH(const Tp::ContactPtr &recipientOld, channel->groupContacts(false)) { |
902 | + if (PhoneUtils::comparePhoneNumbers(recipientOld->id(), recipientNew)) { |
903 | count++; |
904 | } |
905 | } |
906 | } |
907 | - if (count == phoneNumbers.size()) { |
908 | + if (count == recipients.size()) { |
909 | return channel; |
910 | } |
911 | |
912 | @@ -212,22 +218,25 @@ |
913 | return channel; |
914 | } |
915 | |
916 | -void ChatManager::acknowledgeMessage(const QString &phoneNumber, const QString &messageId, const QString &accountId) |
917 | +void ChatManager::acknowledgeMessage(const QStringList &recipients, const QString &messageId, const QString &accountId) |
918 | { |
919 | - AccountEntry *account; |
920 | - if (accountId.isNull()) { |
921 | - account = TelepathyHelper::instance()->accounts()[0]; |
922 | + AccountEntry *account = NULL; |
923 | + if (accountId.isNull() || accountId.isEmpty()) { |
924 | + account = TelepathyHelper::instance()->defaultMessagingAccount(); |
925 | + if (!account && !TelepathyHelper::instance()->activeAccounts().isEmpty()) { |
926 | + account = TelepathyHelper::instance()->activeAccounts()[0]; |
927 | + } |
928 | } else { |
929 | account = TelepathyHelper::instance()->accountForId(accountId); |
930 | } |
931 | |
932 | if (!account) { |
933 | - mMessagesToAck[accountId][phoneNumber].append(messageId); |
934 | + mMessagesToAck[accountId][recipients].append(messageId); |
935 | return; |
936 | } |
937 | |
938 | mMessagesAckTimer.start(); |
939 | - mMessagesToAck[account->accountId()][phoneNumber].append(messageId); |
940 | + mMessagesToAck[account->accountId()][recipients].append(messageId); |
941 | } |
942 | |
943 | void ChatManager::onAckTimerTriggered() |
944 | @@ -235,12 +244,12 @@ |
945 | // ack all pending messages |
946 | QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface(); |
947 | |
948 | - QMap<QString, QMap<QString,QStringList> >::const_iterator it = mMessagesToAck.constBegin(); |
949 | + QMap<QString, QMap<QStringList,QStringList> >::const_iterator it = mMessagesToAck.constBegin(); |
950 | while (it != mMessagesToAck.constEnd()) { |
951 | QString accountId = it.key(); |
952 | - QMap<QString, QStringList>::const_iterator it2 = it.value().constBegin(); |
953 | + QMap<QStringList, QStringList>::const_iterator it2 = it.value().constBegin(); |
954 | while (it2 != it.value().constEnd()) { |
955 | - phoneAppHandler->call("AcknowledgeMessages", QStringList() << it2.key(), it2.value(), accountId); |
956 | + phoneAppHandler->call("AcknowledgeMessages", it2.key(), it2.value(), accountId); |
957 | ++it2; |
958 | } |
959 | ++it; |
960 | |
961 | === modified file 'libtelephonyservice/chatmanager.h' |
962 | --- libtelephonyservice/chatmanager.h 2014-07-14 20:34:48 +0000 |
963 | +++ libtelephonyservice/chatmanager.h 2015-02-05 12:16:44 +0000 |
964 | @@ -34,13 +34,13 @@ |
965 | public: |
966 | static ChatManager *instance(); |
967 | |
968 | - Q_INVOKABLE void sendMessage(const QStringList &phoneNumbers, const QString &message, const QString &accountId = QString::null); |
969 | - Q_INVOKABLE void sendMMS(const QStringList &phoneNumbers, const QString &message, const QVariant &attachments, const QString &accountId = QString:: null); |
970 | + Q_INVOKABLE void sendMessage(const QStringList &recipients, const QString &message, const QString &accountId = QString::null); |
971 | + Q_INVOKABLE void sendMMS(const QStringList &recipients, const QString &message, const QVariant &attachments, const QString &accountId = QString:: null); |
972 | |
973 | Q_SIGNALS: |
974 | - void messageReceived(const QString &phoneNumber, const QString &message, const QDateTime ×tamp, const QString &messageId, bool unread); |
975 | - void messageSent(const QString &phoneNumber, const QString &message); |
976 | - void unreadMessagesChanged(const QString &phoneNumber); |
977 | + void messageReceived(const QString &recipient, const QString &message, const QDateTime ×tamp, const QString &messageId, bool unread); |
978 | + void messageSent(const QString &recipient, const QString &message); |
979 | + void unreadMessagesChanged(const QString &recipient); |
980 | |
981 | public Q_SLOTS: |
982 | void onTextChannelAvailable(Tp::TextChannelPtr channel); |
983 | @@ -49,10 +49,10 @@ |
984 | void onPendingMessageRemoved(const Tp::ReceivedMessage &message); |
985 | void onMessageSent(const Tp::Message &sentMessage, const Tp::MessageSendingFlags flags, const QString &message); |
986 | |
987 | - void acknowledgeMessage(const QString &phoneNumber, const QString &messageId, const QString &accountId = QString::null); |
988 | + void acknowledgeMessage(const QStringList &recipients, const QString &messageId, const QString &accountId = QString::null); |
989 | |
990 | protected: |
991 | - Tp::TextChannelPtr existingChat(const QStringList &phoneNumbers, const QString &accountId); |
992 | + Tp::TextChannelPtr existingChat(const QStringList &recipients, const QString &accountId); |
993 | |
994 | protected Q_SLOTS: |
995 | void onAckTimerTriggered(); |
996 | @@ -61,7 +61,7 @@ |
997 | explicit ChatManager(QObject *parent = 0); |
998 | |
999 | QList<Tp::TextChannelPtr> mChannels; |
1000 | - QMap<QString, QMap<QString,QStringList> > mMessagesToAck; |
1001 | + QMap<QString, QMap<QStringList,QStringList> > mMessagesToAck; |
1002 | QTimer mMessagesAckTimer; |
1003 | }; |
1004 | |
1005 | |
1006 | === modified file 'libtelephonyservice/telepathyhelper.cpp' |
1007 | --- libtelephonyservice/telepathyhelper.cpp 2015-01-15 14:17:06 +0000 |
1008 | +++ libtelephonyservice/telepathyhelper.cpp 2015-02-05 12:16:44 +0000 |
1009 | @@ -35,6 +35,11 @@ |
1010 | #include <TelepathyQt/PendingReady> |
1011 | #include <TelepathyQt/PendingAccount> |
1012 | |
1013 | +template<> bool qMapLessThanKey<QStringList>(const QStringList &key1, const QStringList &key2) |
1014 | +{ |
1015 | + return key1.size() > key2.size(); // sort by operator> ! |
1016 | +} |
1017 | + |
1018 | TelepathyHelper::TelepathyHelper(QObject *parent) |
1019 | : QObject(parent), |
1020 | mDefaultCallAccount(NULL), |
1021 | @@ -43,8 +48,8 @@ |
1022 | mFirstTime(true), |
1023 | mConnected(false), |
1024 | mHandlerInterface(0), |
1025 | + mPhoneSettings(new QGSettings("com.ubuntu.phone")), |
1026 | mApproverInterface(0), |
1027 | - mDefaultSimSettings(new QGSettings("com.ubuntu.phone")), |
1028 | mFlightModeInterface("org.freedesktop.URfkill", |
1029 | "/org/freedesktop/URfkill", |
1030 | "org.freedesktop.URfkill", |
1031 | @@ -78,13 +83,15 @@ |
1032 | |
1033 | mClientRegistrar = Tp::ClientRegistrar::create(mAccountManager); |
1034 | connect(this, SIGNAL(accountReady()), SIGNAL(setupReady())); |
1035 | - connect(mDefaultSimSettings, SIGNAL(changed(QString)), this, SLOT(onSettingsChanged(QString))); |
1036 | + connect(mPhoneSettings, SIGNAL(changed(QString)), this, SLOT(onSettingsChanged(QString))); |
1037 | connect(&mFlightModeInterface, SIGNAL(FlightModeChanged(bool)), this, SIGNAL(flightModeChanged())); |
1038 | + |
1039 | + mMmsGroupChat = mPhoneSettings->get("mmsGroupChatEnabled").value<bool>(); |
1040 | } |
1041 | |
1042 | TelepathyHelper::~TelepathyHelper() |
1043 | { |
1044 | - mDefaultSimSettings->deleteLater(); |
1045 | + mPhoneSettings->deleteLater(); |
1046 | } |
1047 | |
1048 | TelepathyHelper *TelepathyHelper::instance() |
1049 | @@ -112,6 +119,16 @@ |
1050 | return ids; |
1051 | } |
1052 | |
1053 | +void TelepathyHelper::setMmsGroupChat(bool enable) |
1054 | +{ |
1055 | + mPhoneSettings->set("mmsGroupChatEnabled", enable); |
1056 | +} |
1057 | + |
1058 | +bool TelepathyHelper::mmsGroupChat() |
1059 | +{ |
1060 | + return mMmsGroupChat; |
1061 | +} |
1062 | + |
1063 | bool TelepathyHelper::flightMode() |
1064 | { |
1065 | QDBusReply<bool> reply = mFlightModeInterface.call("IsFlightMode"); |
1066 | @@ -477,9 +494,9 @@ |
1067 | QString modemObjName = account->account()->parameters().value("modem-objpath").toString(); |
1068 | if (!modemObjName.isEmpty()) { |
1069 | if (type == Call) { |
1070 | - mDefaultSimSettings->set("defaultSimForCalls", modemObjName); |
1071 | + mPhoneSettings->set("defaultSimForCalls", modemObjName); |
1072 | } else if (type == Messaging) { |
1073 | - mDefaultSimSettings->set("defaultSimForMessages", modemObjName); |
1074 | + mPhoneSettings->set("defaultSimForMessages", modemObjName); |
1075 | } |
1076 | } |
1077 | } |
1078 | @@ -497,7 +514,7 @@ |
1079 | void TelepathyHelper::onSettingsChanged(const QString &key) |
1080 | { |
1081 | if (key == "defaultSimForMessages") { |
1082 | - QString defaultSim = mDefaultSimSettings->get("defaultSimForMessages").value<QString>(); |
1083 | + QString defaultSim = mPhoneSettings->get("defaultSimForMessages").value<QString>(); |
1084 | if (defaultSim == "ask") { |
1085 | mDefaultMessagingAccount = NULL; |
1086 | Q_EMIT defaultMessagingAccountChanged(); |
1087 | @@ -515,7 +532,7 @@ |
1088 | mDefaultMessagingAccount = NULL; |
1089 | Q_EMIT defaultMessagingAccountChanged(); |
1090 | } else if (key == "defaultSimForCalls") { |
1091 | - QString defaultSim = mDefaultSimSettings->get("defaultSimForCalls").value<QString>(); |
1092 | + QString defaultSim = mPhoneSettings->get("defaultSimForCalls").value<QString>(); |
1093 | if (defaultSim == "ask") { |
1094 | mDefaultCallAccount = NULL; |
1095 | Q_EMIT defaultCallAccountChanged(); |
1096 | @@ -532,6 +549,9 @@ |
1097 | } |
1098 | mDefaultCallAccount = NULL; |
1099 | Q_EMIT defaultCallAccountChanged(); |
1100 | + } else if (key == "mmsGroupChatEnabled") { |
1101 | + mMmsGroupChat = mPhoneSettings->get("mmsGroupChatEnabled").value<bool>(); |
1102 | + Q_EMIT mmsGroupChatChanged(); |
1103 | } |
1104 | } |
1105 | |
1106 | |
1107 | === modified file 'libtelephonyservice/telepathyhelper.h' |
1108 | --- libtelephonyservice/telepathyhelper.h 2015-01-13 14:57:52 +0000 |
1109 | +++ libtelephonyservice/telepathyhelper.h 2015-02-05 12:16:44 +0000 |
1110 | @@ -37,6 +37,8 @@ |
1111 | #define CANONICAL_TELEPHONY_USSD_IFACE "com.canonical.Telephony.USSD" |
1112 | #define CANONICAL_TELEPHONY_EMERGENCYMODE_IFACE "com.canonical.Telephony.EmergencyMode" |
1113 | |
1114 | +template<> bool qMapLessThanKey<QStringList>(const QStringList &key1, const QStringList &key2); |
1115 | + |
1116 | class AccountEntry; |
1117 | class QGSettings; |
1118 | |
1119 | @@ -50,6 +52,7 @@ |
1120 | Q_PROPERTY(AccountEntry *defaultMessagingAccount READ defaultMessagingAccount NOTIFY defaultMessagingAccountChanged) |
1121 | Q_PROPERTY(AccountEntry *defaultCallAccount READ defaultCallAccount NOTIFY defaultCallAccountChanged) |
1122 | Q_PROPERTY(bool flightMode READ flightMode WRITE setFlightMode NOTIFY flightModeChanged) |
1123 | + Q_PROPERTY(bool mmsGroupChat READ mmsGroupChat WRITE setMmsGroupChat NOTIFY mmsGroupChatChanged) |
1124 | Q_PROPERTY(bool emergencyCallsAvailable READ emergencyCallsAvailable NOTIFY emergencyCallsAvailableChanged) |
1125 | Q_ENUMS(AccountType) |
1126 | public: |
1127 | @@ -71,6 +74,8 @@ |
1128 | AccountEntry *defaultMessagingAccount() const; |
1129 | AccountEntry *defaultCallAccount() const; |
1130 | |
1131 | + bool mmsGroupChat(); |
1132 | + void setMmsGroupChat(bool value); |
1133 | bool flightMode(); |
1134 | void setFlightMode(bool value); |
1135 | bool connected() const; |
1136 | @@ -105,6 +110,7 @@ |
1137 | void defaultCallAccountChanged(); |
1138 | void flightModeChanged(); |
1139 | void emergencyCallsAvailableChanged(); |
1140 | + void mmsGroupChatChanged(); |
1141 | |
1142 | public Q_SLOTS: |
1143 | Q_INVOKABLE void registerChannelObserver(const QString &observerName = QString::null); |
1144 | @@ -136,9 +142,10 @@ |
1145 | ChannelObserver *mChannelObserver; |
1146 | bool mFirstTime; |
1147 | bool mConnected; |
1148 | + bool mMmsGroupChat; |
1149 | mutable QDBusInterface *mHandlerInterface; |
1150 | + QGSettings *mPhoneSettings; |
1151 | mutable QDBusInterface *mApproverInterface; |
1152 | - QGSettings *mDefaultSimSettings; |
1153 | QDBusInterface mFlightModeInterface; |
1154 | }; |
1155 |
FAILED: Continuous integration, rev:978 jenkins. qa.ubuntu. com/job/ telephony- service- ci/342/ jenkins. qa.ubuntu. com/job/ telephony- service- vivid-amd64- ci/10/console jenkins. qa.ubuntu. com/job/ telephony- service- vivid-armhf- ci/10/console jenkins. qa.ubuntu. com/job/ telephony- service- vivid-i386- ci/10/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/telephony- service- ci/342/ rebuild
http://