Merge lp:~boiko/telephony-service/preserve_call_status into lp:telephony-service

Proposed by Gustavo Pichorim Boiko
Status: Merged
Approved by: Tiago Salem Herrmann
Approved revision: 777
Merged at revision: 776
Proposed branch: lp:~boiko/telephony-service/preserve_call_status
Merge into: lp:telephony-service
Diff against target: 164 lines (+60/-7)
7 files modified
handler/Handler.xml (+6/-0)
handler/callhandler.cpp (+18/-0)
handler/callhandler.h (+1/-0)
handler/handlerdbus.cpp (+5/-0)
handler/handlerdbus.h (+1/-0)
libtelephonyservice/callmanager.cpp (+28/-7)
libtelephonyservice/callmanager.h (+1/-0)
To merge this branch: bzr merge lp:~boiko/telephony-service/preserve_call_status
Reviewer Review Type Date Requested Status
Tiago Salem Herrmann (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+207554@code.launchpad.net

Commit message

Avoid flickering the UI on client apps by addressing the following points:
- Get the "hasCalls" property value from the handler even before the telepathy observer is properly registered
- Delay the cleaning up of manager data when unregistering the observer

Description of the change

Avoid flickering the UI on client apps by addressing the following points:
- Get the "hasCalls" property value from the handler even before the telepathy observer is properly registered
- Delay the cleaning up of manager data when unregistering the observer

To post a comment you must log in.
Revision history for this message
Tiago Salem Herrmann (tiagosh) wrote :

I think there might be a case where this logic fails.
Correct me if I am wrong, but consider the case where we are on a call and switch to another app, then while dialer-app is in background the remote party hangs up. When you bring the dialer-app to foreground again and register the observer, onCallChannelAvailable() wont be called as there are no active calls at the moment, so we will end up in an inconsistent state.

139 void CallManager::onCallChannelAvailable(Tp::CallChannelPtr channel)
140 {
141 + // if this is the first call after re-registering the observer, clear the data

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote :

> I think there might be a case where this logic fails.
> Correct me if I am wrong, but consider the case where we are on a call and
> switch to another app, then while dialer-app is in background the remote party
> hangs up. When you bring the dialer-app to foreground again and register the
> observer, onCallChannelAvailable() wont be called as there are no active calls
> at the moment, so we will end up in an inconsistent state.
>
>
> 139 void CallManager::onCallChannelAvailable(Tp::CallChannelPtr channel)
> 140 {
> 141 + // if this is the first call after re-registering the observer,
> clear the data

At first I also thought this case was not covered, but it is: the Tp::CallChannel has already introspected the DBus object for the call, so even after the observer is unregistered, the correct signals from the channel are still emitted.
So even if dialer-app is in background (sigstopped), when it comes back to life it is going to receive the notifications for the existing calls even before registering the observer again.

Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote :

Are there any related MPs required for this MP to build/function as expected? Please list.
No

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://wiki.ubuntu.com/Process/Merges/TestPlan/telephony-service) on device or emulator?
Yes

If you changed the UI, was the change specified/approved by design?
No UI changes

If you changed the packaging (debian), did you subscribe a core-dev to this MP?
No packaging changes

Revision history for this message
Tiago Salem Herrmann (tiagosh) wrote :

Did you perform an exploratory manual test run of the 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://wiki.ubuntu.com/Process/Merges/TestPlan/telephony-service) on device or emulator?
Yes

Did CI run pass? If not, please explain why.
Yes

Have you checked that submitter has accurately filled out the submitter checklist and has taken no shortcut?
Yes

The code looks good and it works as expected.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'handler/Handler.xml'
2--- handler/Handler.xml 2014-02-17 12:43:27 +0000
3+++ handler/Handler.xml 2014-02-20 21:36:37 +0000
4@@ -67,6 +67,12 @@
5 <arg name="objectPath" type="s" direction="in"/>
6 <arg name="key" type="s" direction="in"/>
7 </method>
8+ <method name="HasCalls">
9+ <dox:d><![CDATA[
10+ Returns whether the handler is managing any call
11+ ]]></dox:d>
12+ <arg name="result" type="b" direction="out"/>
13+ </method>
14 <method name="GetCallProperties">
15 <dox:d><![CDATA[
16 Get the properties of a given call channel
17
18=== modified file 'handler/callhandler.cpp'
19--- handler/callhandler.cpp 2014-01-29 16:22:30 +0000
20+++ handler/callhandler.cpp 2014-02-20 21:36:37 +0000
21@@ -64,6 +64,24 @@
22 return properties;
23 }
24
25+bool CallHandler::hasCalls() const
26+{
27+ bool hasActiveCalls = false;
28+
29+ Q_FOREACH(const Tp::CallChannelPtr channel, mCallChannels) {
30+ bool incoming = channel->initiatorContact() != TelepathyHelper::instance()->account()->connection()->selfContact();
31+ bool dialing = !incoming && (channel->callState() == Tp::CallStateInitialised);
32+ bool active = channel->callState() == Tp::CallStateActive;
33+
34+ if (dialing || active) {
35+ hasActiveCalls = true;
36+ break;
37+ }
38+ }
39+
40+ return hasActiveCalls;
41+}
42+
43 CallHandler::CallHandler(QObject *parent)
44 : QObject(parent)
45 {
46
47=== modified file 'handler/callhandler.h'
48--- handler/callhandler.h 2014-01-29 16:22:30 +0000
49+++ handler/callhandler.h 2014-02-20 21:36:37 +0000
50@@ -36,6 +36,7 @@
51 public:
52 static CallHandler *instance();
53 QVariantMap getCallProperties(const QString &objectPath);
54+ bool hasCalls() const;
55
56 public Q_SLOTS:
57 void onCallChannelAvailable(Tp::CallChannelPtr channel);
58
59=== modified file 'handler/handlerdbus.cpp'
60--- handler/handlerdbus.cpp 2014-02-17 12:43:27 +0000
61+++ handler/handlerdbus.cpp 2014-02-20 21:36:37 +0000
62@@ -48,6 +48,11 @@
63 return CallHandler::instance()->getCallProperties(objectPath);
64 }
65
66+bool HandlerDBus::HasCalls()
67+{
68+ return CallHandler::instance()->hasCalls();
69+}
70+
71 bool HandlerDBus::connectToBus()
72 {
73 bool ok = QDBusConnection::sessionBus().registerService(DBUS_SERVICE);
74
75=== modified file 'handler/handlerdbus.h'
76--- handler/handlerdbus.h 2014-02-17 12:43:27 +0000
77+++ handler/handlerdbus.h 2014-02-20 21:36:37 +0000
78@@ -40,6 +40,7 @@
79 ~HandlerDBus();
80
81 QVariantMap GetCallProperties(const QString &objectPath);
82+ bool HasCalls();
83
84 public Q_SLOTS:
85 bool connectToBus();
86
87=== modified file 'libtelephonyservice/callmanager.cpp'
88--- libtelephonyservice/callmanager.cpp 2014-01-28 13:16:58 +0000
89+++ libtelephonyservice/callmanager.cpp 2014-02-20 21:36:37 +0000
90@@ -38,7 +38,7 @@
91 }
92
93 CallManager::CallManager(QObject *parent)
94-: QObject(parent)
95+: QObject(parent), mNeedsUpdate(false)
96 {
97 connect(TelepathyHelper::instance(), SIGNAL(connectedChanged()), SLOT(onConnectedChanged()));
98 connect(TelepathyHelper::instance(), SIGNAL(channelObserverUnregistered()), SLOT(onChannelObserverUnregistered()));
99@@ -46,11 +46,9 @@
100
101 void CallManager::onChannelObserverUnregistered()
102 {
103- mCallEntries.clear();
104- Q_EMIT hasCallsChanged();
105- Q_EMIT hasBackgroundCallChanged();
106- Q_EMIT foregroundCallChanged();
107- Q_EMIT backgroundCallChanged();
108+ // do not clear the manager right now, wait until the observer is re-registered
109+ // to avoid flickering in the UI
110+ mNeedsUpdate = true;
111 }
112
113 void CallManager::startCall(const QString &phoneNumber)
114@@ -126,7 +124,21 @@
115
116 bool CallManager::hasCalls() const
117 {
118- return activeCallsCount() > 0;
119+ // check if the callmanager already has active calls
120+ if (activeCallsCount() > 0) {
121+ return true;
122+ }
123+
124+ // if that's not the case, query the teleophony-service-handler for the availability of calls
125+ // this is done only to get the live call view on clients as soon as possible, even before the
126+ // telepathy observer is configured
127+ QDBusInterface *phoneAppHandler = TelepathyHelper::instance()->handlerInterface();
128+ QDBusReply<bool> reply = phoneAppHandler->call("HasCalls");
129+ if (reply.isValid()) {
130+ return reply.value();
131+ }
132+
133+ return false;
134 }
135
136 bool CallManager::hasBackgroundCall() const
137@@ -136,6 +148,15 @@
138
139 void CallManager::onCallChannelAvailable(Tp::CallChannelPtr channel)
140 {
141+ // if this is the first call after re-registering the observer, clear the data
142+ if (mNeedsUpdate) {
143+ Q_FOREACH(CallEntry *entry, mCallEntries) {
144+ entry->deleteLater();
145+ }
146+ mCallEntries.clear();
147+ mNeedsUpdate = false;
148+ }
149+
150 CallEntry *entry = new CallEntry(channel, this);
151 if (entry->phoneNumber() == getVoicemailNumber()) {
152 entry->setVoicemail(true);
153
154=== modified file 'libtelephonyservice/callmanager.h'
155--- libtelephonyservice/callmanager.h 2014-01-20 12:57:43 +0000
156+++ libtelephonyservice/callmanager.h 2014-02-20 21:36:37 +0000
157@@ -84,6 +84,7 @@
158
159 QList<CallEntry*> mCallEntries;
160 QString mVoicemailNumber;
161+ bool mNeedsUpdate;
162 };
163
164 #endif // CALLMANAGER_H

Subscribers

People subscribed via source and target branches