summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristian Strømme <christian.stromme@theqtcompany.com>2015-02-13 12:18:33 +0100
committerChristian Stromme <christian.stromme@theqtcompany.com>2015-02-17 14:30:32 +0000
commit02c5657a7d6d30c6e874e29a0adcc38b58a45b7d (patch)
tree59b5be095cb8d393ee0e6b9b64b9065b48cd6d61 /src
parent921dd85c7a90bf7432d50bd9f631d065f5281d34 (diff)
Android: Fix local ref handling.
We where allowing conversion from jobject to QJNIObject without taking ownership of the jobject. Since we are managing the JNI environment we should not allow conversions without having the option of taking ownership of the local ref. This is now done by making the conversions explicit, i.e., local refs are converted through QJNIObjectPrivate::fromLocalRef() and global refs through the QJNIObjectPrivate's jobject constructor. This change breaks SC, but the API is private and no usage have been found outside QtBase. Change-Id: I3175f171699ec3f8e65144aaebc6246bc6e5bb4d Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qstandardpaths_android.cpp4
-rw-r--r--src/corelib/kernel/qjni.cpp9
-rw-r--r--src/corelib/kernel/qjni_p.h8
-rw-r--r--src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp3
4 files changed, 18 insertions, 6 deletions
diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp
index 958b4ea486..50cba3135e 100644
--- a/src/corelib/io/qstandardpaths_android.cpp
+++ b/src/corelib/io/qstandardpaths_android.cpp
@@ -57,7 +57,7 @@ static QJNIObjectPrivate applicationContext()
if (appCtx.isValid())
return appCtx;
- QJNIObjectPrivate activity = QtAndroidPrivate::activity();
+ QJNIObjectPrivate activity(QtAndroidPrivate::activity());
if (!activity.isValid())
return appCtx;
@@ -131,7 +131,7 @@ static QString getExternalFilesDir(const char *directoryField = 0)
if (!path.isEmpty())
return path;
- QJNIObjectPrivate activity = QtAndroidPrivate::activity();
+ QJNIObjectPrivate activity(QtAndroidPrivate::activity());
if (!activity.isValid())
return QString();
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index 9d74fd69de..8431ee3b67 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -96,7 +96,7 @@ static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env)
if (clazz != 0 || isCached)
return clazz;
- QJNIObjectPrivate classLoader = QtAndroidPrivate::classLoader();
+ QJNIObjectPrivate classLoader(QtAndroidPrivate::classLoader());
if (!classLoader.isValid())
return 0;
@@ -2239,6 +2239,13 @@ bool QJNIObjectPrivate::isValid() const
return d->m_jobject;
}
+QJNIObjectPrivate QJNIObjectPrivate::fromLocalRef(jobject lref)
+{
+ QJNIObjectPrivate o(lref);
+ QJNIEnvironmentPrivate()->DeleteLocalRef(lref);
+ return o;
+}
+
bool QJNIObjectPrivate::isSameObject(jobject obj) const
{
QJNIEnvironmentPrivate env;
diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h
index 5f573624c6..fb1982dc74 100644
--- a/src/corelib/kernel/qjni_p.h
+++ b/src/corelib/kernel/qjni_p.h
@@ -84,7 +84,10 @@ public:
QJNIObjectPrivate(const char *className, const char *sig, ...);
explicit QJNIObjectPrivate(jclass clazz);
QJNIObjectPrivate(jclass clazz, const char *sig, ...);
- QJNIObjectPrivate(jobject obj);
+ // In most cases you should never call this function with a local ref. unless you intend
+ // to manage the local ref. yourself.
+ // NOTE: see fromLocalRef() for converting a local ref. to QJNIObjectPrivate.
+ explicit QJNIObjectPrivate(jobject globalRef);
template <typename T>
T callMethod(const char *methodName,
@@ -183,6 +186,9 @@ public:
return *this;
}
+ // This function takes ownership of the jobject and releases the local ref. before returning.
+ static QJNIObjectPrivate fromLocalRef(jobject lref);
+
private:
friend class QAndroidJniObject;
diff --git a/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp b/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp
index 4beb2e581b..c6a013ebed 100644
--- a/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp
+++ b/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp
@@ -295,8 +295,7 @@ QList<AndroidNetworkInfo> AndroidConnectivityManager::getAllNetworkInfo() const
if (exceptionCheckAndClear(env))
break;
- list << AndroidNetworkInfo(lref);
- env->DeleteLocalRef(lref);
+ list << AndroidNetworkInfo(QJNIObjectPrivate::fromLocalRef(lref));
}
return list;