mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-14 20:12:29 -04:00
QML app fix: crash closing, notification deadlock
The crash was introduced at 533dbef0c7
This has been particurarly tricky as lot of different parts contributed
in causing unexpected behaviours
When the activity is created onNewIntent is not called and we have to
get the intent data from C++ bu other means, but C++ code is running
in a different thread so there is no guarantee that the intent data is
reacheable yet on starting, so the C++ code has to wait for the intent
data being ready, but paying attention to not cause a deadlock beetween
the two thread (the android ui thread may be waiting for some
operation performed by Qt)
Because of notification intent flags not properly set the activity was
recreated also if it was already on top, this caused a nasty
interaction between android ui thread and qt thread that derived in a
deadlock, to avoid this lot of try/error has been made until the
proper soup of manifest and intent flags has been found
At this point link handling, notification handling, and Activity closing
should work as expected without any deadlock or crash
This commit is contained in:
parent
d2598dd437
commit
987b5a1cdc
10 changed files with 236 additions and 62 deletions
|
@ -64,14 +64,6 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
|
@ -80,6 +72,14 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/intermediates/blame" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/intermediates/manifests" />
|
||||
|
|
|
@ -17,30 +17,27 @@
|
|||
*/
|
||||
|
||||
#include "NativeCalls.h"
|
||||
#include "singletonqmlengine.h"
|
||||
#include "rsqmlappengine.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QMetaObject>
|
||||
#include <QDebug>
|
||||
#include <QQuickWindow>
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_retroshare_android_qml_1app_jni_NativeCalls_notifyIntentUri
|
||||
(JNIEnv* env, jclass, jstring uri)
|
||||
{
|
||||
qDebug() << __PRETTY_FUNCTION__;
|
||||
|
||||
const char *uriBytes = env->GetStringUTFChars(uri, NULL);
|
||||
QString uriStr(uriBytes);
|
||||
env->ReleaseStringUTFChars(uri, uriBytes);
|
||||
|
||||
QQmlApplicationEngine& engine(SingletonQmlEngine::instance());
|
||||
QObject* rootObj = engine.rootObjects()[0];
|
||||
QQuickWindow* mainWindow = qobject_cast<QQuickWindow*>(rootObj);
|
||||
|
||||
if(mainWindow)
|
||||
{
|
||||
QMetaObject::invokeMethod(mainWindow, "handleIntentUri",
|
||||
Q_ARG(QVariant, uriStr));
|
||||
}
|
||||
else qCritical() << __PRETTY_FUNCTION__ << "Root object is not a window!";
|
||||
RsQmlAppEngine* engine = RsQmlAppEngine::mainInstance();
|
||||
if(engine)
|
||||
QMetaObject::invokeMethod(
|
||||
engine, "handleUri",
|
||||
Qt::QueuedConnection, // BlockingQueuedConnection, AutoConnection
|
||||
Q_ARG(QString, uriStr));
|
||||
else qCritical() << __PRETTY_FUNCTION__ << "RsQmlAppEngine::mainInstance()"
|
||||
<< "not initialized yet!";
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.retroshare.android.qml_app;
|
|||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.TaskStackBuilder;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
@ -39,19 +38,23 @@ public class RetroShareAndroidNotifyService extends QtService
|
|||
.setContentText(text)
|
||||
.setAutoCancel(true);
|
||||
|
||||
Intent resultIntent = new Intent(this, RetroShareQmlActivity.class);
|
||||
if(!uri.isEmpty()) resultIntent.setData(Uri.parse(uri));
|
||||
Intent intent = new Intent(this, RetroShareQmlActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
|
||||
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
|
||||
stackBuilder.addParentStack(RetroShareQmlActivity.class);
|
||||
stackBuilder.addNextIntent(resultIntent);
|
||||
PendingIntent resultPendingIntent =
|
||||
stackBuilder.getPendingIntent( 0,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT );
|
||||
if(!uri.isEmpty()) intent.setData(Uri.parse(uri));
|
||||
|
||||
mBuilder.setContentIntent(resultPendingIntent);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(
|
||||
this, NOTIFY_REQ_CODE, intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
mBuilder.setContentIntent(pendingIntent);
|
||||
NotificationManager mNotificationManager =
|
||||
(NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mNotificationManager.notify(0, mBuilder.build());
|
||||
}
|
||||
|
||||
/** Must not be 0 otherwise a new activity may be created when should not
|
||||
* (ex. the activity is already visible/on top) and deadlocks happens */
|
||||
private static final int NOTIFY_REQ_CODE = 2173;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ public class RetroShareQmlActivity extends QtActivity
|
|||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
Log.i("RetroShareQmlActivity", "onCreate()");
|
||||
|
||||
if (!isMyServiceRunning(RetroShareAndroidService.class))
|
||||
{
|
||||
Log.i("RetroShareQmlActivity", "onCreate(): RetroShareAndroidService is not running, let's start it by Intent");
|
||||
|
@ -55,13 +57,12 @@ public class RetroShareQmlActivity extends QtActivity
|
|||
@Override
|
||||
public void onNewIntent(Intent intent)
|
||||
{
|
||||
Log.i("RetroShareQmlActivity", "onNewIntent(Intent intent)");
|
||||
|
||||
super.onNewIntent(intent);
|
||||
|
||||
String uri = intent.getDataString();
|
||||
if (uri != null)
|
||||
{
|
||||
Log.d("RetroShareQmlActivity", "onNewIntent() " + uri);
|
||||
NativeCalls.notifyIntentUri(uri);
|
||||
}
|
||||
if (uri != null) NativeCalls.notifyIntentUri(uri);
|
||||
}
|
||||
|
||||
private boolean isMyServiceRunning(Class<?> serviceClass)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue