Skip to content

Commit c8a1e7b

Browse files
committed
Android: ensure valid focus object before native input context actions
Before attempting any input context operations coming from Qt native Java calls ensure we have a valid focus object. Attempting to do this locks the AndroidDeadlockProtector, at the time potentially QAndroidPlatformOpenGLWindow::eglSurface() can be called while the surface is not yet ready, and it attempts to create one and that also locks the AndroidDeadlockProtector. Pick-to: 6.5 6.8 6.9 6.10 Fixes: QTBUG-139211 Fixes: QTBUG-100991 Fixes: QTBUG-131695 Fixes: QTBUG-125083 Fixes: QTBUG-138837 Task-number: QTBUG-132695 Task-number: QTBUG-139400 Change-Id: I4689a0625d62f3ae3fbcd3674c046c431a3e84ca Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
1 parent a5028fe commit c8a1e7b

File tree

2 files changed

+37
-22
lines changed

2 files changed

+37
-22
lines changed

src/plugins/platforms/android/qandroidinputcontext.cpp

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,15 @@ static void runOnQtThread(const std::function<void()> &func)
7575
QMetaObject::invokeMethod(m_androidInputContext, "safeCall", Qt::BlockingQueuedConnection, Q_ARG(std::function<void()>, func));
7676
}
7777

78+
static bool hasValidFocusObject()
79+
{
80+
return m_androidInputContext && m_androidInputContext->focusObject()
81+
&& m_androidInputContext->isInputPanelVisible();
82+
}
83+
7884
static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
7985
{
80-
if (!m_androidInputContext)
86+
if (!hasValidFocusObject())
8187
return JNI_FALSE;
8288

8389
qCDebug(lcQpaInputMethods) << "@@@ BEGINBATCH";
@@ -88,7 +94,7 @@ static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
8894

8995
static jboolean endBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
9096
{
91-
if (!m_androidInputContext)
97+
if (!hasValidFocusObject())
9298
return JNI_FALSE;
9399

94100
qCDebug(lcQpaInputMethods) << "@@@ ENDBATCH";
@@ -101,7 +107,7 @@ static jboolean endBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
101107

102108
static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint newCursorPosition)
103109
{
104-
if (!m_androidInputContext)
110+
if (!hasValidFocusObject())
105111
return JNI_FALSE;
106112

107113
jboolean isCopy;
@@ -117,7 +123,7 @@ static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint new
117123

118124
static jboolean deleteSurroundingText(JNIEnv */*env*/, jobject /*thiz*/, jint leftLength, jint rightLength)
119125
{
120-
if (!m_androidInputContext)
126+
if (!hasValidFocusObject())
121127
return JNI_FALSE;
122128

123129
qCDebug(lcQpaInputMethods) << "@@@ DELETE" << leftLength << rightLength;
@@ -128,7 +134,7 @@ static jboolean deleteSurroundingText(JNIEnv */*env*/, jobject /*thiz*/, jint le
128134

129135
static jboolean finishComposingText(JNIEnv */*env*/, jobject /*thiz*/)
130136
{
131-
if (!m_androidInputContext)
137+
if (!hasValidFocusObject())
132138
return JNI_FALSE;
133139

134140
qCDebug(lcQpaInputMethods) << "@@@ FINISH";
@@ -139,7 +145,7 @@ static jboolean finishComposingText(JNIEnv */*env*/, jobject /*thiz*/)
139145

140146
static jboolean replaceText(JNIEnv *env, jobject /*thiz*/, jint start, jint end, jstring text, jint newCursorPosition)
141147
{
142-
if (!m_androidInputContext)
148+
if (!hasValidFocusObject())
143149
return JNI_FALSE;
144150

145151
jboolean isCopy;
@@ -156,7 +162,7 @@ static jboolean replaceText(JNIEnv *env, jobject /*thiz*/, jint start, jint end,
156162

157163
static jint getCursorCapsMode(JNIEnv */*env*/, jobject /*thiz*/, jint reqModes)
158164
{
159-
if (!m_androidInputContext)
165+
if (!hasValidFocusObject())
160166
return 0;
161167

162168
jint res = 0;
@@ -166,7 +172,7 @@ static jint getCursorCapsMode(JNIEnv */*env*/, jobject /*thiz*/, jint reqModes)
166172

167173
static jobject getExtractedText(JNIEnv *env, jobject /*thiz*/, int hintMaxChars, int hintMaxLines, jint flags)
168174
{
169-
if (!m_androidInputContext)
175+
if (!hasValidFocusObject())
170176
return 0;
171177

172178
QAndroidInputContext::ExtractedText extractedText;
@@ -190,7 +196,7 @@ static jobject getExtractedText(JNIEnv *env, jobject /*thiz*/, int hintMaxChars,
190196

191197
static jstring getSelectedText(JNIEnv *env, jobject /*thiz*/, jint flags)
192198
{
193-
if (!m_androidInputContext)
199+
if (!hasValidFocusObject())
194200
return 0;
195201

196202
QString text;
@@ -203,7 +209,7 @@ static jstring getSelectedText(JNIEnv *env, jobject /*thiz*/, jint flags)
203209

204210
static jstring getTextAfterCursor(JNIEnv *env, jobject /*thiz*/, jint length, jint flags)
205211
{
206-
if (!m_androidInputContext)
212+
if (!hasValidFocusObject())
207213
return 0;
208214

209215
QString text;
@@ -214,7 +220,7 @@ static jstring getTextAfterCursor(JNIEnv *env, jobject /*thiz*/, jint length, ji
214220

215221
static jstring getTextBeforeCursor(JNIEnv *env, jobject /*thiz*/, jint length, jint flags)
216222
{
217-
if (!m_androidInputContext)
223+
if (!hasValidFocusObject())
218224
return 0;
219225

220226
QString text;
@@ -225,7 +231,7 @@ static jstring getTextBeforeCursor(JNIEnv *env, jobject /*thiz*/, jint length, j
225231

226232
static jboolean setComposingText(JNIEnv *env, jobject /*thiz*/, jstring text, jint newCursorPosition)
227233
{
228-
if (!m_androidInputContext)
234+
if (!hasValidFocusObject())
229235
return JNI_FALSE;
230236

231237
jboolean isCopy;
@@ -241,7 +247,7 @@ static jboolean setComposingText(JNIEnv *env, jobject /*thiz*/, jstring text, ji
241247

242248
static jboolean setComposingRegion(JNIEnv */*env*/, jobject /*thiz*/, jint start, jint end)
243249
{
244-
if (!m_androidInputContext)
250+
if (!hasValidFocusObject())
245251
return JNI_FALSE;
246252

247253
qCDebug(lcQpaInputMethods) << "@@@ SETR" << start << end;
@@ -253,7 +259,7 @@ static jboolean setComposingRegion(JNIEnv */*env*/, jobject /*thiz*/, jint start
253259

254260
static jboolean setSelection(JNIEnv */*env*/, jobject /*thiz*/, jint start, jint end)
255261
{
256-
if (!m_androidInputContext)
262+
if (!hasValidFocusObject())
257263
return JNI_FALSE;
258264

259265
qCDebug(lcQpaInputMethods) << "@@@ SETSEL" << start << end;
@@ -265,7 +271,7 @@ static jboolean setSelection(JNIEnv */*env*/, jobject /*thiz*/, jint start, jint
265271

266272
static jboolean selectAll(JNIEnv */*env*/, jobject /*thiz*/)
267273
{
268-
if (!m_androidInputContext)
274+
if (!hasValidFocusObject())
269275
return JNI_FALSE;
270276

271277
qCDebug(lcQpaInputMethods) << "@@@ SELALL";
@@ -276,7 +282,7 @@ static jboolean selectAll(JNIEnv */*env*/, jobject /*thiz*/)
276282

277283
static jboolean cut(JNIEnv */*env*/, jobject /*thiz*/)
278284
{
279-
if (!m_androidInputContext)
285+
if (!hasValidFocusObject())
280286
return JNI_FALSE;
281287

282288
qCDebug(lcQpaInputMethods) << "@@@";
@@ -287,7 +293,7 @@ static jboolean cut(JNIEnv */*env*/, jobject /*thiz*/)
287293

288294
static jboolean copy(JNIEnv */*env*/, jobject /*thiz*/)
289295
{
290-
if (!m_androidInputContext)
296+
if (!hasValidFocusObject())
291297
return JNI_FALSE;
292298

293299
qCDebug(lcQpaInputMethods) << "@@@";
@@ -298,7 +304,7 @@ static jboolean copy(JNIEnv */*env*/, jobject /*thiz*/)
298304

299305
static jboolean copyURL(JNIEnv */*env*/, jobject /*thiz*/)
300306
{
301-
if (!m_androidInputContext)
307+
if (!hasValidFocusObject())
302308
return JNI_FALSE;
303309

304310
qCDebug(lcQpaInputMethods) << "@@@";
@@ -309,7 +315,7 @@ static jboolean copyURL(JNIEnv */*env*/, jobject /*thiz*/)
309315

310316
static jboolean paste(JNIEnv */*env*/, jobject /*thiz*/)
311317
{
312-
if (!m_androidInputContext)
318+
if (!hasValidFocusObject())
313319
return JNI_FALSE;
314320

315321
qCDebug(lcQpaInputMethods) << "@@@ PASTE";
@@ -320,7 +326,7 @@ static jboolean paste(JNIEnv */*env*/, jobject /*thiz*/)
320326

321327
static jboolean updateCursorPosition(JNIEnv */*env*/, jobject /*thiz*/)
322328
{
323-
if (!m_androidInputContext)
329+
if (!hasValidFocusObject())
324330
return JNI_FALSE;
325331

326332
qCDebug(lcQpaInputMethods) << "@@@ UPDATECURSORPOS";
@@ -331,15 +337,18 @@ static jboolean updateCursorPosition(JNIEnv */*env*/, jobject /*thiz*/)
331337

332338
static void reportFullscreenMode(JNIEnv */*env*/, jobject /*thiz*/, jboolean enabled)
333339
{
334-
if (!m_androidInputContext)
340+
if (!hasValidFocusObject())
335341
return;
336342

337343
runOnQtThread([&]{m_androidInputContext->reportFullscreenMode(enabled);});
338344
}
339345

340346
static jboolean fullscreenMode(JNIEnv */*env*/, jobject /*thiz*/)
341347
{
342-
return m_androidInputContext ? m_androidInputContext->fullscreenMode() : false;
348+
if (!hasValidFocusObject())
349+
return false;
350+
351+
return m_androidInputContext->fullscreenMode();
343352
}
344353

345354
static JNINativeMethod methods[] = {
@@ -978,6 +987,11 @@ void QAndroidInputContext::clear()
978987
}
979988

980989

990+
QObject *QAndroidInputContext::focusObject()
991+
{
992+
return m_focusObject;
993+
}
994+
981995
void QAndroidInputContext::setFocusObject(QObject *object)
982996
{
983997
if (object != m_focusObject) {

src/plugins/platforms/android/qandroidinputcontext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class QAndroidInputContext: public QPlatformInputContext
7979
bool isComposing() const;
8080
void clear();
8181
void setFocusObject(QObject *object) override;
82+
QObject *focusObject();
8283
void sendShortcut(const QKeySequence &);
8384

8485
//---------------//

0 commit comments

Comments
 (0)