Merge lp:~dandrader/unity-mir/improve_osk_ipc into lp:unity-mir

Proposed by Daniel d'Andrada
Status: Merged
Approved by: Michał Sawicz
Approved revision: 115
Merged at revision: 117
Proposed branch: lp:~dandrader/unity-mir/improve_osk_ipc
Merge into: lp:unity-mir
Diff against target: 177 lines (+71/-25)
2 files modified
src/modules/Unity/Application/ubuntukeyboardinfo.cpp (+61/-22)
src/modules/Unity/Application/ubuntukeyboardinfo.h (+10/-3)
To merge this branch: bzr merge lp:~dandrader/unity-mir/improve_osk_ipc
Reviewer Review Type Date Requested Status
Michał Sawicz Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+190417@code.launchpad.net

Commit message

Make UbuntuKeyboardInfo more robust

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

Can we please use $XDG_RUNTIME_DIR and mode 600 for this? Or Jamie will eat us alive ;)

IIUC, this will still bail if the connection isn't available within 50s. It might be good enough, but if there's an easy way to get notified on changes to the socket, maybe we should add it? So that if it shows up after the 50s, we will try again?

review: Needs Fixing
Revision history for this message
Michał Sawicz (saviq) wrote :

I stopped maliit-server, but the keyboard dimensions were not reset - can't use the bottom part of the shell...

review: Needs Fixing
Revision history for this message
Michał Sawicz (saviq) wrote :

Stopped when it was on screen, btw.

Revision history for this message
Michał Sawicz (saviq) wrote :

It also seems much more difficult to dismiss the keyboard - the 2GU or something, at the top of the keyboard, that caused the original bug, were probably meant for this?

review: Needs Information
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> I stopped maliit-server, but the keyboard dimensions were not reset - can't
> use the bottom part of the shell... Stopped when it was on screen, btw.

That's an unrelated bug.

There are two different kinds of OSK information handled by unity8:

1 - the OSK geometry, which is what being dealt with here
2 - whether the OSK is visible or not

They are orthogonal to each other. So the problem when you kill maliit-server while the OSK is being displayed is that unity8-mir somehow doesn't notice or gets notified of its disappearance and hence doesn't disable OSK's InputFilterArea. Let's not mix bugs!

Revision history for this message
Michał Sawicz (saviq) wrote :

On 11.10.2013 15:54, Daniel d'Andrada wrote:
> They are orthogonal to each other. So the problem when you kill maliit-server while the OSK is being displayed is that unity8-mir somehow doesn't notice or gets notified of its disappearance and hence doesn't disable OSK's InputFilterArea. Let's not mix bugs!

Of course, sorry - that's Qt.inputMethod then.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> IIUC, this will still bail if the connection isn't available within 50s.

Right.

> It might be good enough, but if there's an easy way to get notified on changes to
> the socket, maybe we should add it?

The only thing I can think of is watching (through inotify) the directory where the socket file is expected to appear. But that will wake up unity8 for every file change in this directory and not only the socket one.

> So that if it shows up after the 50s, we
> will try again?

I think we could simply throttle the retry frequency as time passes (frequent at first and occasionally later on) and finally give up at a much later point in time (say, 30 minutes).

Revision history for this message
Michał Sawicz (saviq) wrote :

On 11.10.2013 16:16, Daniel d'Andrada wrote:
>> IIUC, this will still bail if the connection isn't available within 50s.
> Right.
>
>> >It might be good enough, but if there's an easy way to get notified on changes to
>> >the socket, maybe we should add it?
> The only thing I can think of is watching (through inotify) the directory where the socket file is expected to appear. But that will wake up unity8 for every file change in this directory and not only the socket one.
>
>> >So that if it shows up after the 50s, we
>> >will try again?
> I think we could simply throttle the retry frequency as time passes (frequent at first and occasionally later on) and finally give up at a much later point in time (say, 30 minutes).

Actually after a fix in upstart jobs, maliit-server will *always* be
running when unity8 is, so we should be good there. Let's leave as is.

115. By Daniel d'Andrada

Use XDG_RUNTIME_DIR instead of /tmp

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> Can we please use $XDG_RUNTIME_DIR and mode 600 for this? Or Jamie will eat us
> alive ;)

Done.

Revision history for this message
Michał Sawicz (saviq) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/modules/Unity/Application/ubuntukeyboardinfo.cpp'
2--- src/modules/Unity/Application/ubuntukeyboardinfo.cpp 2013-10-09 15:24:16 +0000
3+++ src/modules/Unity/Application/ubuntukeyboardinfo.cpp 2013-10-11 15:35:13 +0000
4@@ -16,58 +16,85 @@
5
6 #include "ubuntukeyboardinfo.h"
7
8-#include <QTimer>
9+#include <QDir>
10
11 namespace {
12 const int gConnectionAttemptIntervalMs = 5000;
13- const int gMaxFailedAttempts = 10;
14+ const int gMaxConsecutiveAttempts = 10;
15 const char gServerName[] = "ubuntu-keyboard-info";
16 }
17
18 UbuntuKeyboardInfo::UbuntuKeyboardInfo(QObject *parent)
19 : QObject(parent),
20- m_failedAttempts(0),
21+ m_consecutiveAttempts(0),
22 m_lastWidth(0),
23 m_lastHeight(0)
24 {
25- connect(&m_socket, &QLocalSocket::connected, this, &UbuntuKeyboardInfo::onConnected);
26- connect(&m_socket, &QLocalSocket::disconnected, this, &UbuntuKeyboardInfo::onDisconnected);
27+ connect(&m_socket, &QLocalSocket::stateChanged, this, &UbuntuKeyboardInfo::onSocketStateChanged);
28 connect(&m_socket, &QIODevice::readyRead,
29 this, &UbuntuKeyboardInfo::readAllBytesFromSocket);
30
31+ buildSocketFilePath();
32+
33 typedef void (QLocalSocket::*MemberFunctionType)(QLocalSocket::LocalSocketError);
34 MemberFunctionType funcPointer = &QLocalSocket::error;
35 connect(&m_socket, funcPointer,
36 this, &UbuntuKeyboardInfo::onSocketError);
37
38+ m_connectionRetryTimer.setInterval(gConnectionAttemptIntervalMs);
39+ m_connectionRetryTimer.setSingleShot(true);
40+ connect(&m_connectionRetryTimer, &QTimer::timeout,
41+ this, &UbuntuKeyboardInfo::tryConnectingToServer);
42 tryConnectingToServer();
43 }
44
45+UbuntuKeyboardInfo::~UbuntuKeyboardInfo()
46+{
47+ // Make sure we don't get onSocketStateChanged() called during
48+ // destruction.
49+ m_socket.disconnect(this);
50+}
51+
52 void UbuntuKeyboardInfo::tryConnectingToServer()
53 {
54- m_socket.connectToServer(gServerName, QIODevice::ReadOnly);
55-}
56-
57-void UbuntuKeyboardInfo::onConnected()
58-{
59- m_failedAttempts = 0;
60-}
61-
62-void UbuntuKeyboardInfo::onDisconnected()
63-{
64- qWarning("UbuntuKeyboardInfo - disconnected");
65+ ++m_consecutiveAttempts;
66+ Q_ASSERT(!m_socketFilePath.isEmtpy());
67+ m_socket.connectToServer(m_socketFilePath, QIODevice::ReadOnly);
68+}
69+
70+void UbuntuKeyboardInfo::onSocketStateChanged(QLocalSocket::LocalSocketState socketState)
71+{
72+ switch (socketState) {
73+ case QLocalSocket::UnconnectedState:
74+ retryConnection();
75+ break;
76+ case QLocalSocket::ConnectedState:
77+ m_consecutiveAttempts = 0;
78+ break;
79+ default:
80+ break;
81+ }
82 }
83
84 void UbuntuKeyboardInfo::onSocketError(QLocalSocket::LocalSocketError socketError)
85 {
86+ Q_UNUSED(socketError);
87+ qWarning() << "UbuntuKeyboardInfo - socket error:" << m_socket.errorString();
88+}
89+
90+void UbuntuKeyboardInfo::retryConnection()
91+{
92 // Polling every gConnectionAttemptIntervalMs. Not the best approach but could be worse.
93- Q_UNUSED(socketError);
94- ++m_failedAttempts;
95- if (m_failedAttempts < gMaxFailedAttempts) {
96- QTimer::singleShot(gConnectionAttemptIntervalMs, this, SLOT(tryConnectingToServer()));
97+ if (m_consecutiveAttempts < gMaxConsecutiveAttempts) {
98+ if (!m_connectionRetryTimer.isActive()) {
99+ m_connectionRetryTimer.start();
100+ }
101 } else {
102- qCritical() << "Failed to connect to" << gServerName << "after"
103- << m_failedAttempts << "failed attempts";
104+ qCritical() << "Failed to connect to" << m_socketFilePath << "after"
105+ << m_consecutiveAttempts << "failed attempts";
106+
107+ // it shouldn't be running, but just to be sure.
108+ m_connectionRetryTimer.stop();
109 }
110 }
111
112@@ -101,3 +128,15 @@
113 }
114 }
115 }
116+
117+void UbuntuKeyboardInfo::buildSocketFilePath()
118+{
119+ char *xdgRuntimeDir = getenv("XDG_RUNTIME_DIR");
120+
121+ if (xdgRuntimeDir) {
122+ m_socketFilePath = QDir(xdgRuntimeDir).filePath(gServerName);
123+ } else {
124+ m_socketFilePath = QDir("/tmp").filePath(gServerName);
125+ }
126+
127+}
128
129=== modified file 'src/modules/Unity/Application/ubuntukeyboardinfo.h'
130--- src/modules/Unity/Application/ubuntukeyboardinfo.h 2013-10-09 15:24:16 +0000
131+++ src/modules/Unity/Application/ubuntukeyboardinfo.h 2013-10-11 15:35:13 +0000
132@@ -18,6 +18,7 @@
133 #define UBUNTU_KEYBOARD_INFO_H
134
135 #include <QLocalSocket>
136+#include <QTimer>
137
138 // Temporary solution to get information about the onscreen keyboard
139 // This shouldn't be needed once the OSK is a properly sized surface
140@@ -28,6 +29,7 @@
141 Q_PROPERTY(qreal height READ height NOTIFY heightChanged)
142 public:
143 UbuntuKeyboardInfo(QObject *parent = 0);
144+ virtual ~UbuntuKeyboardInfo();
145 qreal width() const { return m_lastWidth; }
146 qreal height() const { return m_lastHeight; }
147
148@@ -37,8 +39,7 @@
149
150 private Q_SLOTS:
151 void tryConnectingToServer();
152- void onConnected();
153- void onDisconnected();
154+ void onSocketStateChanged(QLocalSocket::LocalSocketState socketState);
155 void onSocketError(QLocalSocket::LocalSocketError socketError);
156 void readAllBytesFromSocket();
157
158@@ -50,12 +51,18 @@
159 qint32 keyboardHeight;
160 };
161 void readInfoFromSocket();
162+ void retryConnection();
163+ void buildSocketFilePath();
164
165- int m_failedAttempts;
166+ int m_consecutiveAttempts;
167
168 QLocalSocket m_socket;
169 qint32 m_lastWidth;
170 qint32 m_lastHeight;
171+ QTimer m_connectionRetryTimer;
172+
173+ // Path to the socket file created by ubuntu-keyboard
174+ QString m_socketFilePath;
175 };
176
177 #endif // UBUNTU_KEYBOARD_INFO_H

Subscribers

People subscribed via source and target branches