Add QAndroidApplication as a nativeInterface

QAndroidApplication provides the Android specific app context() and
isActivityContext() to determine whether the context is an Activity or
otherwise a Service.

Task-number: QTBUG-90499
Change-Id: Iae2eef7ec44859a89825b09f52f09506b20b5420
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Assam Boudjelthia 2021-02-10 20:06:09 +02:00
parent 4c6579eacd
commit 255459250d
10 changed files with 196 additions and 50 deletions

View File

@ -94,6 +94,7 @@ qt_internal_add_module(Core
kernel/qassociativeiterable.cpp kernel/qassociativeiterable.h
kernel/qbasictimer.cpp kernel/qbasictimer.h
kernel/qcoreapplication.cpp kernel/qcoreapplication.h kernel/qcoreapplication_p.h
kernel/qcoreapplication_platform.h
kernel/qcorecmdlineargs_p.h
kernel/qcoreevent.cpp kernel/qcoreevent.h
kernel/qcoreglobaldata.cpp kernel/qcoreglobaldata_p.h
@ -996,6 +997,7 @@ qt_internal_extend_target(Core CONDITION ANDROID AND NOT ANDROID_EMBEDDED
kernel/qjniobject.cpp kernel/qjniobject.h
kernel/qjnihelpers.cpp kernel/qjnihelpers_p.h
kernel/qjnionload.cpp
platform/android/qandroidnativeinterface.cpp
)
qt_internal_extend_target(Core CONDITION HAIKU AND (ANDROID_EMBEDDED OR NOT ANDROID)

View File

@ -41,11 +41,13 @@
#ifndef QT_NO_STANDARDPATHS
#include <QJniObject>
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/qjniobject.h>
#include <QtCore/qmap.h>
#include <QtCore/qcoreapplication.h>
#include <QDir>
using namespace QNativeInterface;
QT_BEGIN_NAMESPACE
typedef QMap<QString, QString> AndroidDirCache;
@ -57,24 +59,6 @@ static QString testDir()
: QLatin1String("");
}
static QJniObject applicationContext()
{
static QJniObject appCtx;
if (appCtx.isValid())
return appCtx;
QJniObject context(QtAndroidPrivate::activity());
if (!context.isValid()) {
context = QtAndroidPrivate::service();
if (!context.isValid())
return appCtx;
}
appCtx = context.callObjectMethod("getApplicationContext",
"()Landroid/content/Context;");
return appCtx;
}
static inline QString getAbsolutePath(const QJniObject &file)
{
QJniObject path = file.callObjectMethod("getAbsolutePath",
@ -95,7 +79,7 @@ static QString getExternalFilesDir(const char *directoryField = nullptr)
if (!path.isEmpty())
return path;
QJniObject appCtx = applicationContext();
QJniObject appCtx = QAndroidApplication::context();
if (!appCtx.isValid())
return QString();
@ -128,7 +112,7 @@ static QString getExternalCacheDir()
if (!path.isEmpty())
return path;
QJniObject appCtx = applicationContext();
QJniObject appCtx = QAndroidApplication::context();
if (!appCtx.isValid())
return QString();
@ -150,7 +134,7 @@ static QString getCacheDir()
if (!path.isEmpty())
return path;
QJniObject appCtx = applicationContext();
QJniObject appCtx = QAndroidApplication::context();
if (!appCtx.isValid())
return QString();
@ -172,7 +156,7 @@ static QString getFilesDir()
if (!path.isEmpty())
return path;
QJniObject appCtx = applicationContext();
QJniObject appCtx = QAndroidApplication::context();
if (!appCtx.isValid())
return QString();

View File

@ -91,8 +91,7 @@
#endif // QT_NO_QOBJECT
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#include <QJniObject>
#include <private/qjnihelpers_p.h>
#include <QtCore/qjniobject.h>
#endif
#ifdef Q_OS_MAC
@ -170,7 +169,7 @@ QString QCoreApplicationPrivate::appVersion() const
# ifdef Q_OS_DARWIN
applicationVersion = infoDictionaryStringProperty(QStringLiteral("CFBundleVersion"));
# elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
QJniObject context(QtAndroidPrivate::context());
QJniObject context(QNativeInterface::QAndroidApplication::context());
if (context.isValid()) {
QJniObject pm = context.callObjectMethod(
"getPackageManager", "()Landroid/content/pm/PackageManager;");

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -246,4 +246,6 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const MSG &);
QT_END_NAMESPACE
#include <QtCore/qcoreapplication_platform.h>
#endif // QCOREAPPLICATION_H

View File

@ -0,0 +1,66 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QCOREAPPLICATION_PLATFORM_H
#define QCOREAPPLICATION_PLATFORM_H
#include <QtCore/qglobal.h>
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
class _jobject;
typedef _jobject* jobject;
#endif
QT_BEGIN_NAMESPACE
namespace QNativeInterface
{
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) || defined(Q_CLANG_QDOC)
struct Q_CORE_EXPORT QAndroidApplication
{
QT_DECLARE_NATIVE_INTERFACE(QAndroidApplication)
static jobject context();
static bool isActivityContext();
};
#endif
}
QT_END_NAMESPACE
#endif // QCOREAPPLICATION_PLATFORM_H

View File

@ -0,0 +1,85 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/qcoreapplication.h>
#include <QtCore/private/qjnihelpers_p.h>
QT_BEGIN_NAMESPACE
/*!
\class QNativeInterface::QAndroidApplication
\since 6.2
\brief Native interface to a core application on Android.
Accessed through QCoreApplication::nativeInterface().
\inmodule QtCore
\inheaderfile QCoreApplication
\ingroup native-interfaces
\ingroup native-interfaces-qcoreapplication
*/
QT_DEFINE_NATIVE_INTERFACE(QAndroidApplication);
/*!
\fn jobject QNativeInterface::QAndroidApplication::context()
Returns the Android context as a \c jobject. The context is an \c Activity
if the main activity object is valid. Otherwise, the context is a \c Service.
\since 6.2
*/
jobject QNativeInterface::QAndroidApplication::context()
{
return QtAndroidPrivate::context();
}
/*!
\fn bool QNativeInterface::QAndroidApplication::isActivityContext()
Returns \c true if QAndroidApplication::context() provides an \c Activity
context.
\since 6.2
*/
bool QNativeInterface::QAndroidApplication::isActivityContext()
{
return QtAndroidPrivate::activity();
}
QT_END_NAMESPACE

View File

@ -39,9 +39,8 @@
#include "qnetworkproxy.h"
#include <QtCore/QJniEnvironment>
#include <QtCore/QJniObject>
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/qjnienvironment.h>
#include <QtCore/qjniobject.h>
#ifndef QT_NO_NETWORKPROXY
@ -54,6 +53,8 @@ public:
~ProxyInfoObject();
};
using namespace QNativeInterface;
Q_GLOBAL_STATIC(ProxyInfoObject, proxyInfoInstance)
static const char networkClass[] = "org/qtproject/qt/android/network/QtNetwork";
@ -63,7 +64,7 @@ ProxyInfoObject::ProxyInfoObject()
QJniObject::callStaticMethod<void>(networkClass,
"registerReceiver",
"(Landroid/content/Context;)V",
QtAndroidPrivate::context());
QAndroidApplication::context());
}
ProxyInfoObject::~ProxyInfoObject()
@ -71,7 +72,7 @@ ProxyInfoObject::~ProxyInfoObject()
QJniObject::callStaticMethod<void>(networkClass,
"unregisterReceiver",
"(Landroid/content/Context;)V",
QtAndroidPrivate::context());
QAndroidApplication::context());
}
QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
@ -83,7 +84,7 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
QJniObject proxyInfo = QJniObject::callStaticObjectMethod(networkClass,
"getProxyInfo",
"(Landroid/content/Context;)Landroid/net/ProxyInfo;",
QtAndroidPrivate::context());
QAndroidApplication::context());
if (proxyInfo.isValid()) {
QJniObject exclusionList = proxyInfo.callObjectMethod("getExclusionList",
"()[Ljava/lang/String;");

View File

@ -39,11 +39,13 @@
#include "androidconnectivitymanager.h"
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qjnienvironment.h>
QT_BEGIN_NAMESPACE
using namespace QNativeInterface;
struct AndroidConnectivityManagerInstance
{
AndroidConnectivityManagerInstance() : connManager(new AndroidConnectivityManager) { }
@ -67,12 +69,12 @@ AndroidConnectivityManager::AndroidConnectivityManager()
m_connectivityManager = QJniObject::callStaticObjectMethod(
networkInformationClass, "getConnectivityManager",
"(Landroid/content/Context;)Landroid/net/ConnectivityManager;",
QtAndroidPrivate::context());
QAndroidApplication::context());
if (!m_connectivityManager.isValid())
return;
QJniObject::callStaticMethod<void>(networkInformationClass, "registerReceiver",
"(Landroid/content/Context;)V", QtAndroidPrivate::context());
"(Landroid/content/Context;)V", QAndroidApplication::context());
}
AndroidConnectivityManager *AndroidConnectivityManager::getInstance()
@ -87,7 +89,7 @@ AndroidConnectivityManager *AndroidConnectivityManager::getInstance()
AndroidConnectivityManager::~AndroidConnectivityManager()
{
QJniObject::callStaticMethod<void>(networkInformationClass, "unregisterReceiver",
"(Landroid/content/Context;)V", QtAndroidPrivate::context());
"(Landroid/content/Context;)V", QAndroidApplication::context());
}
AndroidConnectivityManager::AndroidConnectivity AndroidConnectivityManager::networkConnectivity()

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2019 Volker Krause <vkrause@kde.org>
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -39,12 +40,14 @@
#include "androidcontentfileengine.h"
#include <QtCore/QJniEnvironment>
#include <QtCore/QJniObject>
#include <private/qjnihelpers_p.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qjnienvironment.h>
#include <QtCore/qjniobject.h>
#include <QDebug>
using namespace QNativeInterface;
AndroidContentFileEngine::AndroidContentFileEngine(const QString &f)
: m_file(f)
{
@ -69,7 +72,7 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
const auto fd = QJniObject::callStaticMethod<jint>("org/qtproject/qt/android/QtNative",
"openFdForContentUrl",
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I",
QtAndroidPrivate::context(),
QAndroidApplication::context(),
QJniObject::fromString(fileName(DefaultName)).object(),
QJniObject::fromString(openModeStr).object());
@ -84,7 +87,7 @@ qint64 AndroidContentFileEngine::size() const
{
const jlong size = QJniObject::callStaticMethod<jlong>(
"org/qtproject/qt/android/QtNative", "getSize",
"(Landroid/content/Context;Ljava/lang/String;)J", QtAndroidPrivate::context(),
"(Landroid/content/Context;Ljava/lang/String;)J", QAndroidApplication::context(),
QJniObject::fromString(fileName(DefaultName)).object());
return (qint64)size;
}
@ -95,12 +98,12 @@ AndroidContentFileEngine::FileFlags AndroidContentFileEngine::fileFlags(FileFlag
FileFlags flags;
const bool isDir = QJniObject::callStaticMethod<jboolean>(
"org/qtproject/qt/android/QtNative", "checkIfDir",
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
"(Landroid/content/Context;Ljava/lang/String;)Z", QAndroidApplication::context(),
QJniObject::fromString(fileName(DefaultName)).object());
// If it is a directory then we know it exists so there is no reason to explicitly check
const bool exists = isDir ? true : QJniObject::callStaticMethod<jboolean>(
"org/qtproject/qt/android/QtNative", "checkFileExists",
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
"(Landroid/content/Context;Ljava/lang/String;)Z", QAndroidApplication::context(),
QJniObject::fromString(fileName(DefaultName)).object());
if (!exists && !isDir)
return flags;
@ -110,7 +113,7 @@ AndroidContentFileEngine::FileFlags AndroidContentFileEngine::fileFlags(FileFlag
flags = FileType | commonFlags;
const bool writable = QJniObject::callStaticMethod<jboolean>(
"org/qtproject/qt/android/QtNative", "checkIfWritable",
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
"(Landroid/content/Context;Ljava/lang/String;)Z", QAndroidApplication::context(),
QJniObject::fromString(fileName(DefaultName)).object());
if (writable)
flags |= WriteOwnerPerm|WriteUserPerm|WriteGroupPerm|WriteOtherPerm;
@ -186,13 +189,13 @@ bool AndroidContentFileEngineIterator::hasNext() const
const bool isDir = QJniObject::callStaticMethod<jboolean>(
"org/qtproject/qt/android/QtNative", "checkIfDir",
"(Landroid/content/Context;Ljava/lang/String;)Z",
QtAndroidPrivate::context(),
QAndroidApplication::context(),
QJniObject::fromString(path()).object());
if (isDir) {
QJniObject objArray = QJniObject::callStaticObjectMethod("org/qtproject/qt/android/QtNative",
"listContentsFromTreeUri",
"(Landroid/content/Context;Ljava/lang/String;)[Ljava/lang/String;",
QtAndroidPrivate::context(),
QAndroidApplication::context(),
QJniObject::fromString(path()).object());
if (objArray.isValid()) {
QJniEnvironment env;

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -44,7 +45,7 @@
#include <QMimeDatabase>
#include <QUrl>
#include <QtCore/QJniObject>
#include <private/qjnihelpers_p.h>
#include <QtCore/qcoreapplication.h>
QT_BEGIN_NAMESPACE
@ -67,12 +68,13 @@ bool QAndroidPlatformServices::openUrl(const QUrl &theUrl)
mime = mimeDb.mimeTypeForUrl(url).name();
}
using namespace QNativeInterface;
QJniObject urlString = QJniObject::fromString(url.toString());
QJniObject mimeString = QJniObject::fromString(mime);
return QJniObject::callStaticMethod<jboolean>(
QtAndroid::applicationClass(), "openURL",
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Z",
QtAndroidPrivate::context(), urlString.object(), mimeString.object());
QAndroidApplication::context(), urlString.object(), mimeString.object());
}
bool QAndroidPlatformServices::openDocument(const QUrl &url)